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

  • 相关阅读:
    Vasya and Endless Credits CodeForces
    Dreamoon and Strings CodeForces
    Online Meeting CodeForces
    数塔取数 基础dp
    1001 数组中和等于K的数对 1090 3个数和为0
    1091 线段的重叠
    51nod 最小周长
    走格子 51nod
    1289 大鱼吃小鱼
    POJ 1979 Red and Black
  • 原文地址:https://www.cnblogs.com/yrbbest/p/4438758.html
Copyright © 2011-2022 走看看