SONG Shengjie

数组理论基础

文章链接:数组理论基础

数组:存放在连续内存空间上的相同类型数据集合,可以方便的通过下标索引的方式获取到下标对应的数据

特点:数组下标都是从0开始的。数组内存空间的地址是连续的。数组的元素是不能删的,只能覆盖

704.二分查找

相关链接:力扣原题 文章解读 视频解读

易错点:1. left<right? left<=right? 2. right=middle? right=middle-1?

题目的前提是数组为有序数组,同时题目还强调数组中无重复元素,因为一旦有重复元素,使用二分查找法返回的元素下标可能不是唯一的,这些都是使用二分法的前提条件。

错误点在计算中间索引 middle 时,使用了普通除法 /,导致 middle 是一个浮点数,而 Python 的列表索引必须是整数或切片,不能是浮点数。将普通除法 / 改为整数除法 //,确保 middle 是整数。

循环不变量:[left,right] or [left,right)

class Solution:
    def search(self, nums: List[int], target: int) -> int:
        left=0
        right=len(nums)-1
        while left<=right:
            middle=(left+right)//2
            if target<nums[middle]:
                right=middle-1
            elif target>nums[middle]:
                left=middle+1
            elif target==nums[middle]:
                return middle
        return -1
class Solution:
    def search(self, nums: List[int], target: int) -> int:
        left=0
        right=len(nums)
        while left<right:
            middle=(left+right)//2
            if target<nums[middle]:
                right=middle
            elif target>nums[middle]:
                left=middle+1
            elif target==nums[middle]:
                return middle
        return -1

口诀:左闭右闭,右含右数;左闭右开,右不含右数。左不变,不重判。

27.移除元素

相关链接:力扣原题 文章解读 视频解读

class Solution:
    def removeElement(self, nums: List[int], val: int) -> int:
        i = 0
        while i < len(nums):
            if nums[i] == val:
                for j in range(i, len(nums) - 1):
                    nums[j] = nums[j+1]
                nums.pop()
            else:
                i += 1
        return len(nums)

易错点:1.第一层循环中,由于列表长度随循环而更新,while 循环在每次迭代开始时都会重新计算循环条件表达式的值。而 for i in range(0, len(nums)) 这个循环的范围在开始时就已经确定好了,它不会随着列表长度的改变而动态调整。2.使用 nums.pop() 移除最后一个重复的元素。

class Solution:
    def removeElement(self, nums: List[int], val: int) -> int:
        slow, fast = 0, 0
        for fast in range(0, len(nums)):
            if nums[fast] != val :
                nums[slow] = nums[fast]
                slow += 1
                fast += 1
            else :
                fast += 1
        return slow

核心思想:快指针-寻找新数组的元素 ,新数组就是不含有目标元素的数组;慢指针-指向更新 新数组下标的位置

977.有序数组的平方

相关链接:力扣原题 文章解读 视频解读

class Solution:
    def sortedSquares(self, nums: List[int]) -> List[int]:
        k = len(nums) - 1
        i = 0
        j = len(nums) - 1
        result = [0] * len(nums)
        while i <= j :
            if nums[i]*nums[i] <= nums[j]*nums[j] :
                result[k] = nums[j]*nums[j]
                k -= 1
                j -= 1
            else :
                result[k] = nums[i]*nums[i]
                k -= 1
                i += 1
        return result

思路:数组有序, 但负数平方之后可能成为最大数。那么数组平方的最大值就在数组的两端,不是最左就是最右,不可能是中间。考虑双指针法了,i指向起始位置,j指向终止位置。
为什么while i <= j? 如果i<j,那么当i与j相等时,就退出循环了,有一个数没有被判断。

总结:多变量区间开闭判合法,双指针快慢前后定去留。