[LeetCode]Search for a Range
2015-07-04 10:52
357 查看
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
[LeetCode Source]
思路:
1)先用二分查找找到点,然后再左右扩展,找到范围。如果有m个要搜寻点,算法复杂度为O(lgN+m),m<=N。最好的情况下是O(lgN),只有一个点的时候;最差情况O(N),全是要搜寻点的时候。这种做法可以Ac。
2)可能是最优解法。两次二分查找,一次是找到左边界点,第二次找到右边界点。
找左边界点时,修改二分查找的规则,如果找到点,还要继续往左二分直到找到左边界点;
找右边界点时,同理。
特别注意break的处理,当明显找不到点时break掉循环,对于找左边界点就是nums[right]<target。
这种解法复杂度是O(lgN)
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].
[LeetCode Source]
思路:
1)先用二分查找找到点,然后再左右扩展,找到范围。如果有m个要搜寻点,算法复杂度为O(lgN+m),m<=N。最好的情况下是O(lgN),只有一个点的时候;最差情况O(N),全是要搜寻点的时候。这种做法可以Ac。
class Solution { public: vector<int> searchRange(vector<int>& nums, int target) { vector<int> result(2,-1); int left = 0; int right = nums.size()-1; int mid = 0; int first = -1; int second = -1; while(left<=right){ mid = left+(right-left)/2; if(nums[mid] > target) right = mid - 1; if(nums[mid] < target) left = mid + 1; if(nums[mid] == target){ first = mid; second = mid; break; } } for(int i=mid-1;i>=0;i--){ if(nums[i]==target) first--; else break; } for(int i=mid+1;i<nums.size();++i){ if(nums[i]==target) second++; else break; } result[0] = first; result[1] = second; return result; } };
2)可能是最优解法。两次二分查找,一次是找到左边界点,第二次找到右边界点。
找左边界点时,修改二分查找的规则,如果找到点,还要继续往左二分直到找到左边界点;
找右边界点时,同理。
特别注意break的处理,当明显找不到点时break掉循环,对于找左边界点就是nums[right]<target。
这种解法复杂度是O(lgN)
class Solution { public: vector<int> searchRange(vector<int>& nums, int target) { int hit = -1; int left=0, right=nums.size() - 1; int first = 0, second = 0; vector<int> ret(2, -1); while(left <= right) { int mid = left + (right - left) / 2; if(nums[right] < target) break; if(nums[mid] >= target) { if(nums[mid] == target) hit = mid; right = mid - 1; } else { left = mid + 1; } } if(hit == -1) return ret; first = hit; left = hit; right = nums.size() - 1; hit = -1; while(left <= right) { int mid = left + (right - left) / 2; if(nums[left] > target) break; if(nums[mid] <= target) { if(nums[mid] == target) hit = mid; left = mid + 1; } else { right = mid - 1; } } if(hit == -1) return ret; second = hit; ret[0] = first; ret[1] = second; return ret; } };
相关文章推荐
- Fragment的懒加载(解决ViewPager中Fragment生命周期错乱的问题)
- GCO3.0的图割分割算法应用(三)
- 网络图片加载
- 我的学习计划---第一部分数据结构与算法
- Android基于发展Service音乐播放器
- 访问控制
- 带你认识LabVIEW和MATLAB
- 把你的代码卸载到GPU(用GPU编程):如何开始
- error C2065: “list”: 未声明的标识符
- 文章标题
- C语言 常用函数
- 机器人视觉技术的关键所在
- Factory Pattern 工厂模式
- 查找同构数的数量
- java深入解析-第1章 基本概念2
- 音乐播放
- 【动态规划】HDU 1003 Max Sum
- iOS --- UITableView的优化技巧
- 备忘录
- 最近的题越来越难了,卧槽,搞一上午一题不会,题解也看不懂