LeetCode 之动态规划
2014-03-07 12:27
302 查看
1. 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 =
A =
一维动态规划,从左到右扫描
方法二:
直接实现,len记录当前Jump距离,大于等于n-1时返回true
2 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?
![](http://4.bp.blogspot.com/_UElib2WLeDE/TNJf8VtC2VI/AAAAAAAACXU/UyUa-9LKp4E/s400/robot_maze.png)
Above is a 3 x 7 grid. How many possible unique paths are there?
Note: m and n will be at most 100.
一维DP。 Step[i][j] = Step[i-1][j] + Step[i][j-1];
3.Unique Paths II
Follow up for "Unique Paths":
Now consider if some obstacles are added to the grids. How many unique paths would there be?
An obstacle and empty space is marked as
in the grid.
For example,
There is one obstacle in the middle of a 3x3 grid as illustrated below.
The total number of unique paths is
Note: m and n will be at most 100.
和Unique Path一样的转移方程:
Step[i][j] = Step[i-1][j] + Step[i][j-1] if Array[i][j] ==0
or = 0 if Array[i][j] =1
4. Edit Distance
Given two words word1 and word2, find the minimum number of steps required to convert word1 to word2. (each operation is counted as 1 step.)
You have the following 3 operations permitted on a word:
a) Insert a character
b) Delete a character
c) Replace a character
利用动态规划的思路。dp[i][j]表示word1的前i个字母与word2的前j个字母的编辑距离。
1)若word1[i+1]==word2[j+1] dp[i+1][j+1] = dp[i][j];否则,dp[i+1][j+1] = dp[i][j] + 1。(利用替换原则)
2)dp[i+1][j+1]还可以取dp[i][j+1]与dp[i+1][j]中的较小值。(利用删除添加原则)
总结的递推公式就是:
dp[j][i] = min(distance[j][i - 1] + insert, distance[j - 1][i] + delete, distance[j - 1][i - 1] + replace);
其中replace需要判断一下
实际dp[i+1][j+1]应当取上述两种情况的较小值。
5.Best Time to Buy and Sell Stock
Say you have an array for which the ith element is the price of a given stock on day i.
If you were only permitted to complete at most one transaction (ie, buy one and sell one share of the stock), design an algorithm to find the maximum profit.
从左到右扫面,记录当前最低股票值,同时比较股票差值,并记录
6.Best Time to Buy and Sell Stock II
Say you have an array for which the ith element is the price of a given stock on day i.
Design an algorithm to find the maximum profit. You may complete as many transactions as you like (ie, buy one and sell one share of the stock multiple times). However, you may not engage in multiple transactions at the same time (ie, you must sell the stock
before you buy again).
从左到右扫面,记录所有差值为正的数据,之和为最大盈利
7. Best Time to Buy and Sell stock III
Say you have an array for which the ith element is the price of a given stock on day i.
Design an algorithm to find the maximum profit. You may complete at most two transactions.
Note:
You may not engage in multiple transactions at the same time (ie, you must sell the stock before you buy again).
MaxPro[0,n] = max(MaxPro[0,i]+MaxPro[i+1,n]);
最多只能交易两次。
两种情况,
1.从左到右只有一个股票上升的区间
2. 从左到右有多个股票上升区间,MaxPro[0,n] = max(MaxPro[0,i]+MaxPro[i+1,n]);
两个数组,一个记录从左到右扫描的每个位置的盈利值,一个记录从右到左扫描的每个位置的盈利值。
最后通过取maxFromLeft[i] maxFromRight[i+1]实现MaxPro[0,n] = max(MaxPro[0,i]+MaxPro[i+1,n]);
8. Restore IP address
Given a string containing only digits, restore it by returning all possible valid IP address combinations.
For example:
Given
return
This problem can be viewed as a DP problem. There needed 3 dots to divide the string, and make sure the IP address is
valid: less than or equal to 255, greater or equal to 0, and note that, "0X" or "00X" is not valid.
For the DP, the length of each part is from 1 to 3. We use a vector<string> to store each part, and cut the string every
time. Details see the code.
9.Climbing a stair
You are climbing a stair case. It takes n steps to reach to the top.
Each time you can either climb 1 or 2 steps. In how many distinct ways can you climb to the top?
DP. The transition function should be:
f(n) = f(n-1) + f(n-2) n>2;
or = 1 n=1
or = 2 n=2
10. Decode Ways
A message containing letters from
the following mapping:
Given an encoded message containing digits, determine the total number of ways to decode it.
For example,
Given encoded message
2) or
The number of ways decoding
Similar as "[LeetCode] Climbing Stairs". DP. Just add some logic to compare character.
Transformation function as:
Count[i] = Count[i-1] if S[i-1] is a valid char
or = Count[i-1]+ Count[i-2] if S[i-1] and S[i-2] together is still a valid char.
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.
一维动态规划,从左到右扫描
bool canJump1(int A[], int n){ int maxCover = 0; for(int start = 0; start<=maxCover && start<n;start++){ if(A[start]+start > maxCover) maxCover = A[start]+start; if(maxCover >=n-1) return true; } return false; }
方法二:
直接实现,len记录当前Jump距离,大于等于n-1时返回true
bool canJump(int A[], int n) { int len = 0; int *p = A; while(len<n){ int dis = *p; if(dis == 0 && len < n-1) return false; len+=dis; if(len == n-1 || (len== n && dis == len)) return true; p += dis; } return true; }
2 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?
![](http://4.bp.blogspot.com/_UElib2WLeDE/TNJf8VtC2VI/AAAAAAAACXU/UyUa-9LKp4E/s400/robot_maze.png)
Above is a 3 x 7 grid. How many possible unique paths are there?
Note: m and n will be at most 100.
一维DP。 Step[i][j] = Step[i-1][j] + Step[i][j-1];
int uniquePaths(int m, int n) { vector <int> maxpath(n,0); maxpath[0] = 1; for(int i=0; i<m;i++){ for(int j=1; j<n;j++){ maxpath[j] = maxpath[j-1]+maxpath[j]; } } return maxpath[n-1]; }
3.Unique Paths II
Follow up for "Unique Paths":
Now consider if some obstacles are added to the grids. How many unique paths would there be?
An obstacle and empty space is marked as
1and
0respectively
in the grid.
For example,
There is one obstacle in the middle of a 3x3 grid as illustrated below.
[ [0,0,0], [0,1,0], [0,0,0] ]
The total number of unique paths is
2.
Note: m and n will be at most 100.
和Unique Path一样的转移方程:
Step[i][j] = Step[i-1][j] + Step[i][j-1] if Array[i][j] ==0
or = 0 if Array[i][j] =1
int uniquePathsWithObstacles(vector<vector<int> > &obstacleGrid) { int m = obstacleGrid.size(); if(m==0) return 0; int n = obstacleGrid[0].size(); if(obstacleGrid[0][0] == 1) return 0; vector<int> maxpath(n,0); maxpath[0] = 1; for(int i=0; i< m; i++){ for(int j=0;j<n;j++){ if(obstacleGrid[i][j] == 1) maxpath[j] = 0; else if(j>0) maxpath[j] = maxpath[j]+maxpath[j-1]; } } return maxpath[n-1]; }
4. Edit Distance
Given two words word1 and word2, find the minimum number of steps required to convert word1 to word2. (each operation is counted as 1 step.)
You have the following 3 operations permitted on a word:
a) Insert a character
b) Delete a character
c) Replace a character
利用动态规划的思路。dp[i][j]表示word1的前i个字母与word2的前j个字母的编辑距离。
1)若word1[i+1]==word2[j+1] dp[i+1][j+1] = dp[i][j];否则,dp[i+1][j+1] = dp[i][j] + 1。(利用替换原则)
2)dp[i+1][j+1]还可以取dp[i][j+1]与dp[i+1][j]中的较小值。(利用删除添加原则)
总结的递推公式就是:
dp[j][i] = min(distance[j][i - 1] + insert, distance[j - 1][i] + delete, distance[j - 1][i - 1] + replace);
其中replace需要判断一下
实际dp[i+1][j+1]应当取上述两种情况的较小值。
int minDistance(string word1, string word2) { int s1 = word1.size(); int s2 = word2.size(); if(s1 == 0) return s2; if(s2 == 0) return s1; vector<int> *dp = new vector<int>[s2+1]; for(int i=0;i<=s1;i++) dp[0].push_back(i); for(int i=0;i<=s2;i++) dp[i].push_back(i); for(int i=1;i<=s2;i++){ for(int j=1;j<=s1;j++){ int n1 = word2[i-1]!=word1[j-1]?(dp[i-1][j-1]+1):dp[i-1][j-1]; int n2 = dp[i-1][j]<dp[i][j-1]?(dp[i-1][j]+1):(dp[i][j-1]+1); dp[i].push_back(n1<n2? n1:n2); } } return dp[s2][s1]; }
5.Best Time to Buy and Sell Stock
Say you have an array for which the ith element is the price of a given stock on day i.
If you were only permitted to complete at most one transaction (ie, buy one and sell one share of the stock), design an algorithm to find the maximum profit.
从左到右扫面,记录当前最低股票值,同时比较股票差值,并记录
int maxProfit(vector<int> &prices) { int max=0, minV = INT_MAX; int diff; for(int i=0; i<prices.size();i++){ if(prices[i]<minV) minV = prices[i]; diff = prices[i]-minV; if(diff > max) max = diff; } return max; }
6.Best Time to Buy and Sell Stock II
Say you have an array for which the ith element is the price of a given stock on day i.
Design an algorithm to find the maximum profit. You may complete as many transactions as you like (ie, buy one and sell one share of the stock multiple times). However, you may not engage in multiple transactions at the same time (ie, you must sell the stock
before you buy again).
从左到右扫面,记录所有差值为正的数据,之和为最大盈利
int maxProfit2(vector<int> &prices){ int sum = 0; for(int i=1;i<prices.size();i++){ if(prices[i]-prices[i-1] > 0) sum+= prices[i]-prices[i-1]; } return sum; }
7. Best Time to Buy and Sell stock III
Say you have an array for which the ith element is the price of a given stock on day i.
Design an algorithm to find the maximum profit. You may complete at most two transactions.
Note:
You may not engage in multiple transactions at the same time (ie, you must sell the stock before you buy again).
MaxPro[0,n] = max(MaxPro[0,i]+MaxPro[i+1,n]);
最多只能交易两次。
两种情况,
1.从左到右只有一个股票上升的区间
2. 从左到右有多个股票上升区间,MaxPro[0,n] = max(MaxPro[0,i]+MaxPro[i+1,n]);
两个数组,一个记录从左到右扫描的每个位置的盈利值,一个记录从右到左扫描的每个位置的盈利值。
最后通过取maxFromLeft[i] maxFromRight[i+1]实现MaxPro[0,n] = max(MaxPro[0,i]+MaxPro[i+1,n]);
int maxProfit(vector<int> &prices){ if(prices.size()<=1) return 0; if(prices.size()==2) return prices[1]>prices[0]?prices[1]-prices[0]:0; vector<int> maxFromLeft(prices.size(),0); vector<int> maxFromRight(prices.size(),0); int minL = INT_MAX, max=INT_MIN, diff; for(int i=0;i<prices.size();i++){ if(prices[i]<minL) minL = prices[i]; diff = prices[i]- minL; if(diff >max) max = diff; maxFromLeft[i] = max; } int maxR = INT_MIN; max = INT_MIN; for(int i=prices.size()-1;i>=0;i--){ if(prices[i]>maxR) maxR = prices[i]; diff = maxR - prices[i]; if(diff > max) max = diff; maxFromRight[i] = max; } max = INT_MIN; for(int i=0;i<prices.size()-1;i++){ int diff = maxFromLeft[i]+maxFromRight[i+1]; if(diff > max) max = diff; } if(max < maxFromRight[0]) max = maxFromRight[0]; return max; }
8. Restore IP address
Given a string containing only digits, restore it by returning all possible valid IP address combinations.
For example:
Given
"25525511135",
return
["255.255.11.135", "255.255.111.35"]. (Order does not matter)
This problem can be viewed as a DP problem. There needed 3 dots to divide the string, and make sure the IP address is
valid: less than or equal to 255, greater or equal to 0, and note that, "0X" or "00X" is not valid.
For the DP, the length of each part is from 1 to 3. We use a vector<string> to store each part, and cut the string every
time. Details see the code.
/* s -- string, input start -- startindex, start from which index in s step -- step current step index, start from 0, valid value1-4,4 means the end ip -- intermediate, split result in current spliting process result -- save all possible ip address */ void dfsIp(string s, size_t start, size_t step, string ip, vector<string> &result){ if(start == s.size() && step == 4){//find a possible result ip.resize(ip.size()-1); result.push_back(ip); return; } //since each part of IP address is in 0..255,the leagth of each // part is less than 3 and more than 0 if(s.size()-start > (4-step)*3) return; if(s.size()-start < (4-step)) return; int num=0; for(size_t i=start;i<start+3;i++){ num = num*10 + (s[i]-'0'); if(num<=255){ ip+=s[i]; dfsIp(s,i+1,step+1,ip+'.',result); } if(num == 0) break; } } vector<string> restoreIpAddresses(string s) { vector<string> result; string ip; // save temporaty result in processing dfsIp(s,0,0,ip,result); return result; }
9.Climbing a stair
You are climbing a stair case. It takes n steps to reach to the top.
Each time you can either climb 1 or 2 steps. In how many distinct ways can you climb to the top?
DP. The transition function should be:
f(n) = f(n-1) + f(n-2) n>2;
or = 1 n=1
or = 2 n=2
int climbStairs(int n) { if(n==0) return 0; if(n==1) return 1; if(n==2) return 2; int fn=0, fn_1 = 1,fn_2=2; for(int i=3;i<=n;i++){ fn = fn_2+fn_1; fn_1 = fn_2; fn_2 = fn; } return fn; }
10. Decode Ways
A message containing letters from
A-Zis being encoded to numbers using
the following mapping:
'A' -> 1 'B' -> 2 ... 'Z' -> 26
Given an encoded message containing digits, determine the total number of ways to decode it.
For example,
Given encoded message
"12", it could be decoded as
"AB"(1
2) or
"L"(12).
The number of ways decoding
"12"is 2.
Similar as "[LeetCode] Climbing Stairs". DP. Just add some logic to compare character.
Transformation function as:
Count[i] = Count[i-1] if S[i-1] is a valid char
or = Count[i-1]+ Count[i-2] if S[i-1] and S[i-2] together is still a valid char.
int check(char one){ return (one != '0') ? 1:0; } int check(char one, char two){ return (one =='1' || (one=='2'&& two<='6'))?1:0; } int numDecodings(string s) { if(s.empty() || s[0]=='0') return 0; if(s.size()==1) return check(s[0]); int fn=0, fn_1 = 0,fn_2 = 1; fn_1 = (check(s[0])*check(s[1]))+check(s[0],s[1]); for(int i=2;i<s.size();i++){ if(check(s[i])) fn+=fn_1; if(check(s[i-1],s[i])) fn+=fn_2; if(fn == 0) return 0; fn_2 = fn_1; fn_1 = fn; fn = 0; } return fn_1; }
相关文章推荐
- LeetCode之“动态规划”:Valid Parentheses && Longest Valid Parentheses
- leetcode 446. Arithmetic Slices II - Subsequence 等差序列的数量 + 一个很值得学习的DP动态规划做法
- 算法学习之动态规划(leetcode 91 Decode Ways)
- 动态规划第六讲——leetcode上的动态规划汇总(下)
- LeetCode之动态规划
- LeetCode之“动态规划”:Interleaving String
- leetcode 198:动态规划求小偷偷东西问题:
- 动态规划第六讲——leetcode上的动态规划汇总(下)
- LeetCode中的两道动态规划题目
- LeetCode之“动态规划”:Edit Distance
- 动态规划编程实例——LeetCode 494.Target Sum
- LeetCode题目:Unique Binary Search Trees,一维动态规划
- leetcode 322. Coin Change 类似背包问题 + 很简单的动态规划DP解决
- leetcode 第53题 Maximum Subarray:动态规划的活用
- [LeetCode] Unique Paths && Unique Paths II && Minimum Path Sum (动态规划之 Matrix DP )
- LeetCode之“动态规划”:House Robber && House Robber II
- leetcode动态规划之字符串切割成语句,单词都在字符串数组中
- [LeetCode198 House Robber]数组中的动态规划求最值问题
- leetcode 53. Maximum Subarray(DP动态规划问题)
- leetcode 198House Robber(简单动态规划解法)