標籤:leetcode
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"] ]
原題連結:https://oj.leetcode.com/problems/palindrome-partitioning/
題目;給定一個字串s , 把s 分成每個子串都是迴文串。
返回s 的所有可能的迴文切分。
思路:根據對樣本的結果的觀察,發現需要兩個list,一個用於放入所有的單個字元,一個用於放入第二次的切分結果。於是有了下面的程式,即現遍曆一遍,將單個字元加入到list中去;再切分字元,判斷是否是迴文,如是,則加入到第二個list中去;最後返回結果。但是如下的方法總是在第二次的時候會漏掉單個字元。
public static List<List<String>> partition(String s) {List<List<String>> list = new ArrayList<List<String>>();List<String> li = new ArrayList<String>();int len = s.length();if(len == 0)return list;for(int i=0;i<len;i++){li.add(s.charAt(i)+"");}list.add(li);if(len == 1)return list;List<String> li1 = new ArrayList<String>();boolean flag = false;for(int i=0;i<len;i++){for(int j=i+1;j<len;j++){String sub = s.substring(i, j+1);if(isPalindrome(sub)){flag = true;li1.add(sub);}}}if(flag)list.add(li1);return list;}public static boolean isPalindrome(String s){int len = s.length();if(len <= 1)return true;for(int i=0;i<len;i++){if(s.charAt(i) != s.charAt(len - i - 1))return false;}return true;}
按照如上的程式,會與正確結果插肩而過。不過正確結果重複了呀。
| Input: |
"cdd" |
| Output: |
[["c","d","d"],["dd"]] |
| Expected: |
[["c","d","d"],["c","dd"]] |
下面是引用了網友[1]的解法,可以Accept.學習了。
這個題目考慮用動態規劃解題,關鍵在於構造一個解空間,確定S的任意子串S(i, j)是不是對稱的。判斷標準如下:
1、如果i == j,則S(i, j)是對稱的;
2、如果j - i == 1 && S[i] == S[j],則S(i, j)是對稱的;
3、如果j - i > 1 && S[i] == S[j] && S(i + 1, j - 1)是對稱的,則S(i, j)也是對稱的。
在構造完這樣的解空間後,就可以在O(1)時間內判定任意子串是不是對稱的了。演算法實現如下:
public ArrayList<ArrayList<String>> partition(String s) {ArrayList<ArrayList<String>> ret = new ArrayList<ArrayList<String>>();ArrayList<String> r = new ArrayList<String>();int length = s.length();boolean[][] map = new boolean[length][length];findPartition(s, 0, ret, r, map);return ret;}private void findPartition(String s, int start,ArrayList<ArrayList<String>> ret, ArrayList<String> r,boolean[][] map) {int length = s.length();if (start == length && r.size() != 0) {ArrayList<String> clone = new ArrayList<String>(r);ret.add(clone);} else {for (int j = start; j < length; j++) {if (start == j|| (j - start > 1 && s.charAt(start) == s.charAt(j) && map[start + 1][j - 1])|| (j - start == 1 && s.charAt(start) == s.charAt(j))) {map[start][j] = true;r.add(s.substring(start, j + 1));findPartition(s, j + 1, ret, r, map);r.remove(r.size() - 1);}}}}
[1] reference: http://www.blogjava.net/menglee/archive/2013/12/19/407778.html