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

本来对自己的自学能力和控制力很有信心,尝试自刷了一次,发现自己debug能力太弱了……经常陷在bug里,也没人答疑。索性花钱加了训练营……算是为找工作花的第一笔钱钱……一定能坚持!

704.二分查找

二分法使用的线索提示在“非递减”序列,总之是要经过排序的一堆数

# 左闭右开区间写法
#right的取值比索引最大值大的时候为右开区间,此时判断后赋值也需要比能取的值大1
   
    def search(self, nums: List[int], target: int) -> int:
        left = 0
        right = len(nums)
        while left < right:#right不能取,因此不能带等号
            mid = (left+right)//2
            if nums[mid] < target:#在右区间
                left = mid+1 #要+1
            elif nums[mid] > target:#在左区间
                right = mid # 不可以取mid-1,应该始终比期待值大1
            else:
                return mid
        return -1 
# 左闭右闭区间
# right要为能取的值

class Solution:
    def search(self, nums: List[int], target: int) -> int:
        left = 0
        right = len(nums)-1
        while left <= right:
            mid = (left+right)//2
            if nums[mid] < target:#在右区间
                left = mid+1
            elif nums[mid] > target:#在左区间
                right = mid-1
            else:
                return mid
        
        return -1

自刷时已经学过了,所以这次没有看基本知识直接写的代码,发现还是会有容易错的地方。

1、不熟悉While语法。While 中无返回值,则返回While后的一句。while是一个循环,出现会一直把While中的部分一直循环完毕再往下

2、两种区间写法,什么时候带等号运用不熟悉(也不算完全理解)

而且只能做这种死题,不会灵活运用

二分拓展.34. 在排序数组中查找元素的第一个和最后一个位置

二分的拓展应用,核心都是找到target,但是与基础二分不同的是要多一个验证条件,就是左边的数要比target小,右边的数要比target大。否则就需要继续缩短查找范围。

class Solution:
    def searchRange(self, nums: List[int], target: int) -> List[int]:
        def leftborder(nums,target):
            left = 0
            right = len(nums)-1
            while left<=right:
                mid = (left+right)//2
                if nums[mid]<target:#在右区间
                    left = mid+1
                elif nums[mid]>target:#在左区间
                    right = mid-1
                else :
                    if mid==0 or nums[mid-1]<nums[mid]:
                        return mid
                    else :
                        right = mid-1#继续向左找
            return -1
        def rightborder(nums,target):
            left = 0
            right = len(nums)-1
            while left<=right:
                mid = (left+right)//2
                if nums[mid]<target:#在右区间
                    left = mid+1
                elif nums[mid]>target:#在左区间
                    right = mid-1
                else :
                    if mid==len(nums)-1 or nums[mid+1]>nums[mid]:
                        return mid
                    else :
                        left = mid+1 #继续向右找
            return -1

        left=leftborder(nums,target)
        right=rightborder(nums,target)        
        return  [left,right]

35. 搜索插入位置

二刷忽然大彻大悟啊!!!做起来怎么比一刷快这么多,而且这个逻辑完全理解!!!就是找target的位置,不然就返回计算后的left的索引

感觉还是归因于昨天对while的用法忽然通透!!

class Solution:
    def searchInsert(self, nums: List[int], target: int) -> int:
        left = 0
        right = len(nums)-1
        while left<=right:
            mid = (left+right)//2
            if nums[mid]<target:#在右区间
                left = mid+1
            elif nums[mid]>target:#在左区间
                right = mid-1
            else :
                return mid
            
        return left

27、移除元素

返回数组值时,Python不支持nums[0:j] 这种写法?

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

不标准写的双指针法,i是快指针,j是慢指针。

我理解的暴力法怎么原来就是双指针……

class Solution:
    def removeElement(self, nums: List[int], val: int) -> int:
        left = 0
        right = len(nums)-1
        while left <= right:
            while left<=right and nums[left] != val:#找到第一个val值出现的位置,
                left += 1
            while left<=right and nums[right] == val:#找到右边第一个不为val的位置
                right -= 1
            if left < right :
                nums[left] = nums[right]#把链各个值位置交换,把前面等于val的值换到后面
                left += 1
                right -= 1
        return left

开始觉得挺绕的,原来是不理解While函数的用法。要看成一个整体把While循环完才会运行下一步。而不是只运行一次就往下。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值