zoukankan      html  css  js  c++  java
  • [LeetCode] 131. 分割回文串

    题目链接 : https://leetcode-cn.com/problems/palindrome-partitioning/

    题目描述:

    给定一个字符串 s,将 s 分割成一些子串,使每个子串都是回文串。

    返回 s 所有可能的分割方案。

    示例:

    输入: "aab"
    输出:
    [
      ["aa","b"],
      ["a","a","b"]
    ]
    

    思路:

    思路一: 回溯算法

    思路二: 动态规划 + DFS

    大家可以先看 5. 最长回文子串(题解链接)的动态规划方法, 我们用dp[j][i]字符串从位置j到位置i(闭区间)是否为回文子串.

    再用DFS把所有可能找到!

    相关题型:132. 分割回文串 II

    代码:

    思路一:

    class Solution:
        def partition(self, s: str) -> List[List[str]]:
            res = []
            
            def helper(s, tmp):
                if not s:
                    res.append(tmp)
                for i in range(1, len(s) + 1):
                    if s[:i] == s[:i][::-1]:
                        helper(s[i:], tmp + [s[:i]])
            helper(s, [])
            return res
    

    java

    class Solution {
        public List<List<String>> partition(String s) {
            List<List<String>> res = new ArrayList<>();
            backtrack(res, s,  new ArrayList<String>());
            return res;
    
        }
    
        private void backtrack(List<List<String>> res, String s, ArrayList<String> tmp) {
            if (s == null || s.length() == 0) res.add(new ArrayList<>(tmp));
            for (int i = 1; i <= s.length(); i++) {
                if (isPalidrome(s.substring(0, i))) {
                    // System.out.println(s.substring(0, i));
                    tmp.add(s.substring(0, i));
                    backtrack(res, s.substring(i, s.length()), tmp);
                    tmp.remove(tmp.size() - 1);
                }
            }
        }
    
        private  boolean isPalidrome(String sb) {
            int left = 0;
            int right = sb.length() - 1;
            while (left < right) {
                if (sb.charAt(left) != sb.charAt(right)) return false;
                left++;
                right--;
            }
            return true;
    
        }
    }
    

    思路二:

    class Solution:
        def partition(self, s: str) -> List[List[str]]:
            n = len(s)
            dp = [[False] * n for _ in range(n)]
    
            for i in range(n):
                for j in range(i + 1):
                    if (s[i] == s[j]) and (i - j <= 2 or dp[j + 1][i - 1]):
                        dp[j][i] = True
            #print(dp)
            res = []
    
            def helper(i, tmp):
                if i == n:
                    res.append(tmp)
                for j in range(i, n):
                    if dp[i][j]:
                        helper(j + 1, tmp + [s[i: j + 1]])
    
            helper(0, [])
            return res
    

    java

    class Solution {
        public List<List<String>> partition(String s) {
            List<List<String>> res = new ArrayList<>();
            int n = s.length();
            boolean[][] dp = new boolean[n][n];
            for (int i = 0; i < n; i++) {
                for (int j = 0; j <= i; j++) {
                    if (s.charAt(i) == s.charAt(j) && (i - j < 2 || dp[j + 1][i - 1])) dp[j][i] = true;
                }
            }
            System.out.println(Arrays.deepToString(dp));
            dfs(res, dp, 0, n, s, new ArrayList<String>());
            return res;
    
        }
    
        private void dfs(List<List<String>> res, boolean[][] dp, int i, int n, String s, ArrayList<String> tmp) {
            if (i == n) res.add(new ArrayList<>(tmp));
            for (int j = i; j < n; j++) {
                if (dp[i][j]) {
                    tmp.add(s.substring(i, j + 1));
                    dfs(res, dp, j + 1, n, s, tmp);
                    tmp.remove(tmp.size() - 1);
                }
            }
        }
    }
    
  • 相关阅读:
    POJ2456 Aggressive cows
    Binary Search
    Leetcode1025 Divisor Game
    我的高中生活目标
    leetcode155 min stack
    Leetcode983 Minimum Cost For Tickets
    合并两个有序数组
    X的平方根
    力扣第35场双周赛
    整数反转
  • 原文地址:https://www.cnblogs.com/powercai/p/11191069.html
Copyright © 2011-2022 走看看