/************************************************************************/ /* 34. 在排序数组中查找元素的第一个和最后一个位置 给定一个按照升序排列的整数数组 nums,和一个目标值 target。找出给定目标值在数组中的开始位置和结束位置。 如果数组中不存在目标值 target,返回 [-1, -1]。 进阶: 你可以设计并实现时间复杂度为 O(log n) 的算法解决此问题吗? 示例 1: 输入:nums = [5,7,7,8,8,10], target = 8 输出:[3,4] 示例 2: 输入:nums = [5,7,7,8,8,10], target = 6 输出:[-1,-1] 示例 3: 输入:nums = [], target = 0 输出:[-1,-1] 来源:力扣(LeetCode) 链接:https://leetcode-cn.com/problems/find-first-and-last-position-of-element-in-sorted-array 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。 */ /************************************************************************/ // 二分搜索-相等的部分使用遍历 // 时间复杂度:O(n),空间复杂度:O(1),这个方法不可取,还不如直接遍历 vector<int> searchRange1(vector<int>& nums, int target) { int i = 0; int j = nums.size() - 1; if (nums.empty() || nums[i] > target || nums[j] < target) return{ -1,-1 }; while (i < j) { int m = (i + j) / 2; if (target > nums[m]) i = m + 1; else if (target < nums[m]) j = m - 1; else { while (i <= m) { if (nums[i] == target) break; i++; } while (m <= j) { if (nums[j] == target) break; j--; } break; } } if (i == j && nums[i] != target) { i = j = -1; } return{ i,j }; } // 二分查找-分左右两边二分查找 // 时间复杂度:O(logn),空间复杂度:O(1) vector<int> searchRange2(vector<int>& nums, int target) { int i = 0; int j = nums.size() - 1; if (nums.empty() || nums[i] > target || nums[j] < target) return { -1,-1 }; int m = 0; // 先找左边界,注意,这里需要取到等号,因为是和数组外的值target对比,当闭区间 [i,j] 为空时跳出 // 跳出的时候,i可能为target的第一个位置 while (i <= j) { m = (i + j) / 2; if (nums[m] < target) i = m + 1; else j = m - 1; } // 左边界与目标不等,直接返回 if (nums[i] != target) return{ -1,-1 }; vector<int> result(2,-1); result[0] = i; // 再找右边界,从左边界开始就行,,注意,这里需要取到等号,因为是和数组外的值target对比,当闭区间 [i,j] 为空时跳出 // 跳出的时候,j为target的最后一个位置 j = nums.size() - 1; while (i <= j) { m = (i + j) / 2; if (nums[m] <= target) i = m + 1; else if (nums[m] > target) j = m - 1; } result[1] = j; return result; }
算法实现--二分查找-在排序数组中查找元素的第一个和最后一个位置
最新推荐文章于 2022-01-26 14:41:43 发布