【LeetCode】34. Find First and Last Position of Element in Sorted Array(C++)

地址:https://leetcode.com/problems/find-first-and-last-position-of-element-in-sorted-array/

题目:

Given an array of integers nums sorted in ascending order, find the starting and ending position of a given target value.

Your algorithm’s runtime complexity must be in the order of O ( l o g n ) O(log n) O(logn).

If the target is not found in the array, return [ − 1 , − 1 ] [-1, -1] [1,1].

Example 1:

Input: nums = [5,7,7,8,8,10], target = 8
Output: [3,4]

Example 2:

Input: nums = [5,7,7,8,8,10], target = 6
Output: [-1,-1]

理解:

一直觉得二分查找坑实在是太多,查找小于的,查找大于的,查找第一个等于的,最后一个等于的。。。
这个题就是要查找第一个等于的和最后一个等于的。

实现:

二分查找mid=(l+h)/2因为截断总会得到靠左的元素。
如果在循环中要令l=mid或者h=mid,判断条件就应该是while(l<h),否则可能会一直循环下去。
对于findLeft,h最后指向的是大于等于target的第一个元素。跳出循环的时候,l==h,只需要判断这个元素是不是等于target即可。
对于findRight,本来想和上面一样用对称的思路,但是由于截断,导致会陷入死循环,因此改了一下思路。
在最后一次循环内,l==h==mid,如果这个元素小于等于target,会把l改变,否则会减小h。即这种情况下,h总会指向最后一个等于target的元素。

class Solution {
public:
	vector<int> searchRange(vector<int>& nums, int target) {
		if (nums.empty()) return{ -1,-1 };
		int l = findLeft(nums, target);
		if (l == -1) {
			return{ -1,-1 };
		}
		return{ l,findRight(nums,target) };
	}
private:
	int findLeft(vector<int>& nums, int target) {
		int l = 0, h = nums.size()-1;
		while (l < h) {
			int mid = l + (h - l) / 2;
			// shrink the range such that h point to the left-most num that >= target
			if (nums[mid] >= target)
				h = mid;
			// nums[mid]<target, then l should be bigger than mid, let l=mid+1
			else
				l = mid + 1;
		}
		// since h point to the left-most num that >= target, finally l=h.
		// if nums[l]==target,return the index, otherwise, return -1
		return nums[l]==target?l:-1;
	}

	int findRight(vector<int>& nums, int target) {
		int l = 0, h = nums.size() - 1;
		while (l <= h) {
			int mid = l + (h - l) / 2;
			if (nums[mid] <= target)
				l = mid + 1;
			else
				h = mid - 1;
		}
		return nums[h] == target ? h : -1;
	}
};

更一下:
关于截断导致不能用对称的方法做的,解决方法的确是在计算mid的时候手动加1从而指向靠右的位置。详见Clean iterative solution with two binary searches (with explanation)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值