LeetCode 热题 HOT 100 -------70. 爬楼梯 (动态规划) 、279. 完全平方数(动态规划)、5. 最长回文子串(动态规划)

在这里插入图片描述

//动态规划:转移方程:dp[n] = dp[n-1] + dp[n-2] 初始化:dp[0] =1 , dp[1] =1;

class Solution {
    public int climbStairs(int n) {
        
        int[] dp = new int[n+1];

        dp[0]=dp[1]=1;
        
        for(int i=2 ; i<n+1; i++){
            
            dp[i] = dp[i-1] + dp[i-2]; 
        }
        return dp[n];
    }
}

在这里插入图片描述

//动态规划:典型思想,我们一定要注意动态规划的思想,就是先看成一个一个的小问题,然后每一个小问题都找到一个最优解,然后再此基础上得出最后解
//首先这个基础解,我们要求的是n的由完全平方得到的最小值,此时我们应该找0~n-1的最优解,然后在此基础上得到n的最优解
class Solution {
    public int numSquares(int n) {
        //首先我们用数组表示,数组最后的下标为n,里面相应出的值为结果,也就是最后要返回res[n];
        int[] res = new int[n+1];
        //根据动态规划思想,我们找出每一个小问题的最优解,也就是0~n-1,0的时候自然res[0]=0
        for(int i=1 ; i<=n ; i++){
            //每个小问题的“最差的解”也就是由1*1组成,也就是
            res[i] = i ;
            //然后我们找当前值的“最优解”,(一定要注意动态规划思想,此时j是要找到的临界值,其实也就是小于i的最大的方法值,然后i-j*j后得到的数值是我们之前小问题已经求得的最优解)
            for(int j=1 ; i-j*j>=0; j++){
                res[i] = Math.min(res[i],res[i-j*j]+1);
            }
        }
    return res[n];
    }
}

在这里插入图片描述

//思路:(动态规划)首先我们考虑的是动态规划,其实一个回文子串,那么去了它的首尾段也是回文子串,所以我们分成一个一个小问题,
//比如说“一个字母”一定是回文子串,如果他的首尾是相同的字母那么他也是一个回文子串,以此类推,因此我们去找动态规划的状态转移方程以及边界条件

//状态转移方程:S(i,j) = S(i+1.j-1) && Si==Sj ,并且
//边界条件:长度为1时,一定是一个回文子串,2时,两个值相等一定是一个回文子串
class Solution {
    public String longestPalindrome(String s) {
        //记录回文子串得长度,以及开始位置
        int maxLen = 1;
        int begin = 0;
        //首先得到字符串的长度
        int len = s.length();

        //当长度小于为0,1时那一定是回文子串
        if(len<2){
            return s;
        }

        //创造dp[],一般动态规划我们可以用一个二维数组表示
        boolean[][] dp = new boolean[len][len];

        //因为1个长度一定是回文子串,则[i][i]=true
        for(int i=0 ; i<len ; i++){
            dp[i][i] = true;
        }

        //我们将字符串变为数组,方便根据下标找值
        char[] charArray = s.toCharArray();

        //我们开始递推,因为我们找的回文子串长度是大于1的,所以我们从2开始遍历,最长是字符串的长度
        for(int L=2 ; L <= len ; L++){

            //我们要枚举子串长度
            for(int i=0 ; i<len ; i++){

                //当我们从第i个字母开始,并且长度为L,则尾字母应该是j,且满足j-i+1 = L.得
                int j = L + i - 1;
                //但是如果此时j超过了字符串长度,就退出当前循环
                if(j>=len){
                    break;
                }
                //解下来我们就看长度为L得有没有回文子串(看的其实就是首尾)
                if(charArray[i]!=charArray[j]){
                    dp[i][j] =false;
                }else{
                 //说明相等,当长度为1时,一定是回文子串,前面已经dp[i][i]=true来表示,
                 //当为2时,不能通过 dp[i][j] = dp[i+1][j-1]来判断,只能直接设定
                    if(j-i<2){
                        dp[i][j] = true;
                    }else{
                        dp[i][j] = dp[i+1][j-1];
                    }
                }
                //此时我们找出了i,j,判断dp[i][j]是否为true,并且为长度只要大于1我们就记录
                if(dp[i][j]&&j-i+1>maxLen){
                    maxLen = L;
                    begin =i;
                }
            }
        }
        return s.substring(begin,begin+maxLen); 
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值