LeetCode05

简介: 版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/sinat_32502811/article/details/81563189 最近在刷题,对于动态规划类的问题完全懵逼····就从LeetCode上找DP的题目专门练习一下,熟悉熟悉思路。
版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/sinat_32502811/article/details/81563189

最近在刷题,对于动态规划类的问题完全懵逼····就从LeetCode上找DP的题目专门练习一下,熟悉熟悉思路。
这里还有一个动态规划背包问题的比较好的资源,请戳这里.

LeetCode05

Given a string s, find the longest palindromic substring in s. You may assume that the maximum length of s is 1000.


Example 1:
Input: “babad”
Output: “bab”
Note: “aba” is also a valid answer.

貌似字符串问题中,有好多都是动态规划类问题,比如经典的最大相同子串,以及这道最长回文子串。
最开始,我想到的思路是:类似最大相同子串的方法,对于二维数组dp[i][j],i用字符串的正序,j用字符串的倒序,如果str[i] == str[j] 并且dp[i - 1] [j - 1] 不为0的话,则最长回文子串长度就是dp[i-1]+dp[j-1],对于题目提供的样例,这个方法做出来是对的,但是在测评的时候,有一个样例,“abcefcba”就不对。
所以这种思路被抛弃。
结合在discussion部分看到别人的代码,思路是这样的。dp数组为boolean类型,代表从i 到 j位置的字符串是否为回文。如果从 j 到 i 为回文子串,那么它的子问题就是str[i]==str[j]并且由j+1 到 i- 1也是回文子串。因此状态转移方程就为:

dp[i][j]=truetruefalse,ifdp[j+1][i1]=trueandstr[i]==str[j],ij<=2andstr[i]==str[j],elsedp[i][j]={true,ifdp[j+1][i−1]=trueandstr[i]==str[j]true,i−j<=2andstr[i]==str[j]false,else

代码如下:

class Solution {
    public String longestPalindrome(String s) {
        int len = s.length();
        boolean[][] dp = new boolean[len][len];
        int max = 0;
        int start = 0;
        int end = 0;
        for(int i = 0; i < len; 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;
                }
                if(dp[j][i] && max < (i - j + 1)){
                    max = i - j + 1;
                    start = j;
                    end = i+1;
                }
            }
        }
        return s.substring(start, end);
    }
}
目录
相关文章
|
4月前
|
C++ Python
leetcode-283:移动零
leetcode-283:移动零
26 0
|
存储 Python
LeetCode 66. Plus One
给定表示非负整数的非空数字数组,加上整数的1。 存储数字使得最高有效数字位于列表的开头,并且数组中的每个元素包含单个数字。 您可以假设整数不包含任何前导零,除了数字0本身。
82 0
LeetCode 66. Plus One
|
算法 Java
一和零(LeetCode 474)
一和零(LeetCode 474)
87 0
leetcode第39题
对回溯法又有了更深的了解,一般的架构就是一个大的 for 循环,然后先 add,接着利用递归进行向前遍历,然后再 remove ,继续循环。而解法二的动态规划就是一定要找到递进的规则,开始的时候就想偏了,导致迟迟想不出来。
leetcode第39题
leetcode第34题
从左向右遍历,一旦出现等于 target 的值就结束,保存当前下标。如果从左到右没有找到 target,那么就直接返回 [ -1 , -1 ] 就可以了,因为从左到右没找到,那么从右到左也一定不会找到的。如果找到了,然后再从右到左遍历,一旦出现等于 target 的值就结束,保存当前下标。 时间复杂度是 O(n)并不满足题意,但可以了解下这个思路,从左到右,从右到左之前也遇到过。
leetcode第34题
leetcode第54题
在 leetcode 的 solution 和 discuss 看了下,基本就是这个思路了,只是实现上有些不同,怎么用来标记是否走过,当前方向,怎么遍历,实现有些不同,但本质上是一样的。就是充分理解题意,然后模仿遍历的过程。
leetcode第54题
leetcode第36题
一个 9 * 9 的数独的棋盘。判断已经写入数字的棋盘是不是合法。需要满足下边三点, • 每一行的数字不能重复 • 每一列的数字不能重复 • 9 个 3 * 3 的小棋盘中的数字也不能重复。 只能是 1 - 9 中的数字,不需要考虑数独最后能不能填满
leetcode第36题
leetcode第46题
这是自己开始想到的一个方法,考虑的思路是,先考虑小问题怎么解决,然后再利用小问题去解决大问题。没错,就是递归的思路。比如说, 如果只有 1 个数字 [ 1 ],那么很简单,直接返回 [ [ 1 ] ] 就 OK 了。 如果加了 1 个数字 2, [ 1 2 ] 该怎么办呢?我们只需要在上边的情况里,在 1 的空隙,也就是左边右边插入 2 就够了。变成 [ [ 2 1 ], [ 1 2 ] ]。
leetcode第46题
|
算法
leetcode第30题
如上图,利用循环变量 i ,依次后移,判断每个子串是否符合即可。 怎么判断子串是否符合?这也是这个题的难点了,由于子串包含的单词顺序并不需要固定,如果是两个单词 A,B,我们只需要判断子串是否是 AB 或者 BA 即可。如果是三个单词 A,B,C 也还好,只需要判断子串是否是 ABC,或者 ACB,BAC,BCA,CAB,CBA 就可以了,但如果更多单词呢?那就崩溃了。 链接)的作者提出了,用两个 HashMap 来解决。首先,我们把所有的单词存到 HashMap 里,key 直接存单词,value 存单词出现的个数(因为给出的单词可能会有重复的,所以可能是 1 或 2 或者其他)。然后扫描子
115 0
leetcode第30题
|
存储 算法 Java
leetcode第29题
这道题看起来简单,却藏了不少坑。首先,我们用一次一次减造成了超时,然后我们用递归实现了加倍加倍的减,接着由于 int 表示的数的范围不是对称的,最小的负数并不能转换为对应的相反数,所以我们将之前的算法思路完全逆过来,正数边负数,大于变小于,还是蛮有意思的。
leetcode第29题