当前位置: 首页> 汽车> 车展 > 购物网站下载_电商品牌推广方案_今日财经最新消息_免费源码资源源码站

购物网站下载_电商品牌推广方案_今日财经最新消息_免费源码资源源码站

时间:2025/7/9 21:39:17来源:https://blog.csdn.net/hlyd520/article/details/144121964 浏览次数: 1次
购物网站下载_电商品牌推广方案_今日财经最新消息_免费源码资源源码站

文章目录

    • 题目链接:
    • 题目描述:
    • 解法
    • C++ 算法代码:
    • 图解
    • 总结模板


题目链接:

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


题目描述:

f50224eced38e32f4e678b01dcd1e26a


解法

暴力解法:

从前往后遍历数组,找到所有符合条件的位置,得到开始和结束位置。

朴素二分:

设置左右指针,和中点,然后把中间值和target作比较,分情况讨论。但是这题这么做的话,时间复杂度会比较大。

二段性:

  1. 查找区间的左端点

5a6754831e66127c1c6493633e52b2c3

细节处理:

  1. 循环条件

    left<=right X

    left<right √

    下面就为什么不可以用<=要用<展开讲解

    分为3种情况:tleftright中间,tlefttright

  1. tleftright中间的情况:

542040c4f3b9c72680c26450effc3b01

所以,left=right的时候,就是最终结果,无需判断

  1. tleft的情况:

此时,right向左移动,直到left=right=t,这个时候返回t的下标

如果tleft处的值还小,那么返回[-1,-1]

d547856079ad6160ec76b04342bac8b9

  1. tright的情况:

此时,left向右移动,直到left=right=t,这个时候返回t的下标

如果tright处的值还大,那么返回[-1,-1]

da56a279042757e4a870732b50c3522b

注意:当满足第一个条件的时候,left=right=t,这个时候继续求中间值就陷入死循环了。

所以不可以写<=,要写<

  1. 求中点的操作

    有两种形式:

    left+(right-left)/2

    left+(right-left+1)/2

这么写只对偶数情况由影响:

left+(right-left)/2left+(right-left+1)/2
425cebd01d480453b7854c618fdfa0e10eea5f7ed6de16d1d641fb5b72d0b63b

表面上看起来好像差不多,但是如果只有两个的话:

按照left+(right-left+1)/2的话,mid在如图所示的位置:

238fc7b0f19d1d61629bf071dc2abb46

若此时,x<t -> left=mid+1=x+1left>right程序结束

若此时,x>=t -> right=mid=xright原地不动,进入死循环。


按照left+(right-left)/2的话,mid在如图所示的位置:

58b220b147faa9c1469ea343a846261d

若此时,x<t -> left=mid+1=x+1left=right程序结束。

若此时,x>=t -> right=mid=xleft=right程序结束。


  1. 查找区间的右端点

311383b3aabe1b2c6c711aeff566c29b

求中点的情况,按照left+(right-left+1)/2,不然会死循环。


C++ 算法代码:

class Solution 
{public:vector<int> searchRange(vector<int>& nums, int target) {// 处理边界情况if(nums.size() == 0) return {-1, -1};int begin = 0;// 1. 二分左端点int left = 0, right = nums.size() - 1;while(left < right){int mid = left + (right - left) / 2;if(nums[mid] < target) left = mid + 1;else right = mid;}// 判断是否有结果if(nums[left] != target) return {-1, -1};else begin = left; // 标记一下左端点// 2. 二分右端点left = 0, right = nums.size() - 1;while(left < right){int mid = left + (right - left + 1) / 2;if(nums[mid] <= target) left = mid;else right = mid - 1;}return {begin, right};}
};

图解

例如:[1, 2, 3, 3, 3, 4, 5],t=3

c0fd2019173e136d6079f0e70ce8ef15

经过第一个while(left < right)循环,找到左端点,也就是left=right的时候。得到左端点下标为2

经过第二个while(left < right)循环,找到右端点,也就是left=right的时候。得到右端点下标为4

返回[2,4]


总结模板

查找区间左端点的模板

while(left < right){int mid = left + (right - left) / 2;if(......) left = mid + 1;else right = mid;
}

查找区间右端点的模板

while(left < right){int mid = left + (right - left + 1) / 2;if(......) left = mid;else right = mid - 1;
}
关键字:购物网站下载_电商品牌推广方案_今日财经最新消息_免费源码资源源码站

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

责任编辑: