LeetCode: 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"]
]
Solution 0:
直接用DFS 做,实际上也是可以过Leetcode的检查的。
1 public List<List<String>> partition(String s) { 2 List<List<String>> ret = new ArrayList<List<String>>(); 3 if (s == null) { 4 return ret; 5 } 6 7 dfs(s, 0, new ArrayList<String>(), ret); 8 return ret; 9 } 10 11 public static void dfs(String s, int index, List<String> path, List<List<String>> ret) { 12 int len = s.length(); 13 if (index == len) { 14 ret.add(new ArrayList<String>(path)); 15 return; 16 } 17 18 for (int i = index; i < len; i++) { 19 String sub = s.substring(index, i + 1); 20 if (!isPalindrome(sub)) { 21 continue; 22 } 23 24 path.add(sub); 25 dfs(s, i + 1, path, ret); 26 path.remove(path.size() - 1); 27 } 28 } 29 30 public static boolean isPalindrome(String s) { 31 int len = s.length(); 32 int left = 0; 33 int right = len - 1; 34 35 while (left < right) { 36 if (s.charAt(left) != s.charAt(right)) { 37 return false; 38 } 39 left++; 40 right--; 41 } 42 43 return true; 44 }
Runtime: 520 ms
Solution 1:
用DFS 加上一个记忆。HashMap<String, Boolean> map 用它来记忆某一段是否回文,这样不用每一次都去判断回文。可以减少计算量。
1 public List<List<String>> partition1(String s) { 2 List<List<String>> ret = new ArrayList<List<String>>(); 3 List<String> path = new ArrayList<String>(); 4 5 if (s == null) { 6 return ret; 7 } 8 9 HashMap<String, Boolean> map = new HashMap<String, Boolean>(); 10 11 dfs(s, path, ret, 0, map); 12 13 return ret; 14 } 15 16 public boolean isPalindrom(String s) { 17 int len = s.length(); 18 if (len <= 1) { 19 return true; 20 } 21 22 int left = 0; 23 int right = len - 1; 24 for (; left < right; left++, right--) { 25 if (s.charAt(right) != s.charAt(left)) { 26 return false; 27 } 28 } 29 30 return true; 31 } 32 33 /* 34 we use a map to store the solutions to reduce the times of computing. 35 */ 36 public void dfs(String s, List<String> path, List<List<String>> ret, int index, HashMap<String, Boolean> map) { 37 if (index == s.length()) { 38 ret.add(new ArrayList<String>(path)); 39 return; 40 } 41 42 for (int i = index; i < s.length(); i++) { 43 String sub = s.substring(index, i + 1); 44 45 Boolean flag = map.get(sub); 46 if (flag == null) { 47 flag = isPalindrom(sub); 48 map.put(sub, flag); 49 } 50 51 if (!flag) { 52 continue; 53 } 54 55 path.add(sub); 56 dfs(s, path, ret, i + 1, map); 57 path.remove(path.size() - 1); 58 } 59 }
2014.12.29 Redo:
不过,最后的runtime没有什么大的改善。可能是数据量太小!
1 // Solution 2: The DFS version with memory.
2 public List<List<String>> partition(String s) {
3 List<List<String>> ret = new ArrayList<List<String>>();
4 if (s == null) {
5 return ret;
6 }
7
8 // bug: new map error.
9 dfs2(s, 0, new ArrayList<String>(), ret, new HashMap<String, Boolean>());
10 return ret;
11 }
12
13 public static void dfs2(String s, int index, List<String> path, List<List<String>> ret, HashMap<String, Boolean> map) {
14 int len = s.length();
15 if (index == len) {
16 ret.add(new ArrayList<String>(path));
17 return;
18 }
19
20 for (int i = index; i < len; i++) {
21 String sub = s.substring(index, i + 1);
22 if (!isPalindromeHash(sub, map)) {
23 continue;
24 }
25
26 path.add(sub);
27 dfs2(s, i + 1, path, ret, map);
28 path.remove(path.size() - 1);
29 }
30 }
31
32 // BUG 3: use boolean instead of Boolean.
33 public static boolean isPalindromeHash(String s, HashMap<String, Boolean> map) {
34 int len = s.length();
35 int left = 0;
36 int right = len - 1;
37
38 if (map.get(s) != null) {
39 return map.get(s);
40 }
41
42 map.put(s, true);
43 while (left < right) {
44 if (s.charAt(left) != s.charAt(right)) {
45 map.put(s, false);
46 return false;
47 }
48 left++;
49 right--;
50 }
51
52 return true;
53 }
Runtime: 592 ms
Solution 2:
先用DP做一次判断是不是回文,然后再执行DFS,如果发现某条string不是回文,就可以直接退出,从而减少计算量。
1 public List<List<String>> partition(String s) { 2 List<List<String>> ret = new ArrayList<List<String>>(); 3 List<String> path = new ArrayList<String>(); 4 5 if (s == null) { 6 return ret; 7 } 8 9 boolean[][] isPalindrom = buildPalindromDP(s); 10 11 dfs2(s, path, ret, 0, isPalindrom); 12 13 return ret; 14 } 15 16 /* 17 * Solution 2: Use DP to reduce the duplicate count. 18 * */ 19 boolean[][] buildPalindromDP(String s) { 20 int len = s.length(); 21 boolean[][] D = new boolean[len][len]; 22 23 for (int j = 0; j < len; j++) { 24 for (int i = 0; i <= j; i++) { 25 if (j == 0) { 26 D[i][j] = true; 27 continue; 28 } 29 30 D[i][j] = s.charAt(i) == s.charAt(j) 31 && (j - i <= 2 || D[i + 1][j - 1]); 32 } 33 } 34 35 return D; 36 } 37 38 /* 39 we use a map to store the solutions to reduce the times of computing. 40 */ 41 public void dfs2(String s, List<String> path, List<List<String>> ret, int index, boolean[][] isPalindromDP) { 42 if (index == s.length()) { 43 ret.add(new ArrayList<String>(path)); 44 return; 45 } 46 47 for (int i = index; i < s.length(); i++) { 48 String sub = s.substring(index, i + 1); 49 if (!isPalindromDP[index][i]) { 50 continue; 51 } 52 53 path.add(sub); 54 dfs2(s, path, ret, i + 1, isPalindromDP); 55 path.remove(path.size() - 1); 56 } 57 }
2014.12.29 Redo:
1 // BUG 3: use boolean instead of Boolean. 2 public static boolean isPalindromeHash(String s, HashMap<String, Boolean> map) { 3 int len = s.length(); 4 int left = 0; 5 int right = len - 1; 6 7 if (map.get(s) != null) { 8 return map.get(s); 9 } 10 11 map.put(s, true); 12 while (left < right) { 13 if (s.charAt(left) != s.charAt(right)) { 14 map.put(s, false); 15 return false; 16 } 17 left++; 18 right--; 19 } 20 21 return true; 22 } 23 24 // Solution 3: Use DP to determine the palindrome first. 25 public List<List<String>> partition(String s) { 26 List<List<String>> ret = new ArrayList<List<String>>(); 27 if (s == null) { 28 return ret; 29 } 30 31 int len = s.length(); 32 33 // D[i][j]: if this a palindrom for s.substring(i, j + 1). 34 boolean[][] D = new boolean[len][len]; 35 36 for (int j = 0; j < len; j++) { 37 for (int i = 0; i <= j; i++) { 38 D[i][j] = s.charAt(i) == s.charAt(j) && (j - i <= 2 || D[i + 1][j - 1]); 39 } 40 } 41 42 // bug: new map error. 43 dfs3(s, 0, new ArrayList<String>(), ret, D); 44 return ret; 45 } 46 47 public static void dfs3(String s, int index, List<String> path, List<List<String>> ret, boolean[][] D) { 48 int len = s.length(); 49 if (index == len) { 50 ret.add(new ArrayList<String>(path)); 51 return; 52 } 53 54 for (int i = index; i < len; i++) { 55 String sub = s.substring(index, i + 1); 56 if (!D[index][i]) { 57 continue; 58 } 59 60 path.add(sub); 61 dfs3(s, i + 1, path, ret, D); 62 path.remove(path.size() - 1); 63 } 64 }
Runtime: 524 ms, 实际上运行时间也没多少改善。可能是数据集大小的问题咯。
GitHub Link:
https://github.com/yuzhangcmu/LeetCode_algorithm/blob/master/dfs/Partition_2014_1229.java
posted on 2014-10-20 16:51 Yu's Garden 阅读(1823) 评论(2) 编辑 收藏 举报