diff --git a/leetcode_java/src/main/java/LeetCodeJava/BinarySearch/FindMinimumInRotatedSortedArray.java b/leetcode_java/src/main/java/LeetCodeJava/BinarySearch/FindMinimumInRotatedSortedArray.java index 5e40590d..5c07f7c1 100644 --- a/leetcode_java/src/main/java/LeetCodeJava/BinarySearch/FindMinimumInRotatedSortedArray.java +++ b/leetcode_java/src/main/java/LeetCodeJava/BinarySearch/FindMinimumInRotatedSortedArray.java @@ -1,8 +1,5 @@ package LeetCodeJava.BinarySearch; -import java.util.Arrays; - - // https://leetcode.com/problems/find-minimum-in-rotated-sorted-array/ /** @@ -13,69 +10,111 @@ * Companies * Hint * Suppose an array of length n sorted in ascending order is rotated between 1 and n times. For example, the array nums = [0,1,2,4,5,6,7] might become: - * + *
* [4,5,6,7,0,1,2] if it was rotated 4 times. * [0,1,2,4,5,6,7] if it was rotated 7 times. * Notice that rotating an array [a[0], a[1], a[2], ..., a[n-1]] 1 time results in the array [a[n-1], a[0], a[1], a[2], ..., a[n-2]]. - * + *
* Given the sorted rotated array nums of unique elements, return the minimum element of this array. - * + *
* You must write an algorithm that runs in O(log n) time. - * - * - * + *
+ *
+ *
* Example 1: - * + *
* Input: nums = [3,4,5,1,2] * Output: 1 * Explanation: The original array was [1,2,3,4,5] rotated 3 times. * Example 2: - * + *
* Input: nums = [4,5,6,7,0,1,2] * Output: 0 * Explanation: The original array was [0,1,2,4,5,6,7] and it was rotated 4 times. * Example 3: - * + *
* Input: nums = [11,13,15,17] * Output: 11 * Explanation: The original array was [11,13,15,17] and it was rotated 4 times. - * - * + *
+ *
* Constraints: - * + *
* n == nums.length * 1 <= n <= 5000 * -5000 <= nums[i] <= 5000 * All the integers of nums are unique. * nums is sorted and rotated between 1 and n times. - * - * */ public class FindMinimumInRotatedSortedArray { - // V0' + // V0 // IDEA : BINARY SEARCH (CLOSED BOUNDARY) + public int findMin(int[] nums) { + + // edge case 1): if len == 1 + if (nums.length == 1) { + return nums[0]; + } + + // edge case 1): array already in ascending order + int left = 0; + int right = nums.length - 1; + if (nums[right] > nums[0]) { + return nums[0]; + } + + // binary search + while (right >= left) { + int mid = (left + right) / 2; + // turning point case 1 + if (nums[mid] > nums[mid + 1]) { + return nums[mid + 1]; + } + // TODO : check why below + // turning point case 2 + // if (nums[mid] > nums[mid-1]){ + // return nums[mid - 1]; + // } + if (nums[mid - 1] > nums[mid]) { + return nums[mid]; + } + // left sub array is ascending + if (nums[mid] > nums[0]) { + left = mid + 1; + } + // right sub array is ascending + else { + right = mid - 1; + } + } + + return -1; + } + + // V0'' + // IDEA : BINARY SEARCH (CLOSED BOUNDARY) + /** - * * NOTE !!! the turing point (rotation point) - * -> it's ALWAYS the place that min element located (may at at i, i+1, i-1 place) - * - * case 1) check turing point - * case 2) check if left / right sub array is in Ascending order + * -> it's ALWAYS the place that min element located (may at at i, i+1, i-1 place) + *
+ * case 1) check turing point + * case 2) check if left / right sub array is in Ascending order */ public int findMin_0_1(int[] nums) { - if (nums.length == 0 || nums.equals(null)){ + if (nums.length == 0 || nums.equals(null)) { return 0; } // check if already in ascending order - if (nums[0] < nums[nums.length - 1]){ + if (nums[0] < nums[nums.length - 1]) { return nums[0]; } - if (nums.length == 1){ + if (nums.length == 1) { return nums[0]; } @@ -84,7 +123,7 @@ public int findMin_0_1(int[] nums) { int r = nums.length - 1; /** NOTE !!! here : r >= l (closed boundary) */ - while (r >= l){ + while (r >= l) { int mid = (l + r) / 2; /** NOTE !!! BELOW 4 CONDITIONS @@ -97,23 +136,23 @@ public int findMin_0_1(int[] nums) { */ /** NOTE !!! we found turing point, and it's the minimum element (idx = mid + 1) */ - if (nums[mid] > nums[mid+1]){ - return nums[mid+1]; + if (nums[mid] > nums[mid + 1]) { + return nums[mid + 1]; - /** NOTE !!! we found turing point, and it's the minimum element (idx = mid -1) */ - }else if (nums[mid-1] > nums[mid]){ + /** NOTE !!! we found turing point, and it's the minimum element (idx = mid -1) */ + } else if (nums[mid - 1] > nums[mid]) { return nums[mid]; - /** NOTE !!! compare mid with left, and this means left sub array is ascending order, - * so minimum element MUST in right sub array - */ - }else if (nums[mid] > nums[l]){ + /** NOTE !!! compare mid with left, and this means left sub array is ascending order, + * so minimum element MUST in right sub array + */ + } else if (nums[mid] > nums[l]) { l = mid + 1; - /** NOTE !!! compare mid with left, and this means right sub array is ascending order, - * so minimum element MUST in left sub array - */ - }else{ + /** NOTE !!! compare mid with left, and this means right sub array is ascending order, + * so minimum element MUST in left sub array + */ + } else { r = mid - 1; } @@ -126,12 +165,12 @@ public int findMin_0_1(int[] nums) { // IDEA : BINARY SEARCH (OPEN BOUNDARY) public int findMin_2(int[] nums) { - if (nums.length == 0 || nums.equals(null)){ + if (nums.length == 0 || nums.equals(null)) { return 0; } // already in ascending order - if (nums[0] < nums[nums.length - 1]){ + if (nums[0] < nums[nums.length - 1]) { return nums[0]; } @@ -139,12 +178,12 @@ public int findMin_2(int[] nums) { int l = 0; int r = nums.length - 1; /** NOTE !!! here : r > l (open boundary) */ - while (r > l){ + while (r > l) { int mid = (l + r) / 2; - if (nums[mid] > nums[r]){ + if (nums[mid] > nums[r]) { /** NOTE !!! here : (open boundary) */ l = mid + 1; - }else{ + } else { /** NOTE !!! here : (open boundary) */ r = mid; } diff --git a/leetcode_java/src/main/java/dev/workspace5.java b/leetcode_java/src/main/java/dev/workspace5.java index f6185050..04f30f32 100644 --- a/leetcode_java/src/main/java/dev/workspace5.java +++ b/leetcode_java/src/main/java/dev/workspace5.java @@ -3686,62 +3686,111 @@ public int minMeetingRooms(int[][] intervals) { * left is ascending * - the target val is bigger / smaller than cur */ - public int findMin(int[] nums) { + public int findMin(int[] nums){ + // edge case 1): if len == 1 if (nums.length == 1){ return nums[0]; } - if (nums[0] < nums[nums.length-1]){ + // edge case 1): array already in ascending order + int left = 0; + int right = nums.length - 1; + if (nums[right] > nums[0]){ return nums[0]; } // binary search - int left = 0; - int right = nums.length-1; - - while (left >= right){ - - int mid = (left + right) / 2; - - System.out.println(">>> mid = " + mid + ", left = " + left + ", right = " + right); - - // turning point (??? + while (right >= left){ + int mid = (left + right) / 2; + // turning point case 1 if (nums[mid] > nums[mid+1]){ - return nums[mid+1]; - // turning point (???? - }else if (nums[mid] < nums[mid-1]){ + return nums[mid + 1]; + } + // TODO : check why below + // turning point case 2 + // if (nums[mid] > nums[mid-1]){ + // return nums[mid - 1]; + // } + if (nums[mid - 1] > nums[mid]) { return nums[mid]; - // norming ordering, compare mid and - }else if (nums[mid] > nums[left]){ - //right = mid; + } + // left sub array is ascending + if (nums[mid] > nums[0]){ left = mid + 1; - }else{ - //left = mid + 1; - right = mid-1; } - -// // right is ascending -// if (nums[mid] < nums[mid+1]){ -// if (nums[mid] > nums[mid-1]){ -// right = mid; -// }else{ -// left = mid + 1; -// } -// -// } -// // left is ascending -// else{ -// if (nums[mid] < nums[mid+1]){ -// right = mid; -// }else{ -// left = mid + 1; -// } -// } + // right sub array is ascending + else{ + right = mid - 1; + } } - return nums[left]; + return -1; } + /** + * + * [4,5,6,7,0,1,2] + * + * [7,0,1,2,4,5,6] + * + * + */ +// public int findMin(int[] nums) { +// +// if (nums.length == 1){ +// return nums[0]; +// } +// +// if (nums[0] < nums[nums.length-1]){ +// return nums[0]; +// } +// +// // binary search +// int left = 0; +// int right = nums.length-1; +// +// while (left >= right){ +// +// int mid = (left + right) / 2; +// +// System.out.println(">>> mid = " + mid + ", left = " + left + ", right = " + right); +// +// // turning point (??? +// if (nums[mid] > nums[mid+1]){ +// return nums[mid+1]; +// // turning point (???? +// }else if (nums[mid] < nums[mid-1]){ +// return nums[mid]; +// // norming ordering, compare mid and +// }else if (nums[mid] > nums[left]){ +// //right = mid; +// left = mid + 1; +// }else{ +// //left = mid + 1; +// right = mid-1; +// } +// +//// // right is ascending +//// if (nums[mid] < nums[mid+1]){ +//// if (nums[mid] > nums[mid-1]){ +//// right = mid; +//// }else{ +//// left = mid + 1; +//// } +//// +//// } +//// // left is ascending +//// else{ +//// if (nums[mid] < nums[mid+1]){ +//// right = mid; +//// }else{ +//// left = mid + 1; +//// } +//// } +// } +// +// return nums[left]; +// } }