力扣刷题Day5——内涵动态规划讲解

题目1:

先来一道很简单的题目:

2697. 字典序最小回文串 - 力扣(LeetCode)

思路:

为了得到字典序最小的回文字符串,对于回文串,就是需要左右的字符相等,而要最小的回文串,就需要判断,在对称位置下,哪一个字母是字典序最小的,就把另一个赋值和它一样的字母,这样就可以实现这道题目了。

代码:

char * makeSmallestPalindrome(char * s){
    int l=strlen(s);
    int a=0;
    int b=l-1;
    while(a<b){
        if(s[a]<s[b])
        {
            s[b--]=s[a++];
        }else{
            s[a++]=s[b--];
        }
    }
    return s;
}

题目2:

746. 使用最小花费爬楼梯 - 力扣(LeetCode)

这道题比上面的要难一点,主要涉及的知识点就是——动态规划

那首先这里就来介绍一下什么是动态规划,这样的题目该怎么做?

动态规划讲解:

1.什么是动态规划?

动态规划是解决计算机中最优化问题的方法——通过避免重复计算来实现优化,利用哈希表等来保存中间的计算结果——所以也称为记忆化搜索——所以动态规划其实是空间换取时间

2.怎么实现动态规划?

1)首先把所有可能暴力的列举出来,并画出递归树

2)尝试写一个递归函数求解

3)  如果发现有大量的重复计算,可以用字典、哈希表来存储

4)改写成迭代的形式

概括一下就是——

1.穷举法/暴力搜索列举

2.记忆化搜索

3.改写成迭代的形式

这样看其实还是不好理解,那下面来利用今天这道题来分析一下——

思路: 

首先对于这道上楼梯的题目,设cost数组长度为n,则一共有n+1个台阶

假设数组大小为9,则数组是0到8,但是顶层是9

1. 一般先要分析成递归的形式——从开头看,或者是从结尾看比较容易

这里从最后一个元素看吧——

        1)如果最后一个元素到顶需要2步,则在7上顶层

        2)如果最后一个到顶需要1步,则在8上顶层

这时候发现,这个从最后一个台阶到顶部的问题其实和这个本来的题目的问题很像,不过是变小了,那么这时候就可以进行第二步了

(⭐注:动态规划有「选或不选」「枚举选哪个」这两种基本思考方式。本题目用到的是「枚举选哪个」的方式思考)

2. 定义数组元素的含义

既然动态规划是为了减少重复计算的,那么需要一个空间来存储其计算过的元素,所以这里要定义一下这个记忆数组到底要存储什么?

——怎么分析呢?

这个就是和题目结合起来就OK——题目是什么?使用最小花费来上顶层,

因为要解决的问题都是「从 0 或 1 爬到 i」,所以定义 a(i) 表示从 0 或 1 爬到 i 的最小花费。

3. 步骤1和2结合起来,来分析清楚如何实现递归,明白数组元素之间的联系,缩小问题

还是按照步骤1分析的情况来分析——上最后一个台阶,要么上1个要么上2个到顶层

那么如果上1层到顶层,那就是要知道0或者1到n-1层的最小花费a[n-1],再加上从n-1到n的花费

a[n]=a[n-1]+cost[n-1]

那么如果上2层到顶层,那就是要知道0或者1到n-2层的最小花费a[n-2],再加上从n-2到n的花费

a[n]=a[n-2]+cost[n-2]

两种情况取最小值就可以算出到顶层的最小花费了,这里推广到普通的楼层——上到第i层求最小花费也是一样的方法。

a[i]=min(a[i-1]+cost[i-1],a[i-2]+cost[i-2])

4.定义递归边界和入口

递归边界:a(0)=0, a(1)=0;

爬到 0 或 1 不需要花费,因为我们一开始在 0 或 1。

递归入口:dfs(n),也就是答案

5.确定递归顺序

因为是模拟台阶,而且a[i]又a[i-1]和a[i-2]中推出,所以是从前到后遍历cost数组就🆗

代码:

使用c++和c来编写程序:

代码1.

int min(a,b)
{
    if(a>b)
    {
        return b;
    }else
    {
        return a;
    }
}
int minCostClimbingStairs(int* cost, int costSize) {
    int a[costSize+1];
    a[0]=a[1]=0;
    int i;
    for(i=2;i<=costSize;i++)
    {
        a[i]=min(a[i-1]+cost[i-1],a[i-2]+cost[i-2]);
    }
    return a[costSize];
} 

代码2.

class Solution {
public:
    int minCostClimbingStairs(vector<int>& cost) {
        int n=cost.size();
        vector<int> a(n+1);
        a[0]=a[1]=0;
        int i=2;
        for(;i<=n;i++)
        {
            a[i]=min(a[i-1]+cost[i-1],a[i-2]+cost[i-2]);
        }
        return a[n];
    }
};

总结:

这里的动态规划其实还是要多加练习,自己分析分析,再结合案例多看看别人怎么做的,再自己独立完成,下面可以在力扣里搜索动态规划的题自行练习。

搜索 - 力扣(LeetCode)

  • 15
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值