DP入门(一)

news2025/1/10 12:16:08

前言:由于作者经常卡力扣周赛最后一题的dp,因此决定痛改前非,从头做人,争取下次能做出最后一道dp ak周赛!呜呜呜加油~~ 因此 这个系列的文章不会教 dp ,只会讲刷题思路,目前的计划是先更 lc 的题目,如果有时间也会做其他的 dp 问题

ps: 有些问题的最佳解决方式并非是 dp 思路,反之,这些题目的dp十分麻烦,这里直接给出简单解法!

目录

5、最长回文子串

10、正则表达式匹配

22、括号生成

32、最长有效括号

42、接雨水

44、通配符匹配


5、最长回文子串

思路:这题通常的解法是用中心扩展法来解决,代码也比较简单,大家可以自行学习,这里仅仅介绍 dp 解法,f[i][j] 表示 i 到 j 是不是回文子串,转移的话, 就是 i 的字符 == j 的字符 并且 他们中间的字符串也要是 回文的(f[i + 1] [j - 1] == true || 长度 <= 3)dp 的顺序要按照拓扑序,所以我们必须先便利j,这样 我们的 f[i + 1][j - 1] 才是已经计算过的值 

class Solution {
    public String longestPalindrome(String s) {
        int n = s.length();
        boolean[][] f = new boolean[n][n];
        String res = "";
        for (int j = 0; j < n; j ++) {
            for (int i = 0; i <= j; i ++) {
                if (i == j) f[i][j] = true;
                else if (s.charAt(i) == s.charAt(j)) {
                    if (j - i + 1 <= 3 || f[i + 1][j - 1]) f[i][j] = true; // 长度小于3也是 true
                }
                if (f[i][j] == true && j - i + 1 > res.length()) res = s.substring(i,j + 1);
            }
        }
        return res;
    }
}

10、正则表达式匹配

思路:

状态表示:f[i][j]表示p从j开始到结尾,是否能匹配s从i开始到结尾
状态转移:

如果p[j+1]不是通配符'*',则f[i][j]是真,当且仅当s[i]可以和p[j]匹配,且f[i+1][j+1]是真;
如果p[j+1]是通配符'*',则下面的情况只要有一种满足,f[i][j]就是真;
f[i][j+2]是真;
s[i]可以和p[j]匹配,且f[i+1][j]是真;
第1种情况下的状态转移很好理解,那第2种情况下的状态转移怎么理解呢?

最直观的转移方式是这样的:枚举通配符'*'可以匹配多少个p[j],只要有一种情况可以匹配,则f[i][j]就是真;
这样做的话,我们发现,f[i][j]除了枚举0个p[j]之外,其余的枚举操作都包含在f[i+1][j]中了,所以我们只需判断
f[i+1][j]是否为真,以及s[i]是否可以和p[j]匹配即可。

时间复杂度分析:n 表示s的长度,m 表示p的长度,总共 nm 个状态,状态转移复杂度 O(1),所以总时间复杂度是 O(nm)

class Solution {
    public boolean isMatch(String s, String p) {
        int n = s.length();
        int m = p.length();
        s = " " + s;
        p = " " + p;
        boolean[][] f = new boolean[n + 1][m + 1];
        f[0][0] = true;
        for (int i = 0; i <= n; i ++) {
            for (int j = 1; j <= m; j ++) {
                if (j + 1 <= m && p.charAt(j + 1) == '*') continue;
                if (p.charAt(j) != '*') {
                    if (i > 0) f[i][j] = f[i - 1][j - 1] && (s.charAt(i) == p.charAt(j) || p.charAt(j) == '.');
                } else {
                    f[i][j] = f[i][j - 2] || i != 0 && f[i - 1][j] && (s.charAt(i) == p.charAt(j - 1) || p.charAt(j - 1) == '.');
                }
            }
        }
        return f[n][m];
    }
}

22、括号生成

 思路:

1、dfs(int n,int l,int r,String s):n表示最多有n个左括号和右括号,l表示左括号的个数,r表示右括号的个数,s表示当前的序列
2、若l < n,左括号的个数小于n,则可以在当前序列后面拼接左括号
3、若r < l,右括号的个数小于左括号的个数,则可以在当前序列后面拼接右括号

