Dynamic Programming
Copyright © 直通硅谷
http://www.zhitongguigu.com/
Core of DP
-
mathematical induction
DP VS Recursion
-
recursion : big -> small
-
DP: small -> big
Longest increasing Subarray
Given an array of Integers A , find the length of Longest sub-array whose elements are in Non-Decreasing Order.
{9,7,2,4,1,5,8,9,5}
DP principle
- Base case: M[0] = 1;
- Induction rule: M[i] represents the length of the longest increasing subarray from A[0] to A[i].
- M[i] = M[i-1] + 1 if(A[i] > A[i-1])
- M[i] = 1;
Code
Public static int longestLength(int[] A){
int length = 1;
int maxLength = 0;
for(int i = 1; i < A.length; i++){
if(A[i] > A[i - 1]){
length++;
if(length > maxLength){
maxLength = length;
}
}
else{
length = 1;
}
}
return maxLength;
}
Longest Increasing Subsequence
3, 1, 4, 5, 7, 6, 8, 2
1, 4, 5, 6, 8 (Or 1, 4, 5, 7, 8)
Copyright © 直通硅谷
http://www.zhitongguigu.com/
Longest Increasing Subsequence
What is the optimal sub-structure?
Copyright © 直通硅谷
http://www.zhitongguigu.com/
Longest Increasing Subsequence
Copyright © 直通硅谷
http://www.zhitongguigu.com/
We store lis[i] for the LIS by i?
We store lis[i] for the LIS using sequence[i]
Longest Increasing Subsequence
public int longestIncreasingSubsequence(int[] nums) {
if(nums.length == 0){
return 0;
}
int[] lis = new int[nums.length];
int max = 0;
for (int i = 0; i < nums.length; i++){
int localMax = 0;
for (int j = 0; j < i; j++){
if (lis[j] > localMax && nums[j] <= nums[i]){
localMax = lis[j];
}
}
lis[i] = localMax + 1;
max = Math.max(max, lis[i]);
}
return max;
}
Copyright © 直通硅谷
http://www.zhitongguigu.com/
What is the Time Complexity?
What is the Space Complexity?
Can we do better?
Copyright © 直通硅谷
http://www.zhitongguigu.com/
Patient Sort
Copyright © 直通硅谷
http://www.zhitongguigu.com/
1, 3, 5, 2, 8, 4, 7, 6, 0, 9, 10
1 -> 0 |
1,3 -> 1,2 |
1,3,5 -> 1,3,4 |
1,3,5,8 -> 1,3,5,7 -> 1,3,5,6 |
1,3,5,6,9 |
1,3,5,6,9,10 |
public int longestIncreasingSubsequence(int[] nums) {
if(nums.length == 0){
return 0;
}
int len = 0;
int[] tails = new int[nums.length];
tails[0] = nums[0];
for(int i = 1; i < nums.length; i++){
if(nums[i] < tails[0]){
tails[0] = nums[i];
} else if (nums[i] >= tails[len]){
tails[++len] = nums[i];
} else {
tails[binarySearch(tails, 0, len, nums[i])] = nums[i];
}
}
return len + 1;
}
private int binarySearch(int[] tails, int min, int max, int target){
while(min < max){
int mid = min + (max - min) / 2;
if(tails[mid] == target){
return mid;
}
else if(tails[mid] < target){
min = mid + 1;
}
else max = mid;
}
return min;
}
Copyright © 直通硅谷
http://www.zhitongguigu.com/
1d DP solve pattern
-
1d original data
- if each smallest element is identical/similar
Linear scan and look back to the privous elements
Example
Longest increasing subarray
longest increasing subsequence
cut rope
Jump Game
Given an array of non-negative integers, you are initially positioned at the first index of the array.
Each element in the array represents your maximum jump length at that position.
Determine if you are able to reach the last index.
For example:
A = [2,3,1,1,4], return true.
A = [3,2,1,0,4], return false.
Index [0,1,2,3,4]
A = [2,3,1,1,4],
start goal
M = [x,x,x,x,T]
i j <--- scan direction
i + A[i]
Index [0,1,2,3,4]
A = [2,3,1,1,4],
start goal
M = [x,x,x,x,T]
i j <--- scan direction
i + A[i]
Base case: M[n-1] = true
Induction rule:
M[i] =
case 1: if(i + A[i] >= n-1) M[i] = true;
case 2: if(M[j] == true && j < i + A[i]) M[i] = true;
Index [0,1,2,3,4]
A = [2,3,1,1,4],
start goal
M = [F,F,F,F,T]
i j <--- scan direction
i + A[i]
Base case: M[n-1] = true
Induction rule:
M[i] =
case 1: if(i + A[i] >= n-1) M[i] = true;
case 2: if(M[j] == true && j < i + A[i]) M[i] = true;
//DP
bool canJump1(vector<int>& nums) {
int n = (int)nums.size();
vector<bool> dp(n,false);
dp[n-1] = true;
for(int i= n-2;i>=0;i--){
dp[i] = false;
for(int j=1;j<nums[i];j++){
if(i+j>=n-1 || dp[i+j]){
dp[i] = true;
break;
}
}
}
return dp[0];
}
//greedy
bool canJump(vector<int>& nums) {
int n = (int)nums.size();
int res = nums[0];
for(int i = 1; i < n; i++){
--res;
if(res<0) return false;
res =max(res, nums[i]);
}
return true;
}
Jump Game 2
same setup as Jump Game,
Return the minimum number of jumps needed to reach the end.
same setup as Jump Game,
Return the minimum number of jumps needed to reach the end.
1, base Case: M[n - 1] = 0
2 Induction Rule: M[i] ?????
same setup as Jump Game,
Return the minimum number of jumps needed to reach the end.
1, base Case: M[n - 1] = 0
2 Induction Rule: M[i] ?????
M[i] represent the least number of jumps to reach M[n - 1]
M[i] = 1 + min(M[j])
* j is all the elements that can be reached by 1 jump from i;
public static int minJumps(int A[]) {
int n = A.length;
int[] jumps = new int[n];
int min = Integer.MAX_VALUE;
jump[n-1] = 0;
for(int i = n-2; i >= 0; i--){
if(A[i] == 0){
jumps[i] = Integer.MAX_VALUE;
}
else if(i + A[i] >= n - 1){ // jump over border
jumps[i] = 1;
}
else{
min = Integer.MAX_VALUE;
for(int j = i + 1; j < n && j <= A[i] + i; j++){
if(min > jumps[j]){
min = jumps[j];
}
}
if(min != Integer.MAX_VALUE) {
jumps[i] = min + 1;
}
else{
jumps[i] = Integer.MAX_VALUE;
}
}
}
return jumps[0];
}
Longest Common Sequence
Copyright © 直通硅谷
http://www.zhitongguigu.com/
Longest Common Sequence
Copyright © 直通硅谷
http://www.zhitongguigu.com/
Example: abcfbc abfcab
return 4 (abcb)
Longest Common Sequence
Copyright © 直通硅谷
http://www.zhitongguigu.com/
Example: abcfbc abfcab
return 4 (abcb)
Longest Common Sequence
What is the optimal sub-structure?
maxCommon(i,j): longest common string for String A(0,i) and String B(0,j)
We finally need to get maxCommon(stringA.length, stringB.length)
Copyright © 直通硅谷
http://www.zhitongguigu.com/
Longest Common Sequence
Copyright © 直通硅谷
http://www.zhitongguigu.com/
What is the relationship between maxCommon(i,j) and maxCommon(i-1,j-1)?
If(A[i-1] = B[j-1]) ?
If(A[i-1] != B[j-1])?
Longest Common Sequence
Copyright © 直通硅谷
http://www.zhitongguigu.com/
What is the relationship between maxCommon(i,j) and maxCommon(i-1,j-1)?
If(A[i-1] = B[j-1]) ?
If(A[i-1] != B[j-1])?
maxCommon(i,j) = maxCommon(i-1,j-1) + 1
maxCommon(i,j) = max(maxCommon(i-1,j), maxCommon(i,j-1))
Longest Common Sequence
Copyright © 直通硅谷
http://www.zhitongguigu.com/
public static int longestCommonString(String a, String b) {
int m = a.length();
int n = b.length();
int[][] maxCommon = new int[m+1][n+1];
for(int i = 0; i <= m; i ++) {
maxCommon[i][0] = 0;
}
for(int j = 0; j <= n; j ++) {
maxCommon[0][j] = 0;
}
for(int i = 1; i <= m; i ++) {
for(int j = 1; j <= n; j ++) {
if(a.charAt(i-1) == b.charAt(j-1)) {
maxCommon[i][j] = maxCommon[i-1][j-1] + 1;
}
else {
maxCommon[i][j] = Math.max(maxCommon[i][j-1], maxCommon[i-1][j]);
}
}
}
return maxCommon[m][n];
}
Edit Distance
Copyright © 直通硅谷
http://www.zhitongguigu.com/
Replace: abc -> abd
Remove: abc -> ab
Add: abc -> abcd
How many steps you need from String A to B?
e.g. abca -> eeba 3 steps
abcdf -> eecf 3 steps
Copyright © 直通硅谷
http://www.zhitongguigu.com/
Example:
s1 = "asdf"
s2 = "hjkl"
s1 = c1 and s1r <- rest of s1
s2 = c2 and s2r <- rest of s2
1, replace: a -> h
h sdf
h jkl
editDistance(sdf, jkl) + 1
Copyright © 直通硅谷
http://www.zhitongguigu.com/
Example:
s1 = "asdf"
s2 = "hjkl"
s1 = c1 and s1r <- rest of s1
s2 = c2 and s2r <- rest of s2
2, delete: a
a sdf
hjkl
editDistance(sdf, hjkl) + 1
Copyright © 直通硅谷
http://www.zhitongguigu.com/
Example:
s1 = "asdf"
s2 = "hjkl"
s1 = c1 and s1r <- rest of s1
s2 = c2 and s2r <- rest of s2
3, insert: h
h asdf
h jkl
editDistance(asdf, jkl) + 1
x | x | x | x | x | x | x |
---|---|---|---|---|---|---|
x | x | x | x | x | x | x |
x | x | x | x | x | x | x |
x | x | x | x | x | x | x |
x | x | x | x | x | x | x |
x | x | x | x | x | x | x |
x | x | x | x | x | x | x |
M[i][j]
Edit Distance
Copyright © 直通硅谷
http://www.zhitongguigu.com/
What is the optimal sub-structure?
what is the connection between EDIT[i,j]
and EDIT[i-1,j], EDIT[i,j-1] and EDIT[i-1,j-1]?
Copyright © 直通硅谷
http://www.zhitongguigu.com/
what is the connection between EDIT[i,j]
and EDIT[i-1,j], EDIT[i,j-1] and EDIT[i-1,j-1]?
Edit Distance
Copyright © 直通硅谷
http://www.zhitongguigu.com/
what is the connection between EDIT[i,j]
and EDIT[i-1,j], EDIT[i,j-1] and EDIT[i-1,j-1]?
if(A[i-1]!=B[j-1])?
if(A[i-1]=B[j-1])?
Copyright © 直通硅谷
http://www.zhitongguigu.com/
public static int editDistance(String a, String b) {
int m = a.length() + 1;
int n = b.length() + 1;
int[][] f = new int[m][n];
for(int i = 0; i < m; i ++) {
f[i][0] = i;
}
for(int j = 0; j < n; j ++) {
f[0][j] = j;
}
for(int i = 1; i < m; i ++) {
for(int j = 1; j < n; j ++) {
if(a.charAt(i-1) == b.charAt(j-1)) {
f[i][j] = f[i-1][j-1];
}
else {
f[i][j] = f[i-1][j-1] + 1;
}
f[i][j] = Math.min(f[i][j], Math.min(f[i-1][j]+1, f[i][j-1]+1));
}
}
return f[m-1][n-1];
}
Copyright © 直通硅谷
http://www.zhitongguigu.com/
Homework
Unique Path II
Climbing Stairs
Maximum Subarray
edit Distance
Longest common Subsequence
Copyright © 直通硅谷
http://www.zhitongguigu.com/
Homework (Optional)
Longest Valid Parentheses
Triangle
Best Time to Buy and Sell Stock
Distinct Subsequences
[GoValley-201612] Dynamic Programming 2
By govalley201612
[GoValley-201612] Dynamic Programming 2
- 732