当前位置:   article > 正文

在排序数组中查找元素的第一个和最后一个位置_获取数组第一个和最后一个

获取数组第一个和最后一个
与二分查找唯一的不同就是注意的地方。 当找到目标元素时,并不是直接返回,而是收紧右侧边界,继续查找,以锁定左侧边界。最后返回左侧边界

第一个,最基本的二分查找算法:
因为我们初始化 right = nums.length - 1
所以决定了我们的「搜索区间」是 [left, right]
所以决定了 while (left <= right)
同时也决定了 left = mid+1 和 right = mid-1
因为我们只需找到一个 target 的索引即可
所以当 nums[mid] == target 时可以立即返回

第二个,寻找左侧边界的二分查找:
因为我们初始化 right = nums.length - 1
所以决定了我们的「搜索区间」是 [left, right]
所以决定了 while (left <= right)
同时也决定了 left = mid+1 和 right = mid-1
因为我们需找到 target 的最左侧索引
所以当 nums[mid] == target 时不要立即返回
而要收紧右侧边界以锁定左侧边界

第三个,寻找右侧边界的二分查找:
因为我们初始化 right = nums.length - 1
所以决定了我们的「搜索区间」是 [left, right]
所以决定了 while (left <= right)
同时也决定了 left = mid+1 和 right = mid-1
因为我们需找到 target 的最右侧索引
所以当 nums[mid] == target 时不要立即返回
而要收紧左侧边界以锁定右侧边界
  1. #include<iostream>
  2. #include<vector>
  3. using namespace std;
  4. class Solution {
  5. public:
  6. vector<int> searchRange(vector<int>& nums, int target) {
  7. if (nums.empty()) {
  8. return { -1,-1 };
  9. }
  10. int leftBorder = getLeft(nums, target);
  11. int rightBorder = getRight(nums, target);
  12. if (leftBorder == nums.size() || nums[leftBorder] != target){
  13. return { -1,-1 };
  14. }
  15. vector<int> p = { leftBorder ,rightBorder };
  16. return p;
  17. }
  18. private:
  19. int getLeft(vector<int>& nums, int target) {
  20. int left = 0;
  21. int right = nums.size() - 1;
  22. //寻找左侧边界的二分查找
  23. while (left <= right) {
  24. int middle = left + ((right - left) >> 1); // >>移位运算比 / 操作性能好,另外考虑大数溢出
  25. if (nums[middle] == target) {
  26. right = middle - 1; //收紧右侧边界以锁定左侧边界
  27. }
  28. else if (nums[middle] < target) {
  29. left = middle + 1;
  30. }
  31. else if (nums[middle] > target) {
  32. right = middle - 1;
  33. }
  34. }
  35. return left; // 返回左侧边界
  36. }
  37. int getRight(vector<int>& nums, int target) {
  38. int left = 0;
  39. int right = nums.size() - 1;
  40. //寻找右侧边界的二分查找
  41. while (left <= right) {
  42. int middle = left + ((right - left) >> 1);
  43. if (nums[middle] == target) {
  44. left = middle + 1;
  45. }
  46. else if (nums[middle] < target) {
  47. left = middle + 1;
  48. }
  49. else if (nums[middle] > target) {
  50. right = middle - 1;
  51. }
  52. }
  53. return right; // 返回右侧边界
  54. }
  55. };
  56. int main() {
  57. Solution s;
  58. vector<int> v = { 5,7,7,8,8,10 };
  59. vector<int> t = s.searchRange(v, 9);
  60. cout << t[0] << " " << t[1] << endl;
  61. system("pause");
  62. return 0;
  63. }
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Gausst松鼠会/article/detail/436775
推荐阅读
相关标签
  

闽ICP备14008679号