代码随想录算法训练营第一天 | 704. 二分查找、27. 移除元素、977.有序数组的平方

97 阅读2分钟

704. 二分查找

文章讲解:programmercarl.com/

视频讲解:space.bilibili.com/525438321/l…

思路:

  • 二分法
  • 易错点:区间问题,在边界判断上容易错,注意左闭右闭和左闭右开。

方法一:左闭右闭[left, right]

#左闭右闭
def search(self, nums: List[int], target: int) -> int:   
    left = 0
    # 左闭右闭 right在区间中
    right = len(nums) - 1

    while left <= right: # 试想例子left==right,[1,1]为合法的,可以等于
        middle = (left + right) // 2
        if target < nums[middle]:
            # 左闭右闭,前一次包含middle
            right = middle - 1
        elif target > nums[middle]:
            # 左闭右闭,前一次包含middle
            left = middle + 1
        else:
            return middle
    return -1

方法二:左闭右闭[left, right)

# 左闭右开
def search(self, nums: List[int], target: int) -> int: 
        left = 0
        # 左闭右开 right不在区间中
        right = len(nums)

        while left < right: # 关于等号,试想例子left == right, [1,1)不合法,所以不能等
            middle = (left + right) // 2
            if target < nums[middle]:
                #左闭右开 不包含有边界 等于middle没有重复计算
                right = middle
            elif target > nums[middle]:
                #左闭右开 不包含有边界 middle在上一次循环中
                left = middle + 1
            else:
                return middle
        return -1

27. 移除元素

数组删除原理: image.png

暴力解法

#暴力
def removeElement(self, nums: List[int], val: int) -> int:
    n = len(nums)
    i = 0
    # 第一层循环找val
    while i < n:
        if nums[i] == val:
            #第二层改数组
            for j in range(i, n - 1):
                nums[j] = nums[j + 1]
            i -= 1 # 避免连续出现val值
            n -= 1
        i += 1
    return n

双指针

双指针法(快慢指针法): 通过一个快指针和慢指针在一个for循环下完成两个for循环的工作。

定义快慢指针

  • 快指针:寻找新数组的元素 ,新数组就是不含有目标元素的数组
  • 慢指针:指向更新 新数组下标的位置
# 快慢双指针
def removeElement(self, nums: List[int], val: int) -> int:
    slow = 0 # 慢指针是新数组的位置
    fast = 0 # 快指针是新数组的元素
    l = len(nums)
    while fast < l:
        # 不等于val时,新数组赋值
        # 等于val时,跳过
        if nums[fast] != val:
            nums[slow] = nums[fast]
            slow += 1
        fast += 1
    return slow

977.有序数组的平方

思路: 相向双指针。较大值放入到结果中,指针向中间移动一位,继续比较。

def sortedSquares(self, nums: List[int]) -> List[int]:
    l = 0
    r = len(nums) - 1

    result = [0] * len(nums)
    i = len(nums) - 1 # i表示新数组result的位置,从大到小
    while l <= r:
        if nums[l] ** 2 >= nums[r] ** 2:
            result[i] = nums[l] ** 2
            l += 1
        else:
            result[i] = nums[r] ** 2
            r -= 1
        i -= 1
    return result

今日收获: 二分法的难点(区间的统一),双指针用法