Find Minimum in Rotated Sorted Array I & II

林堯彬發表於2020-04-04

Find Minimum in Rotated Sorted Array I

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

Find the minimum element.

 Notice

You may assume no duplicate exists in the array.

Example

Given [4, 5, 6, 7, 0, 1, 2] return 0

分析:

Although array is rotated, either its left half part or right half part is sorted. We just need to disgard the sorted part, and continue to search in the rotated part. Unlike regular binary search in which start = mid + 1 or end = mid - 1, we need to set start = mid or end = mid, this is to make sure the remaining half is still rotated. When there are only two numbers left, the right one must be the smallest value in the whole rotated array.

 1 public class Solution {
 2     /**
 3      * @param num: a rotated sorted array
 4      * @return: the minimum number in the array
 5      * cnblogs.com/beiyeqingteng/
 6      */
 7     public int findMin(int[] num) {
 8         if (num == null || num.length == 0) return -1;
 9         if (num.length == 1) return num[0];
10         
11         int start = 0;
12         int end = num.length - 1;
13         
14         if (num[start] < num[end]) return num[start];
15         while (start <= end) {
16             int mid = start + (end - start) / 2;
17             if (start + 1 == end) return num[end]; // eventually, there will be only two numbers left
18             if (num[start] < num[mid]){
19                 start = mid; // we don't use start = mid + 1 is to avoid the case in which the remaining array 
20                             // is not rotated sorted array.
21             } else {
22                 end = mid;
23             }
24         }
25         return 0;
26     }
27 }

遞迴的方法:

 1 class Solution {
 2     public int findMin(int[] nums) {
 3         if (nums == null || nums.length == 0) return -1;
 4         return findMinHelper(nums, 0, nums.length - 1);
 5     }
 6     
 7     private int findMinHelper(int[] nums, int start, int end) {
 8         if (start == end) return nums[start];
 9         if (end - start == 1) return Math.min(nums[start], nums[end]);
10         int mid = start + (end - start) / 2;
11         
12         if (nums[start] < nums[end]) {
13             return nums[start];
14         }
15         
16         if (nums[start] < nums[mid]) {
17             return findMinHelper(nums, mid + 1, end);
18         } else {
19             // [3, 1, 2]
20             return findMinHelper(nums, start, mid);
21         }
22     }
23 }

 

Find Minimum in Rotated Sorted Array II

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

Find the minimum element.

 Notice

The array may contain duplicates.

Example

Given [4,4,5,6,7,0,1,2] return 0.

Analysis:

In this case, we have duplicates in the array, so, we cannot compare arr[start] and arr[mid] to determine which part is the rotated part. In stead, we have check all the numbers in the left part. 

 1 public class Solution {
 2 
 3     public int findMin(int[] num) {
 4         if (num == null || num.length == 0) return -1;
 5         if (num.length == 1) return num[0];
 6         
 7         int start = 0;
 8         int end = num.length - 1;
 9         
10         if (num[start] < num[end]) return num[start]; // handle case  4 5 6 7 0 1 2
11         while (start <= end) {
12             if (start + 1 == end) return num[end]; // eventually, there will be only two numbers left
13             int mid = start + (end - start) / 2;
14             if (nonDecreasing(num, start, mid)){
15                 start = mid; 
16             } else {
17                 end = mid;
18             }
19         }
20         return 0;
21     }
22     
23     private boolean nonDecreasing(int[] A, int i, int j) {
24         for (int k = i; k < j; k++) {
25             if (A[k] > A[k + 1] ) return false;
26         }
27         return true;
28     }
29 }

 遞迴解法:

 1 class Solution {
 2     public int findMin(int[] nums) {
 3         if (nums == null || nums.length == 0) return -1;
 4         return findMinHelper(nums, 0, nums.length - 1);
 5     }
 6     
 7     private int findMinHelper(int[] nums, int start, int end) {
 8         if (start == end) return nums[start];
 9         if (end - start == 1) return Math.min(nums[start], nums[end]);
10         int mid = start + (end - start) / 2;
11         boolean firstHalfSorted = sorted(nums, start, mid);
12         boolean secondHalfSorted = sorted(nums, mid, end);
13         
14         if (firstHalfSorted && secondHalfSorted) {
15             return nums[start];
16         }
17         
18         if (firstHalfSorted) {
19             return findMinHelper(nums, mid + 1, end);
20         } else {
21             return findMinHelper(nums, start, mid);
22         }
23     }
24     
25     private boolean sorted(int[] A, int i, int j) {
26         for (int k = i; k < j; k++) {
27             if (A[k] > A[k + 1] ) return false;
28         }
29         return true;
30     }
31 }

 

轉載於:https://www.cnblogs.com/beiyeqingteng/p/5679572.html

相關文章