254. Drop Eggs
https://www.lintcode.com/problem/drop-eggs/description?_from=ladder&&fromId=1
28. Search a 2D Matrix
https://www.lintcode.com/problem/search-a-2d-matrix/description?_from=ladder&&fromId=1
思路1:
1. find the row index, the last number <= target
2. find the column index, the number equal to target
public class Solution { /** * @param matrix: matrix, a list of lists of integers * @param target: An integer * @return: a boolean, indicate whether matrix contains target */ public boolean searchMatrix(int[][] matrix, int target) { // write your code here if(matrix == null || matrix.length == 0) return false; int left = 0, right = matrix[0].length - 1; int row = findRow(matrix, target); if(matrix[row][0] > target || matrix[row][right] < target) { return false; } while(left + 1 < right) { int mid = left + (right - left) / 2; if(matrix[row][mid] == target) { return true; } else if(matrix[row][mid] > target) { right = mid; } else { left = mid; } } if(matrix[row][left] == target || matrix[row][right] == target) { return true; } else { return false; } } public int findRow(int[][] matrix, int target) { int top = 0, bottom = matrix.length - 1, right = matrix[0].length - 1; while(top + 1 < bottom) { int mid = top + (bottom - top) / 2; if(matrix[mid][right] == target) { return mid; } else if(matrix[mid][right] > target) { bottom = mid; } else { top = mid; } } if(matrix[top][right] >= target) { return top; } else { return bottom; } } }
思路2:
1. 可以看作是一个有序数组被分成了n段,每段就是一行。因此依然可以二分求解。
对每个数字,根据其下标 i,j 进行编号,每个数字可被编号为 0 ~ n *(n - 1)
2. 相当于是在一个数组中的下标,然后直接像在数组中二分一样来做。取得 mid 要还原成二维数组中的下标,i = mid / n, j = mid % n
3. int start = 0, end = row * row * column - 1;
int number = matrix[mid / column][mid % column];
// Binary Search Once public class Solution { /** * @param matrix, a list of lists of integers * @param target, an integer * @return a boolean, indicate whether matrix contains target */ public boolean searchMatrix(int[][] matrix, int target) { // write your code here if(matrix == null || matrix.length == 0){ return false; } if(matrix[0] == null || matrix[0].length == 0){ return false; } int row = matrix.length; int column = matrix[0].length; int start = 0, end = row * column - 1; while(start <= end){ int mid = start + (end - start) / 2; int number = matrix[mid / column][mid % column]; if(number == target){ return true; }else if(number > target){ end = mid - 1; }else{ start = mid + 1; } } return false; } }
14. First Position of Target
https://www.lintcode.com/problem/first-position-of-target/description?_from=ladder&&fromId=1
思路:这道题很简单。套用二分法的模版即可
1 public class Solution { 2 /** 3 * @param nums: The integer array. 4 * @param target: Target to find. 5 * @return: The first position of target. Position starts from 0. 6 */ 7 public int binarySearch(int[] nums, int target) { 8 // write your code here 9 if(nums == null || nums.length == 0) return -1; 10 int start = 0, end = nums.length - 1; 11 while(start + 1 < end) { 12 int mid = start + (end - start) / 2; 13 if(nums[mid] >= target) { 14 end = mid; 15 } else { 16 start = mid; 17 } 18 } 19 if(nums[start] == target) { 20 return start; 21 } 22 if(nums[end] == target) { 23 return end; 24 } 25 return -1; 26 } 27 }
414. Divide Two Integers
https://www.lintcode.com/problem/divide-two-integers/description?_from=ladder&&fromId=1
1. 凡是要移位,要做的第一件事就是把 int 转换成 long,为了防止移位时溢出。
2. 基本思路是利用减法,看看被除数可以减去多少次除数。使用倍增的思想优化,可以将减法的次数优化到对数的时间复杂度。
3. 我们将除数左移一位(或加上它自己),即得到了二倍的除数,这时一次相当于减去了两个除数,通过不断倍增,时间复杂度很优秀。
4. 与此同时,还需要一个变量记录此时的除数是最初除数的多少倍,每次减法后都加到结果上即可。
1 public class Solution { 2 /** 3 * @param dividend: the dividend 4 * @param divisor: the divisor 5 * @return: the result 6 */ 7 public int divide(int dividend, int divisor) { 8 // write your code here 9 if(divisor == 0) { 10 return dividend >= 0 ? Integer.MAX_VALUE : Integer.MIN_VALUE; 11 } 12 if(dividend == 0) { 13 return 0; 14 } 15 if(divisor == -1 && dividend == Integer.MIN_VALUE) { 16 return Integer.MAX_VALUE; 17 } 18 boolean isNegative = ((divisor > 0 && dividend < 0) || (divisor < 0 && dividend > 0)) ? true : false; 19 long divisorL = Math.abs((long)divisor); 20 long dividendL = Math.abs((long)dividend); 21 int result = 0; 22 while(dividendL >= divisorL) { 23 int shift = 0; 24 while(dividendL >= (divisorL << shift)) { 25 shift++; 26 } 27 result += 1 << (shift - 1); 28 dividendL -= divisorL << (shift - 1); 29 } 30 if(isNegative) { 31 return result * (-1); 32 } 33 return result; 34 } 35 }
61. Search for a Range
https://www.lintcode.com/problem/search-for-a-range/description?_from=ladder&&fromId=1
这道题同样很简单,套用模版即可。
1 public class Solution { 2 /** 3 * @param A: an integer sorted array 4 * @param target: an integer to be inserted 5 * @return: a list of length 2, [index1, index2] 6 */ 7 public int[] searchRange(int[] A, int target) { 8 // write your code here 9 if(A == null || A.length == 0) return new int[]{-1, -1}; 10 int start = findStart(A, target); 11 int end = findEnd(A, target); 12 return new int[]{start, end}; 13 14 } 15 16 public int findStart(int[] A, int target) { 17 int start = 0; 18 int end = A.length - 1; 19 while(start + 1 < end) { 20 int mid = start + (end - start) / 2; 21 if(A[mid] < target) { 22 start = mid; 23 } else { 24 end = mid; 25 } 26 } 27 if(A[start] == target) { 28 return start; 29 } 30 if(A[end] == target) { 31 return end; 32 } 33 return -1; 34 } 35 36 public int findEnd(int[] A, int target) { 37 int start = 0; 38 int 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 if(A[end] == target) { 48 return end; 49 } 50 if(A[start] == target) { 51 return start; 52 } 53 return -1; 54 } 55 }
原文地址:https://www.cnblogs.com/jenna/p/10733567.html