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 ofx
.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 indexk
(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 index3
and become[4,5,6,7,0,1,2]
.Given the array
nums
after the rotation and an integertarget
, return the index oftarget
if it is innums
, or-1
if it is not innums
.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:
Input: matrix = [[1,3,5,7],[10,11,16,20],[23,30,34,60]], target = 3 Output: true
Example 2:
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 between1
andn
times. For example, the arraynums = [0,1,2,4,5,6,7]
might become:[4,5,6,7,0,1,2]
if it was rotated4
times.[0,1,2,4,5,6,7]
if it was rotated7
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 between1
andn
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
Recursion:
dp[i][j] = dp[i + 1][j] + dp[i][j + 1]
-
1143. Longest Common Subsequence
Given two strings
text1
andtext2
, return the length of their longest common subsequence. If there is no common subsequence, return0
.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
andtext2
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]; } }
- For example,
-
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:
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
and0
respectively in the grid.Example 1:
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:
Input: obstacleGrid = [[0,1],[0,0]] Output: 1
Constraints:
m == obstacleGrid.length
n == obstacleGrid[i].length
1 <= m, n <= 100
obstacleGrid[i][j]
is0
or1
.
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; } }