0131. Palindrome Partitioning (M)

Palindrome Partitioning (M)

题目

Given a string s, partition s such that every substring of the partition is a palindrome.

Return all possible palindrome partitioning of s.

Example:

Input: "aab"
Output:
[
  ["aa","b"],
  ["a","a","b"]
]

题意

对给定字符串进行划分,使其分出的每一部分都是一个回文子串。求出所有这样的划分方式。

思路

DFS处理。

可以利用动态规划对判断回文这一步骤进行优化:设若P[i][j]==true,则字符串s中从下标i到下标j构成的子串为回文子串,则很容易得到状态转移方程及边界条件如下:

\[P[i][j] = (P[i+1][j-1] \ \&\&\ s[i] == s[j]) \]

\[P[i][j] = \begin{cases} true, &i==j\\ true, &j==i+1 \ \&\&\ s[i]==s[j]\\ false, &j==i+1 \ \&\&\ s[i]\ !=s[j] \end{cases} \]


代码实现

Java

暴力递归

class Solution {
    public List<List<String>> partition(String s) {
        List<List<String>> ans = new ArrayList<>();
        dfs(s, ans, new ArrayList<>());
        return ans;
    }

    private void dfs(String s, List<List<String>> ans, List<String> temp) {
        if (s.equals("")) {
            ans.add(new ArrayList<>(temp));
            return;
        }

        for (int i = 1; i <= s.length(); i++) {
            String sub = s.substring(0, i);
            if (isPalindrome(sub)) {
                temp.add(sub);
                dfs(s.substring(i), ans, temp);
                temp.remove(temp.size() - 1);
            }
        }
    }

    private boolean isPalindrome(String s) {
        int left = 0, right = s.length() - 1;
        while (left < right) {
            if (s.charAt(left++) != s.charAt(right--)) {
                return false;
            }
        }
        return true;
    }
}

动态规划优化

class Solution {
    public List<List<String>> partition(String s) {
        List<List<String>> ans = new ArrayList<>();
        boolean[][] dp = new boolean[s.length()][s.length()];
        
        // 生成dp数组
        for (int len = 1; len <= s.length(); len++) {
            for (int i = 0; i + len - 1 < s.length(); i++) {
                int j = i + len - 1;
                if (len == 1) {
                    dp[i][j] = true;
                } else if (len == 2) {
                    dp[i][j] = s.charAt(i) == s.charAt(j);
                } else {
                    dp[i][j] = dp[i + 1][j - 1] && s.charAt(i) == s.charAt(j);
                }
            }
        }
        
        dfs(s, dp, 0, ans, new ArrayList<>());
        
        return ans;
    }

    private void dfs(String s, boolean[][] dp, int start, List<List<String>> ans, List<String> temp) {
        if (start == s.length()) {
            ans.add(new ArrayList<>(temp));
            return;
        }

        for (int end = start; end < s.length(); end++) {
            if (dp[start][end]) {
                temp.add(s.substring(start, end + 1));
                dfs(s, dp, end + 1, ans, temp);
                temp.remove(temp.size() - 1);
            }
        }
    }
}

JavaScript

/**
 * @param {string} s
 * @return {string[][]}
 */
var partition = function (s) {
  let ans = []
  let judge = new Array(s.length).fill(0).map(item => new Array(s.length).fill(false))

  for (let len = 1; len <= s.length; len++) {
    for (let left = 0; left + len - 1 < s.length; left++) {
      let right = left + len - 1
      if (left === right) {
        judge[left][right] = true
      } else if (right === left + 1) {
        judge[left][right] = s[left] === s[right]
      } else {
        judge[left][right] = judge[left + 1][right - 1] && s[left] === s[right]
      }
    }
  }

  dfs(s, 0, judge, ans, [])
  return ans
}

let dfs = function (s, start, judge, ans, tmp) {
  if (start === s.length) {
    return ans.push([...tmp])
  }

  for (let end = start; end < s.length; end++) {
    if (judge[start][end]) {
      tmp.push(s.slice(start, end + 1))
      dfs(s, end + 1, judge, ans, tmp)
      tmp.pop()
    }
  }
}
posted @ 2020-12-14 16:53  墨云黑  阅读(85)  评论(0编辑  收藏  举报