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

你可能感兴趣的:(partition)