Data Structure and Algorithm - Day 09

  • Binary Search

    premise : 1. monotonicity 2. exist upper and lower bound 3. index accessible

    left, right = 0, len(array) - 1
    while left <= right:
        mid = (right - left) / 2 + left
        if array[mid] == target:
            # find the target !
            break or return result
        elif array[mid] < target:
            left = mid + 1
        else
        	right = mid - 1
    
  • 69. Sqrt(x)

    Given a non-negative integer x, compute and return the square root of x.

    Since the return type is an integer, the decimal digits are truncated, and only the integer part of the result is returned.

    Example 1:

    Input: x = 4
    Output: 2
    

    Example 2:

    Input: x = 8
    Output: 2
    Explanation: The square root of 8 is 2.82842..., and since the decimal part is truncated, 2 is returned.
    
    class Solution {
        public int mySqrt(int x) {
            if (x == 0 || x == 1) {
                return x;
            }
            int left = 1, right = x;
            while (left <= right) {
                int mid = left + (right - left) / 2;
                if ((long)mid * mid > x) {
                    right = mid - 1;
                } else {
                    left = mid + 1;
                }
            }
            return right;
        }
    }
    
    // Newton iterative method
    class Solution {
        public int mySqrt(int x) {
            if (x == 0) {
                return 0;
            }
    
            double C = x, x0 = x;
            while (true) {
                double xi = 0.5 * (x0 + C / x0);
                if (Math.abs(x0 - xi) < 1e-7) {
                    break;
                }
                x0 = xi;
            }
            return (int) x0;
        }
    }
    
  • 33. Search in Rotated Sorted Array

    There is an integer array nums sorted in ascending order (with distinct values).

    Prior to being passed to your function, nums is rotated at an unknown pivot index k (0 <= k < nums.length) such that the resulting array is [nums[k], nums[k+1], ..., nums[n-1], nums[0], nums[1], ..., nums[k-1]] (0-indexed). For example, [0,1,2,4,5,6,7] might be rotated at pivot index 3 and become [4,5,6,7,0,1,2].

    Given the array nums after the rotation and an integer target, return the index of target if it is in nums, or -1 if it is not in nums.

    Example 1:

    Input: nums = [4,5,6,7,0,1,2], target = 0
    Output: 4
    

    Example 2:

    Input: nums = [4,5,6,7,0,1,2], target = 3
    Output: -1
    

    Example 3:

    Input: nums = [1], target = 0
    Output: -1
    

    Constraints:

    • 1 <= nums.length <= 5000
    • -104 <= nums[i] <= 104
    • All values of nums are unique.
    • nums is guaranteed to be rotated at some pivot.
    • -104 <= target <= 104
    class Solution {
        public int search(int[] nums, int target) {
            int left = 0, right = nums.length - 1;
            while (left <= right) {
                int mid = (right - left) / 2 + left;
                if (nums[mid] == target) {
                    return mid;
                } else if (nums[left] <= nums[mid]){ // left is orderly
                    if (target < nums[mid] && target >= nums[left]) {
                        right = mid - 1;
                    } else {
                        left = mid + 1;
                    }
                } else { // right is orderly
                    if (target > nums[mid] && target <= nums[right]){
                        left = mid + 1;
                    } else {
                        right = mid - 1;
                    }
                }
            }
            return -1;
        }
    }
    
  • 367. Valid Perfect Square

    Given a positive integer num, write a function which returns True if num is a perfect square else False.

    Follow up: Do not use any built-in library function such as sqrt.

    Example 1:

    Input: num = 16
    Output: true
    

    Example 2:

    Input: num = 14
    Output: false
    

    Constraints:

    • 1 <= num <= 2^31 - 1
    class Solution {
        public boolean isPerfectSquare(int num) {
            if (num == 0 || num == 1) return true;
            int left = 1, right = num;
            while (left <= right) {
                int mid = (right - left) / 2 + left;
                if ((long) mid * mid == num) {
                    return true;
                } else if ((long) mid * mid > num) {
                    right = mid - 1;
                } else {
                    left = mid + 1;
                }
            }
            return right * right == num;
        }
    }
    
  • 74. Search a 2D Matrix

    Write an efficient algorithm that searches for a value in an m x n matrix. This matrix has the following properties:

    • Integers in each row are sorted from left to right.
    • The first integer of each row is greater than the last integer of the previous row.

    Example 1:

    img

    Input: matrix = [[1,3,5,7],[10,11,16,20],[23,30,34,60]], target = 3
    Output: true
    

    Example 2:

    img

    Input: matrix = [[1,3,5,7],[10,11,16,20],[23,30,34,60]], target = 13
    Output: false
    

    Constraints:

    • m == matrix.length
    • n == matrix[i].length
    • 1 <= m, n <= 100
    • -104 <= matrix[i][j], target <= 104
    class Solution {
        public boolean searchMatrix(int[][] matrix, int target) {
            if (matrix.length == 0) return false;
            int n = matrix.length, m = matrix[0].length;
            for (int i = 0, j = m - 1; i < n && j >= 0; ) {
                if (matrix[i][j] == target) {
                    return true;
                } else if (matrix[i][j] < target) {
                    i++;
                } else {
                    j--;
                }
            }
            return false;
        }
    }
    
  • 153. Find Minimum in Rotated Sorted Array

    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.

    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.
    class Solution {
        public int findMin(int[] nums) {
            int left = 0, right = nums.length - 1;
            while (left < right) {
                int mid = (right - left) / 2 + left;
                if (nums[left] <= nums[mid]) { // when length == 1, left == mid
                    if (nums[mid] < nums[right]) {
                        return nums[left];
                    } else {
                        left = mid + 1;
                    }
                } else {
                    right = mid;
                }
            }
            return nums[right];
        }
    }
    
  • Dynamic Programming

    Simplifying a complicated problem by breaking it down into simpler sub-problems (in a recursive manner)

    bottom up

    divide & conquer + optimal substructure

    has status cache

  • Count the paths

    image-20210318104512545

    Recursion: dp[i][j] = dp[i + 1][j] + dp[i][j + 1]

  • 1143. Longest Common Subsequence

    Given two strings text1 and text2, return the length of their longest common subsequence. If there is no common subsequence, return 0.

    A subsequence of a string is a new string generated from the original string with some characters (can be none) deleted without changing the relative order of the remaining characters.

    • For example, "ace" is a subsequence of "abcde".

    A common subsequence of two strings is a subsequence that is common to both strings.

    Example 1:

    Input: text1 = "abcde", text2 = "ace" 
    Output: 3  
    Explanation: The longest common subsequence is "ace" and its length is 3.
    

    Example 2:

    Input: text1 = "abc", text2 = "abc"
    Output: 3
    Explanation: The longest common subsequence is "abc" and its length is 3.
    

    Example 3:

    Input: text1 = "abc", text2 = "def"
    Output: 0
    Explanation: There is no such common subsequence, so the result is 0.
    

    Constraints:

    • 1 <= text1.length, text2.length <= 1000
    • text1 and text2 consist of only lowercase English characters.
    class Solution {
        public int longestCommonSubsequence(String text1, String text2) {
            int n = text1.length(), m = text2.length();
            int[][] dp = new int[n + 1][m + 1];
            for (int i = 1; i < n + 1; i++) {
                for (int j = 1; j < m + 1; j++) {
                    if (text1.charAt(i - 1) == text2.charAt(j - 1)) {
                        dp[i][j] = dp[i - 1][j - 1] + 1;
                    } else {
                        dp[i][j] = Math.max(dp[i][j - 1], dp[i - 1][j]);
                    }
                }
            }
            return dp[n][m];
        }
    }
    
  • 62. Unique Paths

    A robot is located at the top-left corner of a m x n grid (marked 'Start' in the diagram below).

    The robot can only move either down or right at any point in time. The robot is trying to reach the bottom-right corner of the grid (marked 'Finish' in the diagram below).

    How many possible unique paths are there?

    Example 1:

    img

    Input: m = 3, n = 7
    Output: 28
    

    Example 2:

    Input: m = 3, n = 2
    Output: 3
    Explanation:
    From the top-left corner, there are a total of 3 ways to reach the bottom-right corner:
    1. Right -> Down -> Down
    2. Down -> Down -> Right
    3. Down -> Right -> Down
    

    Example 3:

    Input: m = 7, n = 3
    Output: 28
    

    Example 4:

    Input: m = 3, n = 3
    Output: 6
    

    Constraints:

    • 1 <= m, n <= 100
    • It's guaranteed that the answer will be less than or equal to 2 * 109.
    class Solution {
        public int uniquePaths(int m, int n) {
            int[] dp = new int[n];
            Arrays.fill(dp, 1);
            for (int i = 1; i < m; i++) {
                for (int j = 1; j < n; j++) {
                    dp[j] += dp[j - 1];
                }
            }
            return dp[n - 1];
        }
    }
    
  • 63. Unique Paths II

    A robot is located at the top-left corner of a m x n grid (marked 'Start' in the diagram below).

    The robot can only move either down or right at any point in time. The robot is trying to reach the bottom-right corner of the grid (marked 'Finish' in the diagram below).

    Now consider if some obstacles are added to the grids. How many unique paths would there be?

    An obstacle and space is marked as 1 and 0 respectively in the grid.

    Example 1:

    img

    Input: obstacleGrid = [[0,0,0],[0,1,0],[0,0,0]]
    Output: 2
    Explanation: There is one obstacle in the middle of the 3x3 grid above.
    There are two ways to reach the bottom-right corner:
    1. Right -> Right -> Down -> Down
    2. Down -> Down -> Right -> Right
    

    Example 2:

    img

    Input: obstacleGrid = [[0,1],[0,0]]
    Output: 1
    

    Constraints:

    • m == obstacleGrid.length
    • n == obstacleGrid[i].length
    • 1 <= m, n <= 100
    • obstacleGrid[i][j] is 0 or 1.
    class Solution {
        public int uniquePathsWithObstacles(int[][] obstacleGrid) {
            obstacleGrid[0][0] = obstacleGrid[0][0] == 1 ? 0 : 1;
            for (int i = 1; i < obstacleGrid.length; i++) {
                obstacleGrid[i][0] = obstacleGrid[i][0] == 1 ? 0 : obstacleGrid[i - 1][0];
            }
            for (int j = 1; j < obstacleGrid[0].length; j++) {
                obstacleGrid[0][j] = obstacleGrid[0][j] == 1 ? 0 : obstacleGrid[0][j - 1];
            }
            for (int i = 1; i < obstacleGrid.length; i++) {
                for (int j = 1; j < obstacleGrid[0].length; j++) {
                    obstacleGrid[i][j] = obstacleGrid[i][j] == 1 ? 0 :obstacleGrid[i-1][j] + obstacleGrid[i][j-1];
                }
            }
            return obstacleGrid[obstacleGrid.length - 1][obstacleGrid[0].length - 1];
        }
    }
    
  • 53. Maximum Subarray

    Given an integer array nums, find the contiguous subarray (containing at least one number) which has the largest sum and return its sum.

    Example 1:

    Input: nums = [-2,1,-3,4,-1,2,1,-5,4]
    Output: 6
    Explanation: [4,-1,2,1] has the largest sum = 6.
    

    Example 2:

    Input: nums = [1]
    Output: 1
    

    Example 3:

    Input: nums = [5,4,-1,7,8]
    Output: 23
    

    Constraints:

    • 1 <= nums.length <= 3 * 104
    • -105 <= nums[i] <= 105

    Follow up: If you have figured out the O(n) solution, try coding another solution using the divide and conquer approach, which is more subtle.

    class Solution {
        public int maxSubArray(int[] nums) {
            int max = nums[0];
            for (int i = 1; i < nums.length; i++) {
                nums[i] = Math.max(nums[i] + nums[i-1], nums[i]);
                max = Math.max(max, nums[i]);
            }
            return max;
        }
    }
    
posted @ 2021-03-18 16:20  鹏懿如斯  阅读(33)  评论(0编辑  收藏  举报