2023/7/12--代码随想录算法训练营day1 |704. 二分查找,27. 移除元素

  • 704.左闭右开和左闭右闭已掌握,35.搜索插入位置
  • 34. 在排序数组中查找元素的第一个和最后一个位置 (没看完)
  • 27.移出元素 还需要多写写,有时候用for \while\if有点晕

一.数组理论基础

数组是存放在连续空间内存上的相同类型数据的集合
可以索引,连续内存上储存,所以插入和删除,需要移动其他元素。
需要注意:1.index从0开始 2.内存连续

二. 704.二分查找

力扣题目链接 704.二分查找:
个人觉得使用左闭右闭比较好想一点!强烈推荐使用,一定要注意,因为我们使用index大小传递了数值的相对大小;所以非常要注意二分法的适用范围:1.有序的 2.非重复(重复的话,index不就不确定了)
总之写代码上,要注意:1.注意边界 2.注意target和数组的值比较的 3.mid要放在while里面,要保证可变
*

想不清楚,可以举个具体的例子,比如说:
1.我现在现在[2,4,6,8]找7,刚开始left=0,right=3,mid=1,nums[1]=4<7,所以二分后,target在右边半块,所以把左边的边界赋为mid+1=2(因为num[mid]已经知道不是target,所以考虑左闭右闭,边界能够定位到mid+1);
2. 现在left=2,right=3,mid=2,nums[2]=6<7,target在二分后的右半块,left赋值为3;
3. 此时,还是满足while循环条件,接着left=right=3,mid=3,nums[mid]=8>7,target在左半块,直接right=mid-1=2,此时left=3>right=2,不满足循环条件,while退出,执行return-1

class Solution:
    def search(self, nums: List[int], target: int) -> int:
        left, right = 0, len(nums)-1
        while left <= right:
            mid = left +(right-left)//2  #因为是整数数组
            if nums[mid] < target:
                left = mid+1
            elif nums[mid] > target:
                right = mid-1
            else:
                return mid
        return -1

在扩展一点左闭右开的代码:
修改:
1.right初值【否则会无法覆盖最右边的值】
2. while条件(左闭右开,左边不能等于右边)
3. 3.right=mid(right边界取不到,但是沿用以前mid-1,这个值事实情况会需要到,不能在代码中让她取不到)

`class Solution:
    def search(self, nums: List[int], target: int) -> int:
        left, right = 0, len(nums)
        while left < right:
            mid = left +(right-left)//2  #因为是整数数组
            if nums[mid] < target:
                left = mid+1
            elif nums[mid] > target:
                right = mid
            else:
                return mid
        return -1

**拓展 35.搜索插入位置,给定一个排序数组和一个目标值,在数组中找到目标值,并返回其索引。如果目标值不存在于数组中,返回它将会被按顺序插入的位置。
请必须使用时间复杂度为 O(log n) 的算法。**主要改动在最后的return上面,想清楚就行
我刚开始写的:力扣上也正确

力扣链接

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

答案在最后一行 return right+1,等下准备问问???【return left就行
因为在最后一次循环,left=right=mid
如果target>num[mid],left=mid+1=right+1,我想要插在mid+1位;
如果target<num[mid],right=mid-1=left-1,我想要插在mid位

拓展 34.在排序数组上查找元素的第一个位置和最后一个位置:主要改动在最后的return上面,想清楚就行
我刚开始写的:本来先用递归,分成两节子去找,没写出来
看到答案有四种解法,我震惊!一会梳理一下

三. 27.移除元素

力扣题目
难点:要知道数组的元素在内存地址中是连续的,不能单独删除数组中的某个元素,只能覆盖。
暴力解法(注意用的while,我用for死活跑不出来,for的循环变量i是不能变动的)

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

双指针法

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

            fast += 1
        return slow
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值