zoukankan      html  css  js  c++  java
  • 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

  • 相关阅读:
    NTKO Officecontrol在线Word编辑器的使用
    SQL数据类型解释
    经典SQL语句大全(网络资源共享)
    Ext.grid.GridPanel属性及方法等
    C#简易播放器(基于开源VLC)
    委托,是我委托你处理事件
    .NET面试必备(整理)
    SQL server 数据库连接方式分析
    FTP操作类的使用
    微信企业号平台开发之获取菜单,创建菜单和删除菜单
  • 原文地址:https://www.cnblogs.com/yuzhangcmu/p/4037568.html
Copyright © 2011-2022 走看看