LeetCode | Search for a Range(查找数据出现的范围)
来源:互联网 发布:ai 人工智能 影评 编辑:程序博客网 时间:2024/06/05 15:48
Given a sorted array of integers, find the starting and ending position of a given target value.
Your algorithm's runtime complexity must be in the order of O(log n).
If the target is not found in the array, return [-1, -1]
.
For example,
Given [5, 7, 7, 8, 8, 10]
and target value 8,
return [3, 4]
.
查找某一个值出现在数组中的范围。
方案一:
先二分查找到key,然后再二分查找,知道arr[mid]==key && arr[mid-1] < key时为最左边界,arr[mid]==key && arr[mid-1] > key为最右边界。但是要注意考察mid==0 和 mid==n-1时的情况。所以判断时还要加强条件。代码如下
int SearchRange(int arr[], int n, int key,int *left,int *right){int lo = 0, hi = n - 1, mid = 0;int lhi, rlo;while (lo <= hi){mid = (lo + hi) / 2;if (arr[mid] == key){lhi = mid;//要取等于mid,防止左半区不再含有key值rlo = mid;//同上,防止右半区不含key值while (lo <= lhi){mid = (lo + lhi) / 2;if (arr[mid] == key && (mid == 0 || arr[mid - 1] < key)){*left = mid;break;}if (arr[mid] >= key)//arr[mid] == key的情况要放入这个里面lhi = mid - 1;elselo = mid + 1;}while (rlo <= hi){mid = (rlo + hi) / 2;if (arr[mid] == key && (mid == n - 1 || arr[mid + 1] > key)){*right = mid;break;}if (arr[mid] > key)hi = mid - 1;else//arr[mid] == key的情况要放入这个里面rlo = mid + 1;}return 1;}if (arr[mid] > key)hi = mid - 1;elselo = mid + 1;}return 0;}
方案二:
上面写的有些繁琐,还要先查到再左右加强条件遍历。我们可以分两次二分查找,第一次查找最左端,当arr[mid] >= key时,依然让hi = mid-1。这样得到的越界l刚好为左边界left;同理,第二次查找右边界,当arr[mid] <= key时,依然让l = mid+1。越界的r刚好为右边界。(这两个地方需要仔细考虑好,不然又会像上面一样,在中间添加很多代码来判断)
上面的思路充分利用了循环l<=r的特性。合适超出边界。还有判断时,等号应处于哪个范围。
当然最后还要判断查找失败时的情况。
class Solution {//Binary Search//we must know how to process the 3 cases below://1.how to find the right most target//2.how to find the left most target//3.how to find the insert positionpublic:vector<int> searchRange(int A[], int n, int target) {// Start typing your C/C++ solution below// DO NOT write int main() functionint l = 0;int r = n-1;while (l <= r){int mid = l+(r-l)/2;if (A[mid] >= target)//find the left most target r = mid-1;else if (A[mid] < target)l = mid+1;}int left = l;l = 0; r = n-1;while (l <= r){int mid = l+(r-l)/2;if (A[mid] > target)//find the right most targetr = mid-1;else if (A[mid] <= target)l = mid+1;}int right = r;if(A[left] != target || A[right] != target)left = right = -1;vector<int> ans(2);ans[0] = left;ans[1] = right;return ans;}};
还有一种是传递一个标志符,开表示查找左边界还是右边界。简化了代码。但要考虑清楚如何判断
class Solution {public: int findPos(int a[], int beg, int end, int key, bool findLeft) { if (beg > end) return -1; int mid = (beg + end) / 2; if (a[mid] == key) { int pos = findLeft ? findPos(a, beg, mid - 1, key, findLeft) : findPos(a, mid + 1, end, key, findLeft); return pos == -1 ? mid : pos; } else if (a[mid] < key) return findPos(a, mid + 1, end, key, findLeft); else return findPos(a, beg, mid - 1, key, findLeft); } vector<int> searchRange(int A[], int n, int target) { // Start typing your C/C++ solution below // DO NOT write int main() function int leftPos = findPos(A, 0, n - 1, target, true); int rightPos = findPos(A, 0, n - 1, target, false); vector<int> ret; ret.push_back(leftPos); ret.push_back(rightPos); return ret; }};
- LeetCode | Search for a Range(查找数据出现的范围)
- LeetCode-----34. Search for a Range(查找范围)
- [LeetCode]—Search for a Range 有序数组查找target的下标范围
- Search for a Range 查找一个数所在的范围
- LeetCode OJ 之 Search for a Range (查找一个范围)
- LeetCode 34 Search for a Range(搜索范围)
- LeetCode 34. Search for a Range(搜索范围)
- Search for a Range 有序数组里查找一个数的出现区间 @LeetCode
- [LeetCode] Search for a Range查找区间
- leetcode:Search for a Range 二分查找
- leetcode 二分查找 Search for a Range
- leetcode-二分查找:Search for a range
- [leetcode] 【查找】 34. Search for a Range
- leetcode---search-for-a-range---查找
- Search for a Range--查找某个数范围--二分查找
- [LeetCode-34] Search for a Range (寻找有序数组中关键值的索引范围)
- LeetCode 之 Search for a Range(查找)
- Leetcode-Search for a Range(折半查找)
- 那些妖术——树的遍历
- java.util.Scanner应用详解
- OC面向对象和类
- urb分析,usb_fill_bulk_urb函数理解
- UVA10494 IfWe Were a Child Again
- LeetCode | Search for a Range(查找数据出现的范围)
- oss系统的pager.ftl页面
- MFC activeX入门
- vc6.0中OpenGL开发环境的配置
- 小结
- 操作符重载的应用(数组类)
- 网游服务器数据包设计
- CSerialPort类错误排除
- TCP协议