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

    链接:  http://leetcode.com/problems/palindrome-partitioning/

    题解:

    一看到return all xxxx,就猜到可能要用回溯。这道题就是比较典型的递归+回溯。递归前要判断当前的子字符串是否palindrome,答案是false的话要continue。

    Time Complexity - O(n*2n), Space Complexity - O(n*2n)

    public class Solution {
        public List<List<String>> partition(String s) {
            List<List<String>> res = new ArrayList<>();
            if(s == null || s.length() == 0)
                return res;
            ArrayList<String> list = new ArrayList<>();
            partition(res, list, s, 0);
            return res;
        }
        
        private void partition(List<List<String>> res, ArrayList<String> list, String s, int pos) {
            if(pos == s.length()) {
                res.add(new ArrayList<String>(list));
                return;
            }
            
            for(int i = pos + 1; i <= s.length(); i++) {
                String partition = s.substring(pos, i);
                if(!isPalindrome(partition))
                    continue;
                list.add(partition);
                partition(res, list, s, i);
                list.remove(list.size() - 1);
            }
        }
        
        
        private boolean isPalindrome(String s) {
            int lo = 0, hi = s.length() - 1;
            
            while(lo < hi) {
                if(s.charAt(lo) != s.charAt(hi))
                    return false;
                lo++;
                hi--;
            }
            
            return true;
        }
    }

    需要好好看看主方法来确定定量分析递归算法的时间复杂度。

    二刷:

    仔细想一想代码可以简化不少。主要分为三部分。1是题目给定的方法,2是辅助方法,用来递归和回溯,3是判断string是否是palindrome。注意考虑清楚需要多少变量,以及时间空间复杂度。

    Time Complexity: O(n!)

    Space Complexity: O(n ^ 2)

    Java:

    public class Solution {
        public List<List<String>> partition(String s) {
            List<List<String>> res = new ArrayList<>();
            List<String> list = new ArrayList<>();
            partition(res, list, s);
            return res;
        }
        
        private void partition(List<List<String>> res, List<String> list, String s) {
            if (s == null || s.length() == 0) {
                res.add(new ArrayList<String>(list));
                return;
            }
            for (int i = 0; i < s.length(); i++) {
                String subStr = s.substring(0, i + 1);
                if (isPalindrome(subStr)) {
                    list.add(subStr);
                    partition(res, list, s.substring(i + 1));
                    list.remove(list.size() - 1);
                }
            }
        }
        
        private boolean isPalindrome(String s) {
            if (s == null || s.length() < 2) {
                return true;
            }
            int lo = 0, hi = s.length() - 1;
            while (lo <= hi) {
                if (s.charAt(lo) != s.charAt(hi)) {
                    return false;
                }
                lo++;
                hi--;
            }
            return true;
        }
    }

    三刷:

    依然是使用二刷的方法。

    Java:

    public class Solution {
        public List<List<String>> partition(String s) {
            List<List<String>> res = new ArrayList<>();
            if (s == null || s.length() == 0) return res;
            partition(res, new ArrayList<>(), s);
            return res;
        }
        
        private void partition(List<List<String>> res, List<String> list, String s) {
            if (s.length() == 0) {
                res.add(new ArrayList<String>(list));
                return;
            }
            for (int i = 0; i <= s.length(); i++) {
                String front = s.substring(0, i);
                if (isPalindrome(front)) {
                    list.add(front);
                    partition(res, list, s.substring(i));
                    list.remove(list.size() - 1);
                }
            }
        }
        
        private boolean isPalindrome(String s) {
            if (s == null || s.length() == 0) return false;
            int lo = 0, hi = s.length() - 1;
            while (lo < hi) {
                if (s.charAt(lo) != s.charAt(hi)) return false;
                lo++;
                hi--;
            }
            return true;
        }
    }

    Reference:

    http://stackoverflow.com/questions/24591616/whats-the-time-complexity-of-this-algorithm-for-palindrome-partitioning

    http://blog.csdn.net/metasearch/article/details/4428865

    https://en.wikipedia.org/wiki/Master_theorem

    http://www.cnblogs.com/zhuli19901106/p/3570430.html

    https://leetcode.com/discuss/18984/java-backtracking-solution

    https://leetcode.com/discuss/9623/my-java-dp-only-solution-without-recursion-o-n-2

    https://leetcode.com/discuss/41626/concise-java-solution

    https://leetcode.com/discuss/4788/shouldnt-we-use-dp-in-addition-to-dfs

  • 相关阅读:
    左耳听风-ARTS-第4周(2019/4/21-2019/4/27)
    Java集合总结
    Zuul网关总结
    左耳听风-ARTS-第3周(2019/4/7-2019/4/13)
    左耳听风-ARTS-第2周(2019/3/31-2019/4/6)
    Java泛型相关总结(下)
    左耳听风-ARTS-第1周
    去长江边走走,看看
    第1记
    c#发送邮件
  • 原文地址:https://www.cnblogs.com/yrbbest/p/4438758.html
Copyright © 2011-2022 走看看