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     }
View Code

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     }
View Code

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     }
View Code

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     }
View Code

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     }
View Code 

Runtime: 524 ms, 实际上运行时间也没多少改善。可能是数据集大小的问题咯。

 

GitHub Link:

Partition.java

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编辑  收藏  举报

导航