首页 > 其他分享 >day1 | 704. 二分查找、27.移除元素

day1 | 704. 二分查找、27.移除元素

时间:2023-03-15 18:45:10浏览次数:42  
标签:27 nums 704 middle int right 移除 指针 left

 

704.二分查找

题目简述

一个有序数组中找到目标值,返回其位置

 

思路

确定左右指针,一个指向最左边,一个指向最右边

 

 

1. 闭区间

 

确定中间值,如果中间值大于目标值,目标值在左边,中间值已经确定是不等于目标值的了,那也就没必要将right变成middle,这时候可以往前一个,取为middle-1。与之对应,left取为middle+1。



class Solution:
    def search(self, nums: List[int], target: int) -> int:
        n = len(nums)
        left =0 
        right = n-1 # 定义target在左闭右闭区间里面,即[left,right]
        while(left<=right): # 当left=right,区间[left,right]仍然有效,需要判断
            middle=left+(right-left)//2 # 防止溢出,这种形式也能表示取中值
            if nums[middle] == target:
                return middle
            elif nums[middle]<target:
                left = middle+1 # 既然middle不是,那就赋值为middle+1
            else:
                right = middle-1 # 既然middle不是,那就赋值middle-1

        # 没找到target         return -1

 

这里不用单独讨论数组为空的情况,当数组为空的时候,left一开始为0,right一开始为-1,直接不进入循环,直接return -1。

 

2. 左闭右开

 

确定中间值,如果中间值大于目标值,目标值在左边,中间值已经确定是不等于目标值的了,那也就没必要将right变成middle,这时候可以往前一个,取为middle-1。与之对应,left取为middle+1。

class Solution:
    def search(self, nums: List[int], target: int) -> int:
        n = len(nums)
        left =0 
        right = n # 定义target在左闭右开区间里面,即[left,right)
        while(left<right): # 当left=right,[left,right)里面没有元素,是无效空间,于是使用<
            middle=left+(right-left)//2 # 防止溢出,这种形式也能表示取中值
            if nums[middle] == target:
                return middle
            elif nums[middle]<target:
                left = middle+1 # 既然middle不是,那就赋值为middle+1
            else:
                right = middle # target在左区间,在[left,middle)之中

        # 没找到target
        return -1

 

需要注意的小细节:

1. 找中间值时,避免超出范围,不建议写左加右除以二,建议使用左边值加区间一半写法。因为int有范围,两个大数相加可能超过范围就变成负数了,第二种也存在这种情况,但是发生概率会小点。

2. 跳出循环时,就意味着没有找到,返回-1

3. 这里的left和right取middle还是middle+1/middle-1,需要注意,根据要判断的区间的开闭性来确定是否加减1。

 

 

27.移除元素

 

题目简述

删掉数组中指定的元素,其他元素可以保留,数组前面的数是准确的即可。

 

思路

 

双指针法

 

1. 两个指针都从左边开始

  一个指针用来指向下一个被改变数值的位置,一个指针遍历数组,寻找非指定元素,存入第一个指针指向的位置。

 

class Solution:
    def removeElement(self, nums: List[int], val: int) -> int:
        
        ptr1=0 # 指向待改变的位置
        n=len(nums)
        for ptr2 in range(n): # ptr2用来遍历整个数组
            if nums[ptr2]!=val:
                nums[ptr1]=nums[ptr2]
                ptr1+=1
        
        return ptr1

 

2. 对上面的双指针进行优化处理

  两个指针一左一右。如果左指针left指向的元素等于val,将右指针right指向的元素复制到左指针left的位置,然后右指针左移一位。如果赋值过来的元素恰好也等于val,那就继续把右指针right指向的元素的值赋值过来,直到左指针指向的元素的值不等于val为止。

 

  当right取len(nums),此时循环判断条件为while(left<right),意味着对下标为[0, len(nums)) 中的元素进行操作,刚好囊括了所有元素。对应如下代码实现:

 

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

 

 

  当right取len(nums)-1,此时循环判断条件为while(left<=right),意味着对下标为[0,len(nums)-1]中的元素进行操作,刚好囊括了所有元素。

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

 

总结

1. 边界条件要仔细思考,注意开闭性

 

 

 

  

 


标签:27,nums,704,middle,int,right,移除,指针,left
From: https://www.cnblogs.com/cp1999/p/17219053.html

相关文章

  • 027 反三角函数的求导公式推导
    027反三角函数的求导公式推导 ......
  • 算法随想Day40【动态规划】| LC70-爬楼梯、LC322-零钱兑换、LC279-完全平方数
    LC70.爬楼梯原题其实是一道简单动规的题目。但其实本题稍加改动就是一道面试好题。如改为:一步一个台阶,两个台阶,三个台阶,.......,直到m个台阶。问有多少种不同的方法可......
  • 力扣 (LeetCode)刷题--704. 二分查找
    二分查找是一个非常基础的算法给定一个n个元素有序的(升序)整型数组nums和一个目标值target,写一个函数搜索nums中的target,如果目标值存在返回下标,否则返回-1。示......
  • P2782 友好城市题解
    题目传送门题意:给定一些上下的线段,求出最多不相交的线段数量。一开始看错题了,以为是给定一堆线段,求出线段最大不交数量,然后就写了一个树状数组优化\(dp\)结果样例都不过,......
  • 本地浏览器访问云服务器127.0.0.1的某个端口
    目前在学习gin框架,但是在无图形化界面的linux云服务器上看不到网页的效果,而且lynx等纯文本浏览器过于丑陋了。于是研究了一下如何在本地计算机访问云服务器上的127.......
  • lc203.移除链表元素
    题目给你一个链表的头节点head和一个整数val,请你删除链表中所有满足Node.val==val的节点,并返回新的头节点。示例输入:head=[1,2,6,3,4,5,6],val=6输出:[......
  • µTorrent 2.2.1 build 25273下载
    来源:http://about.empornium.sx/ µTorrentRecommendedversionis2.2.1, newerversionsareknowntocontainvulnerabilities.Youmustensurethat"net.dis......
  • buildroot编译出错(2020-09-27)
    开发主机:Linuxfly-vm4.15.0-118-generic#119~16.04.1-UbuntuSMPTueSep814:54:40UTC2020x86_64x86_64x86_64GNU/LinuxBSP版本:qt_x210v3s_160307Youmustinsta......
  • AtCoder Beginner Contest 272(D,E)
    AtCoderBeginnerContest272(D,E)DD这个题最主要的是需要找出有哪些移动的距离对于题目给出的\(m\),我们的移动过程可以是\((i-ii)^2+(j-jj)^2=m\)这样的话,我们可以......
  • 第127篇:异步函数(async和await)练习题(异步,消息队列)
    好家伙,本篇为做题思考书接上文 题目如下: 1.请给出下列代码的输出结果,并配合"消息队列"写出相关解释asyncfunctionfoo(){console.log(2);console.lo......