代码随想录算法训练营第一天 | 二分查找、双指针

题目一 leetcode 704. 二分查找

首先,题目的前提是数组为有序数组,且数组中元素不重复,当一道题目描述满足如上条件时,可尝试用二分查找解决。
二分查找的思想是比较简单的,主要难点在于边界条件的判定。分为左闭右闭[left, right]和左闭右开[left, right)两种。
(1)左闭右闭[left, right]

  • 初始 right = len(nums) - 1:因为右边界是 “包含” 的,所以取最后一个元素的索引。
  • 循环条件 left <= right :当 left == right 时,区间内依旧有元素,需要继续检查。
  • 边界更新left = mid + 1/right = mid - 1:mid位置的元素每次都进行比较,更新区间时无需再包含。
    def search(self, nums: List[int], target: int) -> int:
        left, right = 0, len(nums)-1
        while left <= right:
        	mid = (left+right) // 2
            if nums[mid] == target:
            	return mid
            elif nums[mid] > target::
                right = mid - 1
            else:
                left = mid + 1
        return -1

(1)左闭右开[left, right)

  • 初始 right = len(nums):因为右边界是 “不包含” 的,所以取数组长度,否则会丢失最后一个元素的查找。
  • 循环条件 left < right :当 left == right 时,区间内已经没有元素。
  • 边界更新left = mid + 1/right = mid:右边界不包含,下一次需要考虑。
    def search(self, nums: List[int], target: int) -> int:
        left = 0
        right = len(nums)
        while left < right:
            mid = (left+right) // 2
            if nums[mid] == target:
            	return mid
            elif nums[mid] > target:
                right = mid
            else:
                left = mid + 1
        return -

题目二 leetcode 27. 移除元素

数组的元素在内存地址中是连续的,不能单独删除数组中的某个元素,只能覆盖。

首先想到的就是暴力解法,遍历数组,如果nums[i] == val 则把后面的每个元素向前移动一位,但时间复杂度为 O ( n 2 ) O(n^2) O(n2)
这里最优的解法是快慢双指针法,慢指针(slow)标记“新数组”的末尾位置,快指针(fast)遍历整个原数组,筛选出不等于目标值的元素,赋值给慢指针位置。

    def removeElement(self, nums, val):
        length = len(nums)
        slow = 0
        for fast in range(length):
            if nums[fast] != val:
                nums[slow] = nums[fast]
                slow += 1
        return slow

另外,首尾双指针法,左指针从数组头部开始,右指针从数组尾部开始。

    def removeElement(self, nums: List[int], val: int) -> int:
        fast = 0
        slow = len(nums) - 1
        while fast <= slow:
            if nums[fast] != val:
                fast = fast + 1
            else: 
                if  nums[slow] != val:
                    nums[fast] = nums[slow]
                    nums[slow] = val
                    slow = slow - 1
                    fast = fast + 1
                else:
                    slow = slow - 1
        return fast

题目三 leetcode 977. 有序数组的平方

首先,想到的还是暴力解法,时间复杂度 O ( n + n l o g n ) O(n+nlogn) O(n+nlogn)
另外,双指针法:

    def sortedSquares(self, nums: List[int]) -> List[int]:
        left = 0
        right = len(nums) - 1
        square_nums = [0] * len(nums)
        index = len(nums) - 1
        while left <= right:
            if nums[left] < 0:
                if -nums[left] > nums[right]:
                    square_nums[index] = nums[left]**2
                    left += 1
                else:
                    square_nums[index] = nums[right]**2
                    right -= 1
            else:
                square_nums[index] = nums[right]**2   
                right -= 1
            index -= 1
        return square_nums
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值