class Solution {
    List<String> res;
    public List<String> generateParenthesis(int n) {
        res = new ArrayList<>();
        dfs(n,0,0,"");
        return res;
    }

    public void dfs(int n,int lc,int rc,String path) {
        if (lc == n && rc == n) res.add(path);
        if (lc < n) dfs(n,lc + 1,rc, path + '(');
        if (rc < lc) dfs(n,lc,rc + 1, path + ')');
    }
}

 dp ? 压根不需要好吧!

32、最长有效括号

 

思路:

1、若当前元素是'(',则直接加入栈中
2、当当前元素是')'时,说明和栈顶元素有可能匹配
        1、若栈顶元素能和')'匹配,直接将栈顶元素pop出,则当前元素i与pop元素后的栈顶元素之间的长度是以i结尾的最长有效括号的长度
        2、若栈顶元素不能和')'匹配,则直接计算
注意:栈保存的是坐标(并且栈里存的只有左括号)

class Solution {
    public int longestValidParentheses(String s) {
        Stack<Integer> stk = new Stack();
        char[] arr = s.toCharArray();
        int res = 0;
        for (int i = 0,last = -1; i < arr.length; i ++) {
            if (arr[i] == '(') stk.push(i);
            else {
                if (stk.size() > 0) {
                    stk.pop();
                    if (stk.size() > 0) {
                        res = Math.max(res,i - stk.peek());
                    } else {
                        res = Math.max(res, i - last);
                    }
                }
                else {
                    last = i;
                }
            }
        }
        return res;
    }
}

42、接雨水

 思路:

对于数组中每个点,水有多高取决于这个点左侧和右侧墙壁的最大高度。第一个for循环找每个点的左侧最大高度,第二个for循环找每个点右侧的最大高度,循环中跳过最左侧(i=0)和最右侧点(i=nums.size()-1)的原因是这两个点由于没有左侧墙壁或右侧墙壁所以最大墙壁高度肯定是0,故在初始化nums的时候已经将其默认设置成0了。在得到所有点的左右墙壁最大高度后,木桶原理取左右墙壁较低的那个高度减去当前位置墙壁作为地面的高度就得到了这个位置上水的高度。然后将所有点的水高度相加即为解。

class Solution {
    public int trap(int[] height) {
        int n = height.length;
        int[] l = new int[n];
        int[] r = new int[n];
        l[0] = height[0];
        l[n - 1] = height[n - 1];
        r[0] = height[0];
        r[n - 1] = height[n - 1];
        for (int i = 1; i < n - 1; i ++) l[i] = Math.max(l[i - 1],height[i]);
        for (int i = n - 2; i >= 1; i --) r[i] = Math.max(r[i + 1],height[i]);
        int res = 0;
        for (int i = 0; i < n; i ++) {
            res += Math.min(l[i],r[i]) - height[i];
        }
        return res;
    }
}

44、通配符匹配

 

class Solution {
    public boolean isMatch(String s, String p) {
        int n = s.length();
        int m = p.length();
        s = " " + s;
        p = " " + p;
        boolean[][] f = new boolean[n + 1][m + 1];
        f[0][0] = true;
        for (int i = 0; i <= n; i ++) {
            for (int j = 1; j <= m; j ++) {
               if (p.charAt(j) != '*') f[i][j] = i != 0 && f[i - 1][j - 1] && (s.charAt(i) == p.charAt(j) || p.charAt(j) == '?');
               else {
                   f[i][j] = f[i][j - 1] || i != 0 && f[i - 1][j];
               } 
            }
        }
        return f[n][m];
    }
}

由于博主水平有限,分享之中不乏出现一些错误,欢迎大家指出讨论,我也会一一改进~~

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/21646.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

[Spring Cloud] RestTemplate跨进程调用

