[Leetcode] Palindrome Partitioning
2014-10-13 12:49
190 查看
题目:
Given a string s, partition s such that every substring of the partition is a palindrome.
Return all possible palindrome partitioning of s.
For example, given s =
Return
思路一:Brute Force解法需要判断所有子字符串是否为回文,这样同一子字符串可能被判断多次,因此考虑到用动态规划。利用一个矩阵记录信息,A[i][j]表示S[i...j]是否为回文。这样下一次需要判断时可以直接从矩阵中获得信息。
思路二(优化):在思路一的基础上,在计算某个子字符串是否为回文时,并不需要判断所有子字符串,可以进一步利用动态规划。
首先,若s[i...j]为回文,即A[i][j]为true,那么对于s[i-1...j+1]只需判断首位两个字符是否相等;同理,若s[i...j]不是回文,那么以该子字符串为中心的所有子字符串都不可能是回文。因此,用矩阵进行计算时,以每个字符为中心,向外扩展。这样较长的子字符串即可以利用较短的子字符串的计算结果,进一步避免了重复计算。需要注意的是,上面只讨论了以每一个字符为中心向外扩展,即子字符串为奇数的情况;同样需要讨论子字符串为偶数的情况。判断这种情况,仅需要以两个相邻的字符对进行扩展即可。
总结:同样的,trace可以定义为static。算法的复杂度由DFS决定。
Given a string s, partition s such that every substring of the partition is a palindrome.
Return all possible palindrome partitioning of s.
For example, given s =
"aab",
Return
[ ["aa","b"], ["a","a","b"] ]
思路一:Brute Force解法需要判断所有子字符串是否为回文,这样同一子字符串可能被判断多次,因此考虑到用动态规划。利用一个矩阵记录信息,A[i][j]表示S[i...j]是否为回文。这样下一次需要判断时可以直接从矩阵中获得信息。
class Solution { public: vector<string> trace; bool isPalindrome(const string& s) { for (int i = 0; i < s.length() / 2; ++i) { if (s[i] != s[s.length() - 1 - i]) return false; } return true; } void dfs(const vector<vector<bool>>& record, const string& s, int pos, vector<vector<string>>& result) { if (pos == (int)s.size()) { result.push_back(trace); return; } for (int i = pos; i < (int)s.size(); ++i) { if (record[pos][i]) { trace.push_back(s.substr(pos, i - pos + 1)); dfs(record, s, i + 1, result); trace.pop_back(); } } } vector<vector<string>> partition(string s) { vector<vector<bool>> record(s.size(), vector<bool>(s.size(), false)); // calculate the status matrix for (int i = 0; i < (int)s.size(); ++i) { for (int j = i; j < (int)s.size(); ++j) { record[i][j] = isPalindrome(s.substr(i, j - i + 1)); } } // get all the combinations vector<vector<string>> result; dfs(record, s, 0, result); return result; } };
思路二(优化):在思路一的基础上,在计算某个子字符串是否为回文时,并不需要判断所有子字符串,可以进一步利用动态规划。
首先,若s[i...j]为回文,即A[i][j]为true,那么对于s[i-1...j+1]只需判断首位两个字符是否相等;同理,若s[i...j]不是回文,那么以该子字符串为中心的所有子字符串都不可能是回文。因此,用矩阵进行计算时,以每个字符为中心,向外扩展。这样较长的子字符串即可以利用较短的子字符串的计算结果,进一步避免了重复计算。需要注意的是,上面只讨论了以每一个字符为中心向外扩展,即子字符串为奇数的情况;同样需要讨论子字符串为偶数的情况。判断这种情况,仅需要以两个相邻的字符对进行扩展即可。
class Solution { public: vector<string> trace; void dfs(const vector<vector<bool>>& record, const string& s, int pos, vector<vector<string>>& result) { if (pos == (int)s.size()) { result.push_back(trace); return; } for (int i = pos; i < (int)s.size(); ++i) { if (record[pos][i]) { trace.push_back(s.substr(pos, i - pos + 1)); dfs(record, s, i + 1, result); trace.pop_back(); } } } vector<vector<string>> partition(string s) { vector<vector<bool>> record(s.size(), vector<bool>(s.size(), false)); for (int i = 0; i < (int)s.size(); ++i) { record[i][i] = true; // odd length for (int j = 1; i - j >= 0 && i + j < (int)s.size(); ++j) { if (s[i-j] == s[i+j]) record[i-j][i+j] = true; else break; } // even length for (int j = 0; i - j >= 0 && i + 1 + j < (int)s.size(); ++j) { if (s[i-j] == s[i+1+j]) record[i-j][i+1+j] = true; else break; } } vector<vector<string>> result; dfs(record, s, 0, result); return result; } };
总结:同样的,trace可以定义为static。算法的复杂度由DFS决定。
相关文章推荐
- LeetCode: Remove Duplicates from Sorted Array
- [LeetCode] Add Two Numbers
- LeetCode:4Sum
- LeetCode: Remove Duplicates from Sorted Array II
- LeetCode--Wrod Break
- 【LeetCode】131. Palindrome Partitioning
- Leetcode - Next Permutation.
- leetcode:Repeated DNA Sequences
- LeetCode Triangle 120 DP问题
- [Leetcode]-Unique Paths II
- 【LeetCode】LRU Cache
- LeetCode Unique Paths (简单DP)
- [leetcode] 40. Combination Sum II 解题报告
- [leetcode] 266. Palindrome Permutation 解题报告
- LeetCode(42)-Best Time to Buy and Sell Stock(卖股票)
- LeetCode 151. Reverse Words in a String(反转单词)
- 【Leetcode】82 Remove Duplicates from Sorted List II 【指针&链表】
- LeetCode -- 62 Unique Paths
- Leetcode 127. Word Ladder 字符变换 解题报告
- 【leetcode】单链表的插入排序