URL
https://leetcode.com/problems/search-in-rotated-sorted-array/#/description
描述
Suppose an array sorted in ascending order is rotated at some pivot unknown to you beforehand.
(i.e., 0 1 2 4 5 6 7 might become 4 5 6 7 0 1 2).
You are given a target value to search. If found in the array return its index, otherwise return -1.
You may assume no duplicate exists in the array.
解题思路
解题思路基本就是二分查找算法。不同之处在于普通情况下数组的数据的值是单调递增或者递减的,但是本题数组是经过旋转处理过的。可以这样理解,把之前的一个单调递增的数组分解成两个,每一个也都是单调递增。我们把前段单调递增的数组简称(前段),后段单调递增的数组简称(后段),前段第一个数值一定是大于后段最后一个数值。基于这样的性质,我们对二分查找算法进行改编。步骤如下:
1. 我们首先还是会获得中间位置的数组下标:mid = (start+end)/2;
2. 如果mid 位置上的值就是等于target,也就是我们查询的目标,则直接返回即可,程序终止;
3. 如果与target不相等,我们就要做一个额外的操作——判断mid在什么位置上,或者说mid的位置是出现在“前段”还是“后段”。判断的依据也很简单:nums[mid]是否大于nums[end],若大于则mid出现在前段,否则出现在后段。
4. 缩小start和end的位置,具体判断依据就放在下面的代码里,逻辑也很简单。
代码示例
public int search(int[] nums, int target) {
int start = 0;
int end = nums.length-1;
while(start<=end){
int mid = (start+end)/2;
int key = nums[mid];
if(key==target) return mid;
if(key>nums[end]){//mid 出现在前段
if(target<key&&target>=nums[start]){
end=mid-1;
}else{
start=mid+1;
}
}else {//mid出现在后段
if(target>key&&target<=nums[end]){
start=mid+1;
}else{
end=mid-1;
}
}
}
return -1;
}
Search in Rotated Sorted Array II
url:
https://leetcode.com/problems/search-in-rotated-sorted-array-ii/#/description
描述:
Follow up for “Search in Rotated Sorted Array”:
What if duplicates are allowed?
Would this affect the run-time complexity? How and why?
解题思路
因为存在相同的元素,所以在判断mid出现哪个阶段的时候会出现一个问题——当nums[mid]==nums[end]的时候,你无法判断mid在前段还是后段,所以对于这种情况我们干脆不进行判断了,而是简单的将end的位置减小一个。这样做的结果是原来我是判断[start,end]这部分数组中是否出现target元素,现在我判断[start,end-1]部分。这样并不会带来数据的丢失,因为至少有nums[mid]的数值是与nums[end]相同的。基于这样的思路给出代码就很方便了。
代码示例
private boolean searchHelper(int start,int end,int[]nums,int target){
while(start<=end){
int mid = (start+end)/2;
int key = nums[mid];
if(key==target) return true;
if(key>nums[end]){
if(target<key&&target>=nums[start]){
end=mid-1;
}else{
start=mid+1;
}
}else if(key<nums[end]){
if(target>key&&target<=nums[end]){
start=mid+1;
}else{
end=mid-1;
}
}else{
end--;
}
}
return false;
}
public boolean search(int[] nums, int target) {
return searchHelper(0,nums.length-1,nums,target);
}