131. Palindrome Partitioning
题目:
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"]
]
链接: http://leetcode.com/problems/palindrome-partitioning/
题解:
一看到return all xxxx,就猜到可能要用回溯。这道题就是比较典型的递归+回溯。递归前要判断当前的子字符串是否palindrome,答案是false的话要continue。
Time Complexity - O(n*2n), Space Complexity - O(n*2n)
public class Solution { public List<List<String>> partition(String s) { List<List<String>> res = new ArrayList<>(); if(s == null || s.length() == 0) return res; ArrayList<String> list = new ArrayList<>(); partition(res, list, s, 0); return res; } private void partition(List<List<String>> res, ArrayList<String> list, String s, int pos) { if(pos == s.length()) { res.add(new ArrayList<String>(list)); return; } for(int i = pos + 1; i <= s.length(); i++) { String partition = s.substring(pos, i); if(!isPalindrome(partition)) continue; list.add(partition); partition(res, list, s, i); list.remove(list.size() - 1); } } private boolean isPalindrome(String s) { int lo = 0, hi = s.length() - 1; while(lo < hi) { if(s.charAt(lo) != s.charAt(hi)) return false; lo++; hi--; } return true; } }
需要好好看看主方法来确定定量分析递归算法的时间复杂度。
二刷:
仔细想一想代码可以简化不少。主要分为三部分。1是题目给定的方法,2是辅助方法,用来递归和回溯,3是判断string是否是palindrome。注意考虑清楚需要多少变量,以及时间空间复杂度。
Time Complexity: O(n!)
Space Complexity: O(n ^ 2)
Java:
public class Solution { public List<List<String>> partition(String s) { List<List<String>> res = new ArrayList<>(); List<String> list = new ArrayList<>(); partition(res, list, s); return res; } private void partition(List<List<String>> res, List<String> list, String s) { if (s == null || s.length() == 0) { res.add(new ArrayList<String>(list)); return; } for (int i = 0; i < s.length(); i++) { String subStr = s.substring(0, i + 1); if (isPalindrome(subStr)) { list.add(subStr); partition(res, list, s.substring(i + 1)); list.remove(list.size() - 1); } } } private boolean isPalindrome(String s) { if (s == null || s.length() < 2) { return true; } int lo = 0, hi = s.length() - 1; while (lo <= hi) { if (s.charAt(lo) != s.charAt(hi)) { return false; } lo++; hi--; } return true; } }
三刷:
依然是使用二刷的方法。
Java:
public class Solution { public List<List<String>> partition(String s) { List<List<String>> res = new ArrayList<>(); if (s == null || s.length() == 0) return res; partition(res, new ArrayList<>(), s); return res; } private void partition(List<List<String>> res, List<String> list, String s) { if (s.length() == 0) { res.add(new ArrayList<String>(list)); return; } for (int i = 0; i <= s.length(); i++) { String front = s.substring(0, i); if (isPalindrome(front)) { list.add(front); partition(res, list, s.substring(i)); list.remove(list.size() - 1); } } } private boolean isPalindrome(String s) { if (s == null || s.length() == 0) return false; int lo = 0, hi = s.length() - 1; while (lo < hi) { if (s.charAt(lo) != s.charAt(hi)) return false; lo++; hi--; } return true; } }
Reference:
http://stackoverflow.com/questions/24591616/whats-the-time-complexity-of-this-algorithm-for-palindrome-partitioning
http://blog.csdn.net/metasearch/article/details/4428865
https://en.wikipedia.org/wiki/Master_theorem
http://www.cnblogs.com/zhuli19901106/p/3570430.html
https://leetcode.com/discuss/18984/java-backtracking-solution
https://leetcode.com/discuss/9623/my-java-dp-only-solution-without-recursion-o-n-2
https://leetcode.com/discuss/41626/concise-java-solution
https://leetcode.com/discuss/4788/shouldnt-we-use-dp-in-addition-to-dfs