LeetCode | Search for a Range(查找数据出现的范围)
2014-07-09 19:40
821 查看
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
For example,
Given
return
查找某一个值出现在数组中的范围。
方案一:
先二分查找到key,然后再二分查找,知道arr[mid]==key && arr[mid-1] < key时为最左边界,arr[mid]==key && arr[mid-1] > key为最右边界。但是要注意考察mid==0 和 mid==n-1时的情况。所以判断时还要加强条件。代码如下
方案二:
上面写的有些繁琐,还要先查到再左右加强条件遍历。我们可以分两次二分查找,第一次查找最左端,当arr[mid] >= key时,依然让hi = mid-1。这样得到的越界l刚好为左边界left;同理,第二次查找右边界,当arr[mid] <= key时,依然让l = mid+1。越界的r刚好为右边界。(这两个地方需要仔细考虑好,不然又会像上面一样,在中间添加很多代码来判断)
上面的思路充分利用了循环l<=r的特性。合适超出边界。还有判断时,等号应处于哪个范围。
当然最后还要判断查找失败时的情况。
还有一种是传递一个标志符,开表示查找左边界还是右边界。简化了代码。但要考虑清楚如何判断
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; else lo = 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; else lo = 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 position public: vector<int> searchRange(int A[], int n, int target) { // Start typing your C/C++ solution below // DO NOT write int main() function int 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 target r = 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-----34. Search for a Range(查找范围)
- [LeetCode]—Search for a Range 有序数组查找target的下标范围
- Leetcode刷题记——34. Search for a Range(查找一个范围)
- leetcode题解:Search for a Range (已排序数组范围查找)
- LeetCode-Search for a Range-搜索范围-二分查找
- LeetCode 34. Search for a Range(有序数组,查找给定值范围)
- 【LeetCode-面试算法经典-Java实现】【034-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 34.Search for a Range (搜索范围) 解题思路和方法
- [LeetCode-34] Search for a Range (寻找有序数组中关键值的索引范围)
- [leetcode-二分查找]--34. Search for a Range
- 二分查找有序数组中某个数的所在范围 Search for a Range
- LeetCode Search for a Range搜索特定数值的范围 三种方法求解
- Search for a Range--查找某个数范围--二分查找
- LeetCode OJ 之 Search for a Range (查找一个范围)