✨✨个人主页:沫洺的主页 &#x1f4da;&#x1f4da;系列专栏: &#x1f4d6; JavaWeb专栏&#x1f4d6; JavaSE专栏 &#x1f4d6; Java基础专栏&#x1f4d6;vue3专栏 &#x1f4d6;MyBatis专栏&#x1f4d6;Spring专栏&#x1f4d6;SpringMVC专栏&#x1f4d6;SpringBoot专…

【k8s】5、资源管理命令-声明式

文章目录一、 yaml和json介绍1、yuml语言介绍2、k8s支持的文件格式3、yaml和json的主要区别二、声明式对象管理1、命令式对象配置2、声明式对象配置3、声明式对象管理命令介绍三、编写资源配置清单1、 编写yaml文件2、 启动并查看资源3、创建service服务对外提供访问测试4、创建…

MySQL介绍

MySQL数据库最初是由瑞典MySQL AB公司开发&#xff0c;2008年1月16号被Sun公司收购。2009年&#xff0c;SUN又被Oracle收购。MySQL是目前IT行业最流行的开放源代码的数据库管理系统&#xff0c;同时它也是一个支持多线程高并发多用户的关系型数据库管理系统。MySQL之所以受到业…

基于51单片机的舞蹈机器人四路步进电机控制仿真

资料编号&#xff1a;091 下面是相关功能视频演示&#xff1a; 91-基于51单片机的舞蹈机器人四路步进电机控制仿真&#xff08;源码仿真全套资料&#xff09;功能介绍&#xff1a;通过51单片机控制4个步进电机旋转&#xff0c;模拟出机器人的四肢动作&#xff0c;全套资料齐全…

ES6 入门教程 17 Promise 对象 17.2 基本用法

ES6 入门教程 ECMAScript 6 入门 作者&#xff1a;阮一峰 本文仅用于学习记录&#xff0c;不存在任何商业用途&#xff0c;如侵删 文章目录ES6 入门教程17 Promise 对象17.2 基本用法17 Promise 对象 17.2 基本用法 ES6 规定&#xff0c;Promise对象是一个构造函数&#xff0…

【Java高级】一篇文章带你搞懂线程

目录 | 线程概述 | 线程创建 方式一&#xff1a;继承 Thread 类 方式二&#xff1a;实现 Runnable 接口 一些小细节 方式三&#xff1a;实现 Callable 接口&#xff08;JDK1.8&#xff09; | 线程生命周期 生命周期概述 [获取线程信息] 方法 set/getName current [运…

ArcGIS绘制北半球俯视投影地图

做全球碳水循环,植被变化,极端气候相关研究的同学都知道。北半球是核心,因为北半球的核心区域(东亚湿润区,中亚干旱半干旱,青藏高原,阿拉伯半岛,非洲北部沙漠以及美国西部等等核心区): 对于北半球的展示一般采用下面的图: 那么该如何做呢? 熟悉地图学的同学都知道…

Dubbo-聊聊Dubbo协议

前言 Dubbo源码阅读分享系列文章&#xff0c;欢迎大家关注点赞 SPI实现部分 Dubbo-SPI机制 Dubbo-Adaptive实现原理 Dubbo-Activate实现原理 Dubbo SPI-Wrapper 注册中心 Dubbo-聊聊注册中心的设计 Dubbo-时间轮设计 通信 Dubbo-聊聊通信模块设计 什么是协议 在网络交…

【FreeRTOS】FreeRTOS删除任务vTaskDelete()

使用说明&#xff1a; 任务中。小时 &#xff08;任务句柄_t xTask&#xff09;; INCLUDE_vTaskDelete必须定义为1&#xff0c;才能使用此函数。有关更多信息&#xff0c;请参见RTOS配置文档。 从RTOS内核管理中删除任务。正在删除的任务将从所有就绪、阻止、暂停和事件列表中删…

CEAC 之《计算机应用助理工程师》1

&#x1f468;‍&#x1f4bb;个人主页&#xff1a;微微的猪食小窝 欢迎 点赞&#x1f44d; 收藏⭐ 留言&#x1f4dd; 加关注✅! 本文由 微微的猪食小窝 原创 收录于专栏 【CEAC证书】 1组合框有3种不同的类型&#xff0c;这3种类型是下拉式组合框、简单组合框、下拉式列表框&…

