代码随想录算法训练营Day1 | 704. 二分查找、27. 移除元素

1. 数组理论基础

  • 数组是存放在连续内存空间上的相同类型数据的集合。

  • 数组的元素不能删除,只能覆盖。

2. 二分查找704

力扣题目链接

文档讲解

视频讲解:《代码随想录》算法视频公开课 (opens new window)手把手带你撕出正确的二分法 (opens new window)

状态:想到了双指针

【要素察觉】二分法的使用条件

  • 有序数组
  • 数组中无重复元素

【重点】区间的定义

  • 二分法主要有两种定义方法:左闭右闭即[left, right],或者左闭右开即[left, right)。
  • 区间的定义就是不变量,那么在循环中坚持根据查找区间的定义来做边界处理,就是循环不变量规则。
  • 两种的主要区别是while条件和middle的赋值对应变化。

【代码实现】

(双指针)while+左闭右闭

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

(双指针)while+左闭右开

下一个查询区间不会去比较nums[mid]。

class Solution:
    def search(self, nums: List[int], target: int) -> int:
        left = 0
        right = len(nums) - 1
        if nums is None or len(nums) == 0:
            return -1
        while left < right:  # 区别点1
            mid = (left + right) // 2
            if nums[mid] == target:
                return mid
            elif nums[mid] > target:
                right = mid  # 区别点2
            elif nums[mid] < target:
                left = mid + 1
        return -1

(暴力)迭代法

class Solution:
    def search(self, nums: List[int], target: int) -> int:
        for i in range(len(nums)):
            if nums[i] == target:
                return i
        return -1

【练习题】

3. 移除元素27

力扣题目链接

文档讲解

视频讲解:《代码随想录》算法视频公开课 (opens new window)数组中移除元素并不容易!LeetCode:27. 移除元素 (opens new window)

状态:用的暴力法

【思路】只能覆盖

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

思路一:暴力解法

27.移除元素-暴力解法

思路二:快慢指针

27.移除元素-双指针法

【代码实现】

(暴力解法)while + for循环,交换位置

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

(暴力解法)while+while交换位置后pop

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

(双指针)快慢指针

class Solution:
    def removeElement(self, nums: List[int], val: int) -> int:
        # 双指针,左指针慢
        left, right = 0,0
        while right < len(nums):
            if nums[right] == val:
                # 等于就跳过
                right += 1 
            else:
                # 不等就存储
                nums[left] = nums[right]
                left += 1
                right += 1
        
        return left

(双指针) 左右指针

class Solution:
    def removeElement(self, nums: List[int], val: int) -> int:
        left = 0
        right = len(nums) - 1
        while left <= right:
            if nums[left] == val:
                nums[left] = nums[right]
                right -= 1
            else:
                left += 1
        return left

【练习题】

  • 23
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值