1 Search in Rotated Sorted Arraynode
二分搜索,注意分清各類狀況算法
1 public class Solution { 2 public int search(int[] nums, int target) { 3 int i = 0, j = nums.length - 1; 4 while (i + 1 < j) { 5 int mid = i + (j - i) / 2; 6 if (nums[mid] == target) { 7 return mid; 8 } 9 10 if (nums[mid] < target) { 11 if (target >= nums[i] && nums[mid] <= nums[i]) { 12 j = mid; 13 } else { 14 i = mid; 15 } 16 } else { 17 if (target <= nums[j] && nums[mid] >= nums[j]) { 18 i = mid; 19 } else { 20 j = mid; 21 } 22 } 23 24 } 25 if (nums[i] == target) { 26 return i; 27 } 28 if (nums[j] == target) { 29 return j; 30 } 31 return -1; 32 } 33 }
這種方法在只有一邊出現的時候容易出bug,target > mid 在對比的時候target和mid都統一用num[i]作比較,target < mid 時用num[j]數組
九章的方式,區分mid在左邊仍是右邊,而後再作判斷,合理簡單不少,代碼以下:less
1 public class Solution { 2 public int search(int[] A, int target) { 3 if (A == null || A.length == 0) { 4 return -1; 5 } 6 7 int start = 0; 8 int end = A.length - 1; 9 int mid; 10 11 while (start + 1 < end) { 12 mid = start + (end - start) / 2; 13 if (A[mid] == target) { 14 return mid; 15 } 16 if (A[start] < A[mid]) { 17 // situation 1, red line 18 if (A[start] <= target && target <= A[mid]) { 19 end = mid; 20 } else { 21 start = mid; 22 } 23 } else { 24 // situation 2, green line 25 if (A[mid] <= target && target <= A[end]) { 26 start = mid; 27 } else { 28 end = mid; 29 } 30 } 31 } // while 32 33 if (A[start] == target) { 34 return start; 35 } 36 if (A[end] == target) { 37 return end; 38 } 39 return -1; 40 } 41 }
follow up : Search in Rotated Sorted Array II ide
注意處理重複元素的方法,o(n)優化
1 public class Solution { 2 /** 3 * param A : an integer ratated sorted array and duplicates are allowed 4 * param target : an integer to be search 5 * return : a boolean 6 */ 7 public boolean search(int[] A, int target) { 8 if (A == null || A.length == 0) { 9 return false; 10 } 11 // write your code here 12 int start = 0; 13 int end = A.length - 1; 14 while (start + 1 < end) { 15 int mid = start + (end - start) / 2; 16 if (A[mid] == target) { 17 return true; 18 } else if (A[mid] == A[end]) { 19 end--; 20 } else if (A[mid] == A[start]){ 21 start++; 22 } else if (A[mid] > A[end]) { 23 //mid on left 24 if (target < A[mid] && target >= A[start]) { 25 end = mid; 26 } else { 27 start = mid; 28 } 29 } else { 30 //mid on right 31 if (target >= A[mid] && target <= A[end]) { 32 start = mid; 33 } else { 34 end = mid; 35 } 36 } 37 } 38 39 if (A[start] == target) { 40 return true; 41 } else if (A[end] == target){ 42 return true; 43 } else { 44 return false; 45 } 46 } 47 }
2. search in a big sorted arraythis
注意 起始點 2^0 = 1, 因此從2^n - 1開始。 或者直接從0開始。這道題二分算法,從0開始和從2^n - 1開始不影響總體複雜度。spa
本題的重點在於用一個lgn的時間找到末尾節點3d
1 /** 2 * Definition of ArrayReader: 3 * 4 * class ArrayReader { 5 * // get the number at index, return -1 if index is less than zero. 6 * public int get(int index); 7 * } 8 */ 9 public class Solution { 10 /** 11 * @param reader: An instance of ArrayReader. 12 * @param target: An integer 13 * @return : An integer which is the index of the target number 14 */ 15 public int searchBigSortedArray(ArrayReader reader, int target) { 16 // write your code here 17 int slow = 0; 18 int fast = 1; 19 while (reader.get(2^fast) < target) { 20 fast++; 21 slow++; 22 } 23 24 25 int start = 2 ^ slow - 1; 26 int end = 2 ^ fast; 27 while (start + 1 < end) { 28 int mid = start + (end - start) / 2; 29 if (target > reader.get(mid)) { 30 start = mid; 31 } else { 32 end = mid; 33 } 34 } 35 if (reader.get(start) == target) { 36 return start; 37 } else if (reader.get(end) == target) { 38 return end; 39 } else { 40 return -1; 41 } 42 } 43 }
3. wood cutcode
Given n pieces of wood with length L[i]
(integer array). Cut them into small pieces to guarantee you could have equal or more than k pieces with the same length. What is the longest length you can get from the n pieces of wood? Given L & k, return the maximum length of the small pieces.
You couldn't cut wood into float length.
For L=[232, 124, 456]
, k=7
, return 114
.
二分cut的長度,注意長度從最長的板子的長度開始,而不是從最短的板子長度開始
1 public class Solution { 2 /** 3 *@param L: Given n pieces of wood with length L[i] 4 *@param k: An integer 5 *return: The maximum length of the small pieces. 6 */ 7 public int woodCut(int[] L, int k) { 8 // write your code here 9 int max = Integer.MIN_VALUE; 10 for (int len : L) { 11 max = Math.max(max, len); 12 } 13 int min = 1; 14 while (min + 1 < max) { 15 int mid = min + (max - min) / 2; 16 if (get(L, mid) >= k) { 17 min = mid; 18 } else { 19 max = mid; 20 } 21 } 22 if (get(L, max) >= k) { 23 return max; 24 } else if (get(L, min) >= k) { 25 return min; 26 } 27 else { 28 return 0; 29 } 30 31 32 33 } 34 private int get(int[] L, int len) { 35 int count = 0; 36 for (int temp : L) { 37 count += (temp/len); 38 } 39 return count; 40 } 41 }
4. Find Peak Element
A peak element is an element that is greater than its neighbors.
Given an input array where num[i] ≠ num[i+1]
, find a peak element and return its index.
The array may contain multiple peaks, in that case return the index to any one of the peaks is fine.
You may imagine that num[-1] = num[n] = -∞
.
For example, in array [1, 2, 3, 1]
, 3 is a peak element and your function should return the index number 2.
思路:若是中間元素大於其相鄰後續元素,則中間元素左側(包含該中間元素)必包含一個局部最大值。若是中間元素小於其相鄰後續元素,則中間元素右側必包含一個局部最大值。
1 public class Solution { 2 public int findPeakElement(int[] nums) { 3 if (nums.length < 2) { 4 return 0; 5 } 6 int start = 0; 7 int end = nums.length - 1; 8 while (start + 1 < end) { 9 int mid = start + (end - start) / 2; 10 if (nums[mid] > nums[mid - 1]) { 11 start = mid; 12 } else { 13 end = mid; 14 } 15 } 16 return nums[start] > nums[end] ? start : end; 17 } 18 }
5. Total Occurrence of Target
1 public class Solution { 2 /** 3 * @param A an integer array sorted in ascending order 4 * @param target an integer 5 * @return an integer 6 */ 7 public int totalOccurrence(int[] A, int target) { 8 if (A == null || A.length == 0) { 9 return 0; 10 } 11 // Write your code here 12 int gobalStart, gobalEnd; 13 14 int start = 0; 15 int end = A.length - 1; 16 //search for the first index 17 while (start + 1 < end) { 18 int mid = start + (end - start) /2; 19 if (A[mid] >= target) { 20 end = mid; 21 } else { 22 start = mid; 23 } 24 } 25 if (A[start] == target) { 26 gobalStart = start; 27 } else if (A[end] == target) { 28 gobalStart = end; 29 } else { 30 return 0; 31 } 32 //gobalStart = A[start] == target ? start : end; 33 //failed for test case : [4], 3 34 35 36 37 //search for second index 38 end = A.length - 1; 39 while (start + 1 < end) { 40 int mid = start + (end - start) / 2; 41 if (A[mid] <= target) { 42 start = mid; 43 } else { 44 end = mid; 45 } 46 } 47 gobalEnd = A[end] == target ? end : start; 48 49 return gobalEnd - gobalStart + 1; 50 } 51 }
6. K Closest Numbers In Sorted Array
1 public class Solution { 2 /** 3 * @param A an integer array 4 * @param target an integer 5 * @param k a non-negative integer 6 * @return an integer array 7 */ 8 public int[] kClosestNumbers(int[] A, int target, int k) { 9 // Write your code here 10 if (A == null || A.length == 0 || A.length < k) { 11 return null; 12 } 13 int start = 0; 14 int end = A.length - 1; 15 while (start + 1 < end) { 16 int mid = start + (end - start) - 1; 17 if (A[mid] >= target) { 18 end = mid; 19 } else { 20 start = mid; 21 } 22 } 23 int left, right; 24 left = start; 25 right = end; 26 27 ArrayList<Integer> temp = new ArrayList<Integer>(); 28 for (int i = 0; i < k; i++) { 29 //note : when difference equals add left node first! 30 if (Math.abs(target - A[left]) <= Math.abs(target - A[right])) { 31 temp.add(A[left]); 32 if(left > 0) { 33 left--; 34 } else { 35 i++; 36 while (i < k) { 37 temp.add(A[right]); 38 right++; 39 i++; 40 } 41 } 42 } else { 43 temp.add(A[right]); 44 if (right < A.length - 1) { 45 right++; 46 } else { 47 i++; 48 while (i < k) { 49 temp.add(A[left]); 50 left--; 51 i++; 52 } 53 } 54 } 55 } 56 int[] ret = new int[temp.size()]; 57 for (int i = 0; i < temp.size(); i++) 58 { 59 ret[i] = temp.get(i); 60 } 61 return ret; 62 63 } 64 }
其實不須要使用arraylist,由於給了k的size,直接新建一個大小爲k的array就好。
另外能夠優化一下循環結構體
版本2
用的if continue代替了if else
1 public class Solution { 2 /** 3 * @param A an integer array 4 * @param target an integer 5 * @param k a non-negative integer 6 * @return an integer array 7 */ 8 public int[] kClosestNumbers(int[] A, int target, int k) { 9 // Write your code here 10 if (A == null || A.length == 0 || A.length < k) { 11 return null; 12 } 13 int start = 0; 14 int end = A.length - 1; 15 while (start + 1 < end) { 16 int mid = start + (end - start) - 1; 17 if (A[mid] >= target) { 18 end = mid; 19 } else { 20 start = mid; 21 } 22 } 23 int left, right; 24 left = start; 25 right = end; 26 27 int[] temp = new int[k]; 28 for (int i = 0; i < k; i++) { 29 30 if (left < 0) { 31 temp[i] = A[right]; 32 right++; 33 continue; 34 } 35 if (right >= A.length) { 36 temp[i] = A[left]; 37 left--; 38 continue; 39 } 40 41 //note : when difference equals add left node first! 42 if (Math.abs(target - A[left]) <= Math.abs(target - A[right])) { 43 temp[i]= A[left]; 44 left--; 45 } else { 46 temp[i] = A[right]; 47 right++; 48 } 49 } 50 return temp; 51 } 52 }
7. Find Minimum in Rotated Sorted Array II
對於1111111111101的極端狀況 只能用0(n)的方法解
1 public class Solution { 2 /** 3 * @param num: a rotated sorted array 4 * @return: the minimum number in the array 5 */ 6 public int findMin(int[] num) { 7 if (num == null || num.length == 0) { 8 return 0; 9 } 10 int start = 0; 11 int end = num.length - 1; 12 while (start + 1 < end) { 13 int mid = start + (end - start) / 2; 14 // on left part 15 if (num[mid] == num[end]) { 16 //用於解決11111111111111111101的狀況 17 end--; 18 } 19 else if (num[mid] >= num[end]) { 20 start = mid; 21 } else { 22 end = mid; 23 } 24 } 25 return Math.min(num[start], num[end]); 26 27 } 28 }
1 public class Solution { 2 /** 3 * @param matrix: A list of lists of integers 4 * @param: A number you want to search in the matrix 5 * @return: An integer indicate the occurrence of target in the given matrix 6 */ 7 public int searchMatrix(int[][] matrix, int target) { 8 // write your code here 9 if (matrix == null || matrix.length == 0) { 10 return 0; 11 } 12 13 int m = matrix[0].length; 14 int n = matrix.length; 15 int x, y; 16 int count = 0; 17 x = n - 1; 18 y = 0; 19 while (x >= 0 && y <= m -1) { 20 if (matrix[x][y] == target) { 21 count++; 22 x--; 23 } else if (matrix[x][y] < target) { 24 y++; 25 } else { 26 x--; 27 } 28 29 } 30 return count; 31 } 32 }