题目
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构成的子串为回文子串,则很容易得到状态转移方程及边界条件如下:
代码实现
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 - 1if (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()}}}
