zoukankan      html  css  js  c++  java
  • 2 Binary Search & LogN Algorithm

    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 }
  • 相关阅读:
    Linux内核TSS的使用
    DPL, CPL及RPL之间的关系
    Linux内存管理(深入理解Linux内核)
    Windows下安装PIL进行图像处理
    内存Zone中的pageset成员分析
    导出符号的意义
    GDI及Windows的消息机制
    kmalloc vs vmalloc
    Linux Kernel Development有关内存管理
    STL sort
  • 原文地址:https://www.cnblogs.com/jenna/p/10733567.html
Copyright © 2011-2022 走看看