DP(5) -- Word Break, Partition Equal Subset Sum,Arithmetic Slices
2017-01-09 21:02
218 查看
Word Break
Given a non-empty string s and a dictionary wordDict containing a list of non-empty words, determine if s can be segmented
into a space-separated sequence of one or more dictionary words. You may assume the dictionary does not contain duplicate words.
For example, given
s =
dict =
Return true because
解法1:DFS。可以递归也可以不用递归去写。遍历搜索的话非常重要的一点是减少空间开辟和销毁的开销,以及避免重复搜索
解法2:BFS,贴一个优化不太好的解法,主要看思路
解法3:DP。记录到i为止是否为满足条件的序列。
Partition Equal Subset Sum
解法1:DP
1. 问题可转化为是否存在subset of nums使得sum = totalSum / 2。
2. 类似背包问题,每个数可能选或者不选。dp[i][j]记录i为止能否使得sum = j. 更新公式为 dp[i][j] = (dp[i][j] || dp[i-1][j-nums[i-1]]);
3. 以下为Java版本
改进:
由于每次新状态的更新为仅和i-1的状态有关,因此可以将空间复杂度降为O(n)。注意此时遍历 j 时,需要从后向前;如若从前向后的话,前面更新的值会对后面值的更新产生影响。
Arithmetic Slices
A sequence of number is called arithmetic if it consists of at least three elements and if the difference between any two consecutive elements is the same.
For example, these are arithmetic sequence:
A slice (P, Q) of array A is called arithmetic if the sequence:
A[P], A[p + 1], ..., A[Q - 1], A[Q] is arithmetic. In particular, this means that P + 1 < Q.
The function should return the number of arithmetic slices in the array A.
不是很困难的一道题。如果A[i] - A[i-1] = lastDiff, 则以A[i]结尾的slice有consecLen - 2 个,所以总的是sliceNum += consecLen - 2。
Given a non-empty string s and a dictionary wordDict containing a list of non-empty words, determine if s can be segmented
into a space-separated sequence of one or more dictionary words. You may assume the dictionary does not contain duplicate words.
For example, given
s =
"leetcode",
dict =
["leet", "code"].
Return true because
"leetcode"can be segmented as
"leet code".
解法1:DFS。可以递归也可以不用递归去写。遍历搜索的话非常重要的一点是减少空间开辟和销毁的开销,以及避免重复搜索
class Solution { public: bool match(int start, string& s, string& word){ for(int i = 0; i < word.size(); i++){ if(s[i+start] != word[i]) return false; } return true; } bool find(string& s, int start, vector<string>& wordDict, unordered_set<int>& visit){ if(visit.find(start) != visit.end()) return false; if(start == s.size()) return true; for(string word: wordDict){ if(word.size() <= s.size() - start && word[0] == s[start]) if(match(start, s, word) && find(s, start+word.size(), wordDict, visit)) return true; } visit.insert(start); return false; } bool wordBreak(string s, vector<string>& wordDict) { unordered_set<int> visit; return find(s, 0, wordDict, visit); } };
解法2:BFS,贴一个优化不太好的解法,主要看思路
bool wordBreak(string s, vector<string>& wordDict) { // BFS queue<int> BFS; unordered_set<int> visited; BFS.push(0); while(BFS.size() > 0) { int start = BFS.front(); BFS.pop(); if(visited.find(start) == visited.end()) { visited.insert(start); for(int j=start; j<s.size(); j++) { string word(s, start, j-start+1); if(find(wordDict.begin(), wordDict.end(), word) != wordDict.end()) //这一部分的搜索是可以优化的,new string和简单的find { //都是很耗时的 BFS.push(j+1); if(j+1 == s.size()) return true; } } } } return false; }
解法3:DP。记录到i为止是否为满足条件的序列。
class Solution { public: bool match(int start, string& s, string& word){ //start为要比较子串的起始在s中的起始位置 for(int i = 0; i < word.size(); i++){ if(s[i+start] != word[i]) return false; } return true; } bool wordBreak(string s, vector<string>& wordDict) { vector<bool> dp(s.size()+1); dp[0] = true; for(int i = 1; i <= s.size(); i++){ bool valid = false; for(int j = 0; j < wordDict.size(); j++){ string word = wordDict[j]; if(i >= word.size() && dp[i - word.size()] && match(i - word.size(), s, word)){ valid = true; break; } } dp[i] = valid; } return dp[s.size()]; } };
Partition Equal Subset Sum
解法1:DP
1. 问题可转化为是否存在subset of nums使得sum = totalSum / 2。
2. 类似背包问题,每个数可能选或者不选。dp[i][j]记录i为止能否使得sum = j. 更新公式为 dp[i][j] = (dp[i][j] || dp[i-1][j-nums[i-1]]);
3. 以下为Java版本
public boolean canPartition(int[] nums) { int sum = 0; for (int num : nums) { sum += num; } if ((sum & 1) == 1) { return false; } sum /= 2; int n = nums.length; boolean[][] dp = new boolean[n+1][sum+1]; for (int i = 0; i < dp.length; i++) { Arrays.fill(dp[i], false); } dp[0][0] = true; for (int i = 1; i < n+1; i++) { dp[i][0] = true; } for (int j = 1; j < sum+1; j++) { dp[0][j] = false; } for (int i = 1; i < n+1; i++) { for (int j = 1; j < sum+1; j++) { dp[i][j] = dp[i-1][j]; if (j >= nums[i-1]) { dp[i][j] = (dp[i][j] || dp[i-1][j-nums[i-1]]); } } } return dp [sum]; }
改进:
由于每次新状态的更新为仅和i-1的状态有关,因此可以将空间复杂度降为O(n)。注意此时遍历 j 时,需要从后向前;如若从前向后的话,前面更新的值会对后面值的更新产生影响。
bool canPartition(vector<int>& nums) { int sum = 0; for(int num: nums) sum += num; if(sum % 2) return false; sum /= 2; bool dp[sum + 1]; fill_n(dp, sum + 1, false); dp[0] = true; for(int i = 0; i < nums.size(); i++){ for(int j = sum; j > 0; j--){ if(j >= nums[i]) dp[j] = dp[j] || dp[j - nums[i]]; //not pick || pick } } return dp[sum]; }
Arithmetic Slices
A sequence of number is called arithmetic if it consists of at least three elements and if the difference between any two consecutive elements is the same.
For example, these are arithmetic sequence:
1, 3, 5, 7, 9 7, 7, 7, 7
A slice (P, Q) of array A is called arithmetic if the sequence:
A[P], A[p + 1], ..., A[Q - 1], A[Q] is arithmetic. In particular, this means that P + 1 < Q.
The function should return the number of arithmetic slices in the array A.
不是很困难的一道题。如果A[i] - A[i-1] = lastDiff, 则以A[i]结尾的slice有consecLen - 2 个,所以总的是sliceNum += consecLen - 2。
int numberOfArithmeticSlices(vector<int>& A) { if(A.size() < 3) return 0; int consecLen = 2; int lastDiff = A[1] - A[0]; int sliceNum = 0; for(int i = 2; i < A.size(); i++){ if(A[i] - A[i-1] == lastDiff){ consecLen++; sliceNum += consecLen - 2; } else{ consecLen = 2; lastDiff = A[i] - A[i-1]; } } a52f return sliceNum; }
相关文章推荐
- 【Leetcode】416-Partition Equal Subset Sum -- javascript解法 01背包问题
- Partition Equal Subset Sum问题及解法
- Partition Equal Subset Sum
- 416. Partition Equal Subset Sum
- 588 - Partition Equal Subset Sum
- 416. Partition Equal Subset Sum
- LeetCode Partition Equal Subset Sum
- [LeetCode] Partition Equal Subset Sum
- 416. Partition Equal Subset Sum
- LeetCode[416] Partition Equal Subset Sum
- LeetCode No.416 Partition Equal Subset Sum
- 416. Partition Equal Subset Sum
- lintcode(588)Partition Equal Subset Sum
- Partition Equal Subset Sum
- [LeetCode] Partition Equal Subset Sum
- 416. Partition Equal Subset Sum
- [LeetCode] Partition Equal Subset Sum划分数组形成两个和相等的子集
- leetCode No.416 Partition Equal Subset Sum
- Partition Equal Subset Sum - leetcode 416号题目个人题解
- 416. Partition Equal Subset Sum