leetcode:Search in Rotated Sorted Array II

贴一下题目:

1.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.

------------------------------------------------------------------------------------------------------

2.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.

------------------------------------------------------------------------------------------------------

      这道题目与上面那一道有所不同,其允许重复,我在纸上写了几个这样的允许重复的例子,按照这个例子去修改前题的代码,结果依旧是错的,其实自己造例子不是一件坏事,但不好的地方在于你想的用于测试的例子永远都是那么几种,无法考虑周全,这时依据例子盲目的改代码就很傻了,结果可能是漏洞百出,我感觉应该是要以思路为主导,在上题的正确思路的基础上进行修改,比较上下两题的细微差异所带来的问题,修改思路,然后才是改代码。

     上题不允许重复,代码如下:

 1 class Solution {
 2 public:
 3     int search(int A[], int n, int target) {
 4         int first=0,last=n-1,mid=0;
 5         while(first<=last){
 6                 mid=(first+last)/2;
 7                 if(A[mid]==target) return mid;
 8                 
 9                 if(A[first]<=A[mid])
10                    {if(A[first]<=target&&A[mid]>target) last=mid-1;
11                     else first=mid+1;}
12                 else{if(A[mid]<target&&A[last]>=target) first=mid+1;
13                      else last=mid-1; }
14         
15         } return -1;
16     }
17 };

if(A[first]<=A[mid])这一句就可以将有序的部分判别出来,如果前面满足,自然是前面有序,如果前面不满足,那就肯定是后面有序了,整个程序有两个入口,if和else二者只入其一,while内部做的都是修改左右边界,把mid计算放在开始的地方是很好的,一次循环只更新一次mid。

允许重复时就不可以通过一句if(A[first]<=A[mid])来判断出有序和无序了,当然这时肯定也会分成有序和无序两部分,因为等号时存在无序的情况(11311111111111111

所以思路要有所改变,大方向依然是上面的思路,但此时要将有序判断部分修改,至少要将这两种情况拆分开来,if(A[first]<A[mid])肯定是有序的,这时前面有序,如果满足这一条那就判断在不在前半段,在就last=mid-1,不在的话那肯定就在(无序)的后半段了,这时只要将first=mid+1就好了,还有一种情况是后半段有序前半段无序,这时该怎么处理呢,有顺序的后半段该怎么判别出来呢,因为有序对应的是两种情况,而我们希望通过一个判断就区分开来,解决办法是这时不是判断后半段有序来区分,而是判断前半段无序来区分if(A[first]>A[mid])说明前半段无序,那言外之意是后半段有序了,如果满足此条件我们就判断target会不会在后半段,如果在后半段那没的说first=mid+1,如果不在后半段那肯定在前半段,那我们就last=mid-1,这样还是将范围缩小了。

但是,对于相等的情况该怎么办呢,(11311111111111111),我们就逐步排除元素直至出现有序,方法是如果上面两条都不满足就在最后first++,因为上面都不满足肯定是

A[first]==A[mid]了,所以也就是说first不是target了,这样一次循环,运气好砍掉一半,运气差就排出一个元素,最后总是会找到的。

我这个大菜鸟在编程时出现的问题是对if语句理解不好,两个判断分支的话两个入口必进其一,但三个时就不会处理了(此时处理的次序也很重要),三个最多只进其一。

 1 if(表达式一)
 2         if(表达式二) 语句一;
 3         else  语句二;
 4 else
 5         语句三。
 6 //if else,二者必进其一,里面可以嵌套处理,但要注意搭配。
 7 //=======================================================
 8 if(表达式1) 语句1;
 9 else if(表达式2) 语句2;
10 else if(表达式3) 语句3;
11 else if(表达式4) 语句4;
12 、、、、、、、、、、、、
13 else   语句n;
14 //此时是多必进其一,多只可进其一。
15 //=======================================================
16 if(表达式1) 语句1;
17 if(表达式2) 语句2;
18 if(表达式3) 语句3;
19 if(表达式4) 语句4;
20 if(表达式5) 语句5;
21 、、、、、、、、、、、、
22 else   语句n;
23 
24 //这时顺序判断进入,前面if语句内部的处理可能会影响到后面的判断要注意,最后的else也可以去掉。

最后是题目解答:

 

 1 class Solution {
 2 public:
 3     bool search(int A[], int n, int target) {
 4          int first=0,last=n-1,mid=0;
 5         while(first<=last){
 6                 mid=(first+last)/2;
 7                 if(A[mid]==target) return true;
 8             
 9                 if(A[first]<A[mid])
10                    {if(A[first]<=target&&A[mid]>target) last=mid-1;
11                     else first=mid+1;}
12                 else if(A[first]>A[mid]) 
13                    {
14                      if(A[mid]<target&&A[last]>=target){first=mid+1;}
15                      else last=mid-1;  }
16                 else  first++;
17         
18         } return false; 
19         
20     }
21 };

 

posted @ 2015-04-18 09:06  韩冰云  阅读(91)  评论(0编辑  收藏  举报