Copyright © 直通硅谷
http://www.zhitongguigu.com/
Copyright © 直通硅谷
http://www.zhitongguigu.com/
Copyright © 直通硅谷
http://www.zhitongguigu.com/
Copyright © 直通硅谷
http://www.zhitongguigu.com/
Copyright © 直通硅谷
http://www.zhitongguigu.com/
It means:
1. If it cannot be solved by recursion, do not bother finding DP.
2. not all the recursion can use DP to solve. E.G. merge sort
Copyright © 直通硅谷
http://www.zhitongguigu.com/
int A() {
...
...
A;
}
int Factorial(int n) {
if(n == 1) return 1;
return n * Factorial(n-1);
}
int Factorial(int n) {
int sum = 1;
for(int i = 1; i <= n; i ++) {
sum = sum * i;
}
return sum;
}
Copyright © 直通硅谷
http://www.zhitongguigu.com/
int Fabonacci(int n) {
if(n == 0 || n == 1) return 1;
return F(n-1) + F(n-2);
}
Copyright © 直通硅谷
http://www.zhitongguigu.com/
Copyright © 直通硅谷
http://www.zhitongguigu.com/
F(6)
F(5)
F(4)
F(4)
F(3)
F(3)
F(3)
F(2)
F(2)
F(1)
F(1)
F(1)
F(0)
F(1)
F(0)
F(1)
F(0)
F(1)
F(0)
F(2)
F(1)
F(1)
F(0)
F(2)
F(2)
int Fabonacci(int n) {
if(n <= 1) return 1;
int[] result = new int[n + 1];
result[0] = 1;
result[1] = 1;
for(int i = 2; i < n + 1; i ++) {
result[i] = result[i-1] + result[i-2];
}
return result[n];
}
We use an Array to store the temp result
What is the optimal sub-structure?
Copyright © 直通硅谷
http://www.zhitongguigu.com/
Copyright © 直通硅谷
http://www.zhitongguigu.com/
Copyright © 直通硅谷
http://www.zhitongguigu.com/
int uniquePaths(int m, int n) {
if(m==1 || n==1) return 1;
return uniquePaths(m-1, n) + uniquePaths(m, n-1);
}
Where is the redundancy?
What is the optimal sub-structure?
Copyright © 直通硅谷
http://www.zhitongguigu.com/
Optimal Sub-structure
a(i,j) = a(i-1,j) + a(i, j-1)
Copyright © 直通硅谷
http://www.zhitongguigu.com/
public int uniquePaths(int m, int n) {
int[][] a = new int[m][n];
for (int i = 0; i < m; i++) {
a[i][0] = 1;
}
for (int i = 0; i < n; i++) {
a[0][i] = 1;
}
for (int i = 1; i < m; i++) {
for (int j = 1; j < n; j++) {
a[i][j] = a[i-1][j] + a[i][j-1];
}
}
return a[m-1][n-1];
}
Copyright © 直通硅谷
http://www.zhitongguigu.com/
1 | 3 | 4 | 2 |
---|---|---|---|
3 | 5 | 2 | 3 |
2 | 1 | 2 | 3 |
2 | 2 | 4 | 2 |
Best optimal sub-structure?
Copyright © 直通硅谷
http://www.zhitongguigu.com/
1 | 3 | 4 | 2 |
---|---|---|---|
3 | 5 | 2 | 3 |
2 | 1 | 2 | 3 |
2 | 2 | 4 | 2 |
PathSum(m,n) = MIN(PathSum(m,n-1),PathSum(m-1,n)) + matrix(m,n)
Copyright © 直通硅谷
http://www.zhitongguigu.com/
public int minPathSum(int[][] grid) {
if(grid == null || grid.length==0)
return 0;
int m = grid.length;
int n = grid[0].length;
int[][] dp = new int[m][n];
dp[0][0] = grid[0][0];
for(int i=1; i<n; i++){
dp[0][i] = dp[0][i-1] + grid[0][i];
}
for(int j=1; j<m; j++){
dp[j][0] = dp[j-1][0] + grid[j][0];
}
for(int i=1; i<m; i++){
for(int j=1; j<n; j++){
if(dp[i-1][j] > dp[i][j-1]){
dp[i][j] = dp[i][j-1] + grid[i][j];
}else{
dp[i][j] = dp[i-1][j] + grid[i][j];
}
}
}
return dp[m-1][n-1];
}
Copyright © 直通硅谷
http://www.zhitongguigu.com/
What is time complexity?
Can we do better?
What is space complexity?
Can we do better?
Any improvement?
Copyright © 直通硅谷
http://www.zhitongguigu.com/
Any improvement?
We can use less space to get the same result without hurting time complexity
Copyright © 直通硅谷
http://www.zhitongguigu.com/
public static int minPathSum(int[][] grid) {
if(grid == null || grid.length==0)
return 0;
int m = grid.length;
int n = grid[0].length;
int[] newline = new int[n];
int[] oldline = new int[n];
oldline[0] = grid[0][0];
for(int i=1; i<n; i++){
oldline[i] = oldline[i-1] + grid[0][i];
}
for(int i=1; i<m; i++){
newline[0] = grid[i][0] + oldline[0];
for(int j=1; j<n; j++){
if(oldline[j] > newline[j-1]){
newline[j] = newline[j-1] + grid[i][j];
}else{
newline[j] = oldline[j] + grid[i][j];
}
}
oldline = newline;
}
return newline[n-1];
}
Given a knapsack which can hold w pounds of items, and a set of items with weight w1, w2, ... wn. Each item has its value s1,s2,...,sn. Try to select the items that could put in knapsack and contains most value.
What is the optimal sub-structure?
Copyright © 直通硅谷
http://www.zhitongguigu.com/
Copyright © 直通硅谷
http://www.zhitongguigu.com/
w[i][j]: for the previous total i items, the max value it can have for capacity j
Which two we need to use to compare?
w[i][j]: for the previous total i items, the max value it can have for capacity j
Copyright © 直通硅谷
http://www.zhitongguigu.com/
When you iterate i, and j, you need to try:
0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | |
---|---|---|---|---|---|---|---|---|
0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
1 | 0 | 3 | 3 | 3 | 3 | 3 | 3 | 3 |
2 | 0 | 3 | 3 | 8 | 11 | 11 | 11 | 11 |
3 | 0 | 3 | 3 | 8 | 11 | 11 | 11 | 12 |
4 | 0 | 3 | 3 | 8 | 11 | 11 | 11 | 12 |
w[i][j]: for the previous total i items, the max value it can have for capacity j
Example: weights{1,3,4,5} values{3,8,4,7}
Copyright © 直通硅谷
http://www.zhitongguigu.com/
public int knapsack(int capacity, int[] weights, int[] values) {
int length = weights.length;
if (capacity == 0 || length == 0)
return 0;
int[][] w = new int[length + 1][capacity + 1];
for (int i = 1; i <= length; i++) {
int index = i - 1;
for (int j = 1; j <= capacity; j++) {
if (j < weights[index]) {
w[i][j] = w[i - 1][j];
} else if (w[i - 1][j - weights[index]] + values[index] > w[i - 1][j]) {
w[i][j] = w[i - 1][j - weights[index]] + values[index];
} else {
w[i][j] = w[i - 1][j];
}
}
}
return w[length][capacity];
}
Copyright © 直通硅谷
http://www.zhitongguigu.com/
3, 1, 4, 5, 7, 6, 8, 2
1, 4, 5, 6, 8 (Or 1, 4, 5, 7, 8)
Copyright © 直通硅谷
http://www.zhitongguigu.com/
What is the optimal sub-structure?
Copyright © 直通硅谷
http://www.zhitongguigu.com/
Copyright © 直通硅谷
http://www.zhitongguigu.com/
We store lis[i] for the LIS by i?
We store lis[i] for the LIS using sequence[i]
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/
Copyright © 直通硅谷
http://www.zhitongguigu.com/
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/
Copyright © 直通硅谷
http://www.zhitongguigu.com/
Copyright © 直通硅谷
http://www.zhitongguigu.com/
Example: abcfbc abfcab
return 4 (abcb)
Copyright © 直通硅谷
http://www.zhitongguigu.com/
Example: abcfbc abfcab
return 4 (abcb)
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/
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])?
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))
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];
}
Copyright © 直通硅谷
http://www.zhitongguigu.com/
Matrix A m*n
Matrix B n*p
C = A * B will need m*n*p times multiplication
A 100 * 10, B 10 * 100, C 100 * 5
D = A * B * C
If we do (AB)C, need 100*10*100 + 100*100*5 = 150000 times
If we do A(BC), need 100*10*5 + 10*100*5 = 10000 times
Copyright © 直通硅谷
http://www.zhitongguigu.com/
Give A0,A1,.....,An-1 n different matrixs
Find minimum of multiplication it needs to get the result
input: An array P with n+1 numbers
A0 = p0*p1, An-1 = Pn-1*Pn
Copyright © 直通硅谷
http://www.zhitongguigu.com/
What is the optimal sub-structure?
For the result A1*...*An, if we split from Ak
It becomes (A1*...Ak)(Ak+1*...An)
T(1,n) = T(1,k) + T(k+1,n) + p0*pk*pn
So if T(1,n) is the best, T(1,k) and T(k+1,n) must be the best
Copyright © 直通硅谷
http://www.zhitongguigu.com/
So how do we get the T(1,k)?
We need to start from the chain with length 1 to finally get to length n
public static int MatrixChain(int[] p)
{
int n = p.length;
n --;
int[][] m = new int[n][n];
for(int i = 0; i < n; i++)
m[i][i] = 0;
for(int r = 2; r <= n; r++)
{
for(int i = 0; i < n - r + 1; i ++)
{
int j = i + r - 1;
m[i][j] = m[i + 1][j] + p[i] * p[i+1] * p[j + 1];
for(int k = i + 1; k < j; k++)
{
int t = m[i][k] + m[k + 1][j] + p[i] * p[k+1] * p[j+1];
if( t < m[i][j])
m[i][j] = t;
}
}
}
return m[0][n-1];
}
Copyright © 直通硅谷
http://www.zhitongguigu.com/
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/
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]?
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/
Unique Path II
Climbing Stairs
Maximum Subarray
Copyright © 直通硅谷
http://www.zhitongguigu.com/
Longest Valid Parentheses
Triangle
Best Time to Buy and Sell Stock
Distinct Subsequences