lintcode 136. 分割回文串 108. 分割回文串 II 200. 最长回文子串 678. 最短回文串

136. 分割回文串

描述
给定字符串 s, 需要将它分割成一些子串, 使得每个子串都是回文串.

返回所有可能的分割方案.

样例
样例 1:

输入: “a”
输出: [[“a”]]
解释: 字符串里只有一个字符, 也就只有一种分割方式 (就是它本身)

样例 2:

输入: “aab”
输出: [[“aa”, “b”], [“a”, “a”, “b”]]
解释: 有两种分割的方式.
1. 将 “aab” 分割成 “aa” 和 “b”, 它们都是回文的.
2. 将 “aab” 分割成 “a”, “a” 和 “b”, 它们全都是回文的.

dfs + 回溯法

public class Solution {
    /*
     * @param s: A string
     * @return: A list of lists of string
     */
     private List<List<String>> list;
    private  boolean[][] dp ;
    public List<List<String>> partition(String s) {
        int n = s.length();
        list = new ArrayList<>();
        dp = new boolean[n][n];
        for (int i = n - 1; i >= 0; i--) {
            for(int j = i; j < n; j++) {
                dp[i][j] = (s.charAt(i) == s.charAt(j)) && (j - i <= 2 || dp[i +1][j - 1]);
            }
        }

            dfs(s, 0, new ArrayList<>());
        return list;
    }

    public void dfs(String s, int curr, List<String> temp) {
        if (s.length() == curr) {
            list.add(new ArrayList<>(temp));// 新建数组  不然会到导致浅拷贝  数据联动
            return;
        }
        for (int i = curr; i < s.length(); i++) {
            if (dp[curr][i]) {
                temp.add(s.substring(curr, i + 1));
                dfs(s, i + 1, temp);
                temp.remove(temp.size() - 1); // 回溯
            }
        }
    }
}

108. 分割回文串 II

描述

给定字符串 s, 需要将它分割成一些子串, 使得每个子串都是回文串.

最少需要分割几次?

样例
样例 1:

输入: “a”
输出: 0
解释: “a” 本身就是回文串, 无需分割

样例 2:

输入: “aab”
输出: 1
解释: 将 “aab” 分割一次, 得到 “aa” 和 “b”, 它们都是回文串.

public class Solution {
    /**
     * @param s: A string
     * @return: An integer
     */
    public int minCut(String s) {
        // write your code here
        int n = s.length();
        boolean[][] dp = new boolean[n][n];
        for (int i = n - 1; i >= 0; i--) {
            for (int j = i; j < n; j++) {
                dp[i][j] = (s.charAt(i) == s.charAt(j)) && (j - i <= 2 || dp[i + 1][j - 1]);
            }
        }
        int[] f = new int[n + 1];
        f[0] = 0;
        for (int i = 1; i <= n; i++) {
              f[i] = Integer.MAX_VALUE;
            for(int j = 0; j < i; j++) {
                if (dp[j][i - 1]) {
                    f[i] = Math.min(f[j] + 1, f[i]);
                }
            }
        }
        return f[n] - 1;  // 因为是划分次数要减一
    }

200. 最长回文子串

描述

给出一个字符串(假设长度最长为1000),求出它的最长回文子串,你可以假定只有一个满足条件的最长回文串。

样例
样例 1:

输入:“abcdzdcab”
输出:“cdzdc”

样例 2:

输入:“aba”
输出:“aba”

public class Solution {
    /**
     * @param s: input string
     * @return: a string as the longest palindromic substring
     */
    public String longestPalindrome(String s) {
        // write your code here
         int n = s.length();
         int res = 0;
         int l = 0;
         int r = 0;
        boolean[][] dp = new boolean[n][n];
        for (int i = n - 1; i >= 0; i--) {
            for (int j = i; j < n; j++) {
                dp[i][j] = (s.charAt(i) == s.charAt(j)) && (j - i <= 2 || dp[i + 1][j - 1]);
                if (dp[i][j]) {
                    if (res < s.substring(i, j + 1).length()) {
                        res = s.substring(i, j + 1).length();
                        l = i;
                        r =j;
                    }
                }
            }
        }
        return s.substring(l, r + 1);
    }
}

678. 最短回文串

描述
给一个字符串 S, 你可以通过在前面添加字符将其转换为回文串.找到并返回用这种方式转换的最短回文串.

您在真实的面试中是否遇到过这个题?
样例
样例1

输入: “aacecaaa”
输出: “aaacecaaa”
解释:
在输入字符串前面添加一个’a’。

样例2

输入: “abcd”
输出: “dcbabcd”

只能过90%

从尾巴开始取出 字符串 如果剩下的是一个回文字符串 就将取出的字符串逆序拼接到头部

public class Solution {
    /**
     * @param str: String
     * @return: String
     */
    public String shortestPalindrome(String str) {
        // Write your code here
        int n = str.length();
        boolean[][] dp = new boolean[n][n];
        for (int i = n - 1; i >= 0; i--) {
            for (int j = i; j < n; j++) {
                dp[i][j] = (str.charAt(i) == str.charAt(j)) && (j - i <= 2 || dp[i + 1][j - 1]);
            }
        }
        String res = "";
        for (int i = n - 1; i > 0; i--) {
            if (dp[0][i]) {
                 
                res = new StringBuffer(str.substring(i + 1 , n)).reverse().toString() + str;
                break;
            }
        }
        if (res.length() == 0 && n != 0) {
            res = new StringBuilder(str).reverse().toString() + str.substring(1, str.length());
        }
        return res;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值