leetcode131-分割回文串

原题

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

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

示例:

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

解法

思想

在字符串中搜索是回文串的子字符串,可以使用dfs。

但判断子字符串是不是回文串的时候,可以下功夫优化,这里不能使用我在leetcode125-验证回文串中用到的方法,因为子字符串之间存在很多个重复的单元。

那么就可以使用动态规划的方法判断子字符串是否为回文串:使用一个二维的dp数组,dp[i][j]代表在字符串中下标i起始,下标j截止的子字符串是否为回文串,根据回文串的判断方法,可以得到状态转移方程dp[i][j] = s.charAt(i)==s.charAt(j) && dp[i+1][j-1]

代码

class Solution {
    boolean[][] dp;
    char[] chars;
    List<List<String>> ans = new ArrayList<>();
    public List<List<String>> partition(String s) {
        int length = s.length();
        chars = s.toCharArray();
        dp = new boolean[length][length];
        List<String> list = new ArrayList<>();
        dfs(0,list);
        return ans;
    }
    // 子字符串是否是回文串,使用动态规划判断
    public boolean isPalindrome(int startIndex,int endIndex){
        if(startIndex >= endIndex) return true;
        boolean result = chars[startIndex] == chars[endIndex] && isPalindrome(startIndex+1,endIndex-1);
        dp[startIndex][endIndex] = result;
        return result;
    }
    // 从下标为startIndex处进行dfs搜索
    public void dfs(int startIndex,List<String> list){
        for(int i = startIndex;i<chars.length;i++){
            if(isPalindrome(startIndex,i)){
                List<String> copy = new ArrayList<>(list);
                copy.add(new String(chars,startIndex,i-startIndex+1));
                if(i == chars.length-1) ans.add(copy);
                else dfs(i+1,copy);
            }
        }
    }
}

原创文章,作者:彭晨涛,如若转载,请注明出处:https://www.codetool.top/article/leetcode131-%e5%88%86%e5%89%b2%e5%9b%9e%e6%96%87%e4%b8%b2/

(0)
彭晨涛彭晨涛管理者
上一篇 2020年5月21日 15:59
下一篇 2020年5月22日

相关推荐

  • leetcode403-青蛙过河

    原题 一只青蛙想要过河。 假定河流被等分为 x 个单元格,并且在每一个单元格内都有可能放有一石子(也有可能没有)。 青蛙可以跳上石头,但是不可以跳入水中。 给定石子的位置列表(用单…

    算法 2020年6月16日
    04710
  • leetcode341-扁平化嵌套列表迭代器

    原题 给定一个嵌套的整型列表。设计一个迭代器,使其能够遍历这个整型列表中的所有整数。 列表中的项或者为一个整数,或者是另一个列表。 示例1: 输入: [[1,1],2,[1,1]]…

    算法 2020年1月27日
    050
  • leetcode983-最低票价

    原题 在一个火车旅行很受欢迎的国度,你提前一年计划了一些火车旅行。在接下来的一年里,你要旅行的日子将以一个名为 days 的数组给出。每一项是一个从 1 到 365 的整数。 火车…

    算法 2020年5月6日
    0120
  • leetcode1115-交替打印FooBar

    原题 我们提供一个类: class FooBar { public void foo() {     for (int i = 0; i < n; i++) {       …

    算法 2020年2月2日
    0180
  • 剑指offer50-第一个只出现一次的字符

    原题(来源Leetcode) 在字符串 s 中找出第一个只出现一次的字符。如果没有,返回一个单空格。 s 只包含小写字母。 示例: s = "abaccdeff" 返回 "b" s…

    算法 2020年6月10日
    0180
  • leetcode300-最长上升子序列

    原题 给定一个无序的整数数组,找到其中最长上升子序列的长度。 示例: 输入: [10,9,2,5,3,7,101,18] 输出: 4 解释: 最长的上升子序列是 [2,3,7,10…

    算法 2020年3月14日
    0280
  • leetcode35-搜索插入位置

    原题 给定一个排序数组和一个目标值,在数组中找到目标值,并返回其索引。如果目标值不存在于数组中,返回它将会被按顺序插入的位置。 你可以假设数组中无重复元素。 示例 1: 输入: […

    算法 2020年3月2日
    0130
  • leetcode23-合并K个排序链表

    原题 合并 k 个排序链表,返回合并后的排序链表。请分析和描述算法的复杂度。 示例: 输入: [ 1->4->5, 1->3->4, 2->6 ] 输出: 1->1->2->3->…

    算法 2020年2月4日
    0170
  • leetcode4-寻找两个有序数组的中位数

    这道题我没想出符合条件的思路 原题 给定两个大小为 m 和 n 的有序数组 nums1 和 nums2。 请你找出这两个有序数组的中位数,并且要求算法的时间复杂度为 O(log(m…

    算法 2020年1月9日
    0620
  • leetcode45-跳跃游戏II

    原题 原题 给定一个非负整数数组,你最初位于数组的第一个位置。 数组中的每个元素代表你在该位置可以跳跃的最大长度。 你的目标是使用最少的跳跃次数到达数组的最后一个位置。 示例: 输…

    算法 2020年2月15日
    0150

发表回复

登录后才能评论