1. 程式人生 > >【LeetCode】34. Find First and Last Position of Element in Sorted Array(C++)

【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) .

If the target is not found in the array, return [

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)