赞
踩
#0.题目描述
34. 在排序数组中查找元素的第一个和最后一个位置
给定一个按照升序排列的整数数组 nums,和一个目标值 target。找出给定目标值在数组中的开始位置和结束位置。
如果数组中不存在目标值 target,返回 [-1, -1]。
进阶:
你可以设计并实现时间复杂度为 O(log n) 的算法解决此问题吗?
示例 1:
输入:nums = [5,7,7,8,8,10], target = 8
输出:[3,4]
#1.解法1
由于是升序数组,我们还是可以用二分法将目标值找出来。
然后分别前后遍历,找到上下限就可以了。
class Solution { public: vector<int> searchRange(vector<int>& nums, int target) { int nLen = nums.size(); int i = 0, j = nLen - 1; int mid; int tmp; if (!nLen) return {-1, -1}; while (i <= j) { mid = (i+j)/2; if (target > nums[mid]) i = mid + 1; else if (target < nums[mid]) j = mid - 1; else break; } if (nums[mid] == target) { i = mid - 1; j = mid + 1; while (i >= 0 && nums[i] == target) i--; while (j < nLen && nums[j] == target) j++; return {++i, --j}; } return {-1, -1}; } };
#2.解法2
解法1貌似不太满足o(logn)的要求,参考答案,我们可以同样可以用二分法把上下限直接逼近出来。
求下限:nums[mid] >= target
求上限:nums[mid] > target
class Solution { public: vector<int> searchRange(vector<int>& nums, int target) { int leftIdx = binarySearch(nums, target, true); int rightIdx = binarySearch(nums, target, false) - 1; if (leftIdx <= rightIdx && rightIdx < nums.size() && nums[leftIdx] == target && nums[rightIdx] == target) return vector<int>{leftIdx, rightIdx}; return vector<int>{-1, -1}; } int binarySearch(vector<int>& nums, int target, bool lower) { int left = 0, right = (int)nums.size() - 1, ans = (int)nums.size(); while (left <= right) { int mid = (left + right) / 2; if (nums[mid] > target || (lower && nums[mid] >= target)) { right = mid - 1; ans = mid; } else { left = mid + 1; } } return ans; } };
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。