您的位置:首页 > 其它

leetcode 33. Search in Rotated Sorted Array

2016-10-07 19:37 471 查看
Suppose a sorted array 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.

这道题目的是通过二分查找在移动过的排序好数组中找到目标值。

我的作法是按照原来的二分查找思路,并根据最大值的位置,做一些平移的操作

class Solution {
private int findmax(int[] nums){
int index=0;
while(index<nums.length-1&&nums[index]<nums[index+1]){
index++;
}
return index;
}
public int search(int[] nums, int target) {
int max=findmax(nums);
int left=(max+1)%nums.length;
int right=max;
int mid=-1;
int flag=0;
while((left<=right||(left>max&&right<=max))&&flag==0){
mid=(((right+nums.length-left)%nums.length/2)+left)%nums.length;
if(nums[mid]<target){
if(left==right) {flag=1;break;}
left=(mid+1)%nums.length;
}
else if(nums[mid]>target){
if(left==right) {flag=1;break;}
right=(mid+nums.length-1)%nums.length;
if(right==max) {flag=1;break;}
}
else break;
}
if((left>right&&((left<=max&&right<=max)||(
left>max&&right>max)))||flag==1) return -1;
else return mid;
}
}

而看到讨论区有更为简单的答案

int search(int* nums, int numsSize, int target) {
int left, right, mid;
left = 0;
right = numsSize-1;

if (right<left)
return -1;
while ( left<=right) {
mid = (left+right)/2;

if (target == nums[mid])
return mid;
if(nums[mid]>=nums[left]){
if(target >= nums[left] && target < nums[mid])
right = mid-1;
else
left = mid+1;
}
else {
if(target <= nums[right] && target > nums[mid]) {
left = mid + 1;
} else
right = mid-1;
}
}

return -1;
}
这个代码的思想:

因为位移,所以很有可能最大的点在数组的中间,而不是最右边。

所以在二分查找时,要判断mid是在最大值的左边还是右边,来区分下一次分块如何分。

要特别注意这些位置 while(left<=right)    nums[mid]>=nums[left]   taget>nums[left] target<=nums[right]

如果存在重复的元素就不能单纯地通过nums[mid]和nums[left]的大小比较来判断mid是不是处于升序序列中,还需要最大值所处的位置来进行辅助判断。

如果存在重复的元素(81. Search in Rotated Sorted Array II),则解题的代码为:

private int findmax(int nums[]){
int index=0;
while(index<nums.length-1&&nums[index]<=nums[index+1]) index++;
return index;
}
public boolean search(int[] nums, int target) {
int left=0,right=nums.length-1,max=findmax(nums);
int mid=-1;
while(left<=right){
mid=left+(right-left)/2;
if(nums[mid]==target) break;
if(nums[mid]>=nums[left]&&mid<=max){
if(nums[left]<=target&&target<nums[mid]) right=mid-1;
else left=mid+1;
}
else{
if(nums[mid]<target&&target<=nums[right]){
left=mid+1;
}
else right=mid-1;
}
}
if(left<=right) return true;
else return false;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: