[LeetCode]81. 搜索旋转排序数组 II(java实现)二分
1. 题目
2. 读题(需要重点注意的东西)
思路:
- 直接遍历一遍,最坏情况下时间复杂度为O(n)
- 删除给定的旋转数组结尾的和nums[0]相同的数,然后按[LeetCode] 33. 搜索旋转排序数组(java实现)二分进行二分,当所有数都相同时,二分会退化成线性搜索,即最坏情况下时间复杂度为O(n)
3. 解法
---------------------------------------------------解法1:直接遍历一遍---------------------------------------------------
class Solution {
public boolean search(int[] nums, int target) {
for(int i = 0;i < nums.length;i++){
if(nums[i] == target) return true;
}
return false;
}
}
---------------------------------------------------解法2:二分---------------------------------------------------
class Solution {
public boolean search(int[] nums, int target) {
if(nums.length == 0) return false;
int R = nums.length - 1;
while(R >= 0 && nums[R] == nums[0]) R--;
if(R < 0) return nums[0] == target;
int l = 0, r = R;
while(l < r){
int mid = l + r + 1>> 1;
// 二分出大于等于nums[0]的最后一个数
if(nums[mid] >= nums[0]) l = mid;
else r = mid - 1;
}
if(target >= nums[0]){
r = l;
l = 0;
}else{
l++;
r = R;
}
while(l < r){
int mid = l + r >> 1;
// 二分出大于等于target的第一个数(对比上面二分式子的l和r)
if(nums[mid] >= target) r =mid;
else l = mid + 1;
}
return nums[r] == target;
}
}
可能存在的问题:
4. 可能有帮助的前置习题
5. 所用到的数据结构与算法思想
- 二分
6. 总结
如有nums数组[4,5,6,6,7,0,1,2,4,4]
-
如果我们要找数组nums中,大于等于某一个数 x 的最大的数:
while(l < r){ int mid = l + r + 1>> 1; if(nums[mid] >= x) l = mid; else r = mid - 1; }
因为此时mid已经大于或等于x了,要找最大的大于等于x的数,那么应该向后找,即
l = mid
; -
如果我们要找数组nums中,大于等于某一个数 x 的最小的数:
while(l < r){ int mid = l + r>> 1; if(nums[mid] >= x) r = mid; else l = mid + 1; }
因为此时mid已经大于或等于x了,要找最小的大于等于x的数,那么应该向前找,即
r = mid
;
注意上述两式的区别!