Follow up for "Search in Rotated Sorted Array": What if duplicates are allowed? Would this affect the run-time complexity? How and why? Write a function to determine if a given target is in the array.
分析:条件判断的前面两个部分与变化之前的版本是一样的。最后一行也可以改称递归的方法,对两边都进行查找,然后对其结果去或之后返回。
2014/07/29: 今天又重新做这两道题,在网上看到有人说如果是降序就不对了,觉得很有意思,就接着研究了一下该如何处理。
我觉得,如果不知道数组是生序还是降序的话,需要先判断一下,然后再用这道题的方法进行查找(当然,如果是降序的话,下面的判断条件需要改一下)。我想了一下,琢磨出了一种生降序的判断方法,不知道还有没有更好的,先写下来吧。
首先,无论是生序还是降序,是至少针对三个数来说的。1个数的情况不用多说,无生降序可言。如果是2个数,一次rotation就可以将生序变为降序,或者是将降序变为生序,所以对2个数的数组谈生降序也是毫无疑义的。所以,问题就扩展到了3个和3个以上数的情况。我的方法是,查看前三个数,然后共有下面若干种可能的情况:
1. 前3个数生序:答案显而易见,这个数组在rotated之前一定是生序。
2. 前3个数降序:同样,很容易判断,该数组rotated之前必然是降序。
3. 前3个数先降后生或先生后降:这里开始,情况变的有意思且复杂起来。
(1)首先,我们讨论先降后生的情况。如果画个图,这3个数组成的图像像一个“V”字形。问题的关键在于,这个降的数有啥特殊性?通过分析可以发现,这个数,即第2个数,必然是原数组,也就是被rotate之前的数组,中的最小值。于是,通过比较第1,3个数的关系,我们便可以得到数组的顺序是生还是降。如果第1个数大于第3个,那么数组一定是生序的。相反,如果第1个数小于第3个,那么数组为降序。
(2)基于(1)中的分析,先生后降的情况就不难理解了。这种情况对应的图像像是“^”。中间的第2个数是原数组中的最大值。所以,如果数1小于数3,则数组为降序。若数1大于数3,则数组为生序。
(3)通过观察(1)和(2)中的结果可以看出,对于这种3个数顺序不一致的情况,如果数1大于数3,则原数组为生序;如果数1小于数3,则原数组为降序。
还要说明一下,以上的分析只适用于没有重复的情况(即这道题的I)。如果数组中有重复的话,好像也只能从头到尾扫描来判断数组是生序还是降序了吧,反正目前我还没想到更好的办法。这样做的话,总体的时间复杂度还是O(N),不会发生变化。
public class Solution {
public boolean search(int[] A, int target) {
int low=0, high=A.length-1;
while(low <= high) {
int mid = (low+high)/2;
if(target==A[mid]) return true;
if(A[mid] > A[low]) { // left in order
if(target<A[mid] && target>=A[low]) high=mid-1;
else low=mid+1;
}
else if(A[mid] < A[low]) { // right in order
if(target>A[mid] && target<=A[high]) low=mid+1;
else high=mid-1;
}
else if(A[mid]==A[low]) low+=1; // increase low by 1 and continue
}
return false;
}
}

本文探讨在含有重复元素的旋转有序数组中搜索特定目标值的方法。文章分析了不同情况下数组的特性,并提出一种改进的二分查找算法实现高效搜索。
1933

被折叠的 条评论
为什么被折叠?