12. PyQt5实现多页面切换之QTabBar

PyQt5 QTabBar 类 QTabBar 类直接继承自 QWidget。该类提供了一个选项卡栏&#xff0c;该类仅提供了一个选项卡&#xff0c; 并没有为每个选项卡提供相应的页面&#xff0c;因此要使选项卡栏实际可用&#xff0c;需要自行为每个选项 卡设置需要显示的页面&#xff0c;可以通过 …

【k8s】6、pod详解

文章目录一、pod介绍1、pod的基础概念2、pod定义&#xff08;资源清单&#xff09;二、Pod中的容器配置1、基本配置2、镜像拉取&#xff08;imagePullPolicy&#xff09;3、启动命令&#xff08;command&#xff09;4、环境变量&#xff08;env&#xff09;5、端口设置&#xf…

应急响应-计划任务排查

计划任务排查 由于很多计算机都会自动加载“计划任务”&#xff0c;“计划任务”也是恶意病毒实现持久化驻留的一种常用手段&#xff0c;因此在应急响应事件排查时需要进行排查。通俗的讲会定期执行某些操作。 Windows计划任务排查 任务计划是Windows系统的一个预置实现某些…

【数据结构】二叉树的顺序存储结构 —— 堆

文章目录前言二叉树的顺序存储堆的概念和结构堆的实现结构的定义接口总览初始化销毁插入向上调整删除向下调整取堆顶数据计算堆大小判空打印堆完整代码Heap.hHeap.ctest.c结语前言 今天&#xff0c;我们开始二叉树的学习。本篇博客的内容为 介绍二叉树的顺序存储 和 堆的实现。…

【滤波跟踪】基于matlab不变扩展卡尔曼滤波器对装有惯性导航系统和全球定位系统IMU+GPS进行滤波跟踪【含Matlab源码 2232期】

⛄一、简介 针对室内定位中的非视距&#xff08;Non-Line-of-Sight,NLOS&#xff09;现象,提出一个新型算法进行识别,同时有效缓解其影响.主要通过超宽带&#xff08;Ultra-Wideband,UWB&#xff09;定位系统与惯性导航系统&#xff08;Inertial Navigation System,INS&#x…

酒店管理系统的设计与实现

Word下载链接如下&#xff1a; https://download.csdn.net/download/yw1990128/87096359 一 设计背景 1.1 课题现状 随着国家社会经济水平的提升&#xff0c;各酒店的发展速度越来越快&#xff0c;入住人员也越来越多。酒店房间的管理要求也愈来愈大&#xff0c;所以很多酒店正…

45.Django模板

1.django模板配置 1.1 Django模板概述 作为一个Web框架&#xff0c;Django需要一种方便的方式来动态生成HTML。最常用的方法依赖于模板。模板包含所需HTML输出的静态部分以及描述如何插入动态内容的特殊语法。 ​ 对模板引擎的一般支持和Django模板语言的实现都存在于 djang…

Linux下的NFS服务(包含windows10下的nfs搭建)

目录 1.NFS服务介绍 2.Linux下搭建NFS服务 &#xff08;1&#xff09;下载NFS服务端 &#xff08;2&#xff09;新建一个共享文件 &#xff08;3&#xff09;修改NFS服务配置文件 &#xff08;4&#xff09;重新启动NFS服务 &#xff08;5&#xff09;显示查看共享的文件…

38、常用类之String类

1、基本介绍&#xff1a; String s5new String(byte[] b)&#xff1b; &#xff08;5&#xff09;String实现了Serializable&#xff0c;说明String可以串行化&#xff0c;即可以网络传输 String实现了Comparable&#xff0c;说明String对象可以比较 &#xff08;6&#xff0…

JavaScript基础(13)_原型、原型对象

上一章构造函数确实简化了多个对象创建的麻烦问题&#xff0c;但是&#xff1a;构造函数每创建一个实例&#xff0c;构造函数就会执行一次&#xff0c;将属性和方法添加到该对象&#xff0c;每个对象实例化后地址互不相同&#xff0c;即使它们的方法所实现的逻辑和功能一样&…