Search In Rotated SortedArray2, 有重复数据的反转序列。例如13111.

问题描述:反转序列,但是有重复的元素,例如序列13111。

算法思路:如果元素有重复,那么left-mid,就不一定是有序的了,所以不能利用二分搜索,二分搜索必须是局部有序。针对有序序列的反转,如果有重复数据的话,那么必然是nums[left]=nums[mid]=nums[right],增加对这种情况的讨论即可。

 

 1 public boolean search(int[] nums, int target) 
 2     {
 3         return binarySearch(nums, 0, nums.length - 1, target);
 4     }
 5     //递归方法
 6     public boolean binarySearch(int[] nums, int left, int right, int target)
 7     {
 8         //不要忘了这个边界条件。
 9         if(left > right)
10         {
11             return false;
12         }
13         int mid = (left + right)/2;
14         if(target == nums[mid])
15         {
16             return true;
17         }
18         
19         //假设序列为13111,那么nums[mid]=nums[right]=nums[left],left和mid之间就不是有序序列了。
20         //并且这种特殊情况,只可能是nums[mid]=nums[left]=nums[right],所以,移动left和right.
21         //二分查找的关键就是要局部序列有序。
22         if(nums[left] == nums[mid] && nums[mid] == nums[right])
23         {
24             return binarySearch(nums, left + 1, right - 1, target);
25         }
26         
27         else if(nums[left] <= nums[mid])//做连续,要包含"="的情况,否则出错。
28         {
29             if(target >= nums[left] && target < nums[mid])//target上下限都要有
30             {
31                 return binarySearch(nums, left, mid - 1, target);//记得return
32             }
33             else
34             {
35                 return binarySearch(nums, mid + 1, right, target);
36             }
37         }
38         else
39         {
40             if(target > nums[mid] && target <= nums[right])
41             {
42                 return binarySearch(nums, mid + 1, right, target);
43             }
44             else
45             {
46                 return binarySearch(nums, left, mid - 1, target);
47             }
48         }
49     }
50     
51     
52     //迭代方法
53     public boolean binarySearch2(int[] nums, int left, int right, int target)
54     {
55         
56         while(left <= right)
57         {
58             int mid = (left + right)/2;
59             if(target == nums[mid])
60             {
61                 return true;
62             }
63             if(nums[left] == nums[mid] && nums[mid] == nums[right])
64             {
65                 left ++;
66                 right --;
67             }
68             else if(nums[left] <= nums[mid]) //左连续,所以要包含=的情况。否则出错。
69             {
70                 if(target >= nums[left] && target < nums[mid])
71                 {
72                     right = mid - 1;
73                 }
74                 else
75                 {
76                     left = mid + 1;
77                 }
78             }
79             else
80             {
81                 if(target > nums[mid] && target <= nums[right])
82                 {
83                     left = mid + 1;
84                 }
85                 else
86                 {
87                     right = mid - 1;
88                 }
89             }
90         }
91         return false;
92     }

 

posted @ 2016-06-09 14:52  32ddd  阅读(168)  评论(0编辑  收藏  举报