算法【Java】—— 动态规划之回文串问题

回文子串

https://leetcode.cn/problems/palindromic-substrings

在这里插入图片描述


我们可以使用二维的 dp 表记录所有的子串情况,dp[i][j] 表示 以 i 起始,j 结尾的子串是否是回文串

状态转移方程推导:回文串要求开头和结尾的两个元素必须是相同的,即当 s[i] == s[j] 的时候,才有机会成为回文串,然后如果 i == j 那说明这是一个字符,一个字符可以构成回文串,赋值 true,如果 i + 1 == j 说明是两个相邻的字符,也是回文串赋值为true,最后就是 i + 1 < j 的时候,我们还要判断 i+1 到 j-1 是不是回文串,是的话整个字符串都是回文串,不是的话整个子串都不是回文串,即 dp[i][j] = dp[i+1][j-1]

填表顺序,由于需要用到 dp[i+1][j-1] 的数值,需要从下到上填表

class Solution {
    public int countSubstrings(String s) {
        int n = s.length();
        boolean[][] dp = new boolean[n][n];
        int ret = 0;
        for(int i = n - 1; i >= 0; i--) {
            for(int j = i; j < n; j++) {
                if(s.charAt(i) == s.charAt(j)) {
                    if(i == j || i + 1 == j) {
                        dp[i][j] = true;
                    } else {
                        dp[i][j] = dp[i+1][j-1];
                    }
                }
                if(dp[i][j]) {
                    ret++;
                }
            }
        }
        return ret;
    }
}

最长回文子串

https://leetcode.cn/problems/longest-palindromic-substring

在这里插入图片描述


dp[i][j] 表示 i 起始,j 结束的回文子串最大长度,如果不是回文串那么长度为 0

class Solution {
    public String longestPalindrome(String s) {
        int n = s.length();
        int[][] dp = new int[n][n];
        int len = 0;
        int start = 0;
        for(int i = n-1; i >= 0; i--) {
            for(int j = i; j < n; j++) {
                if(s.charAt(i) == s.charAt(j)) {
                    if(i == j) {
                        dp[i][j] = 1;
                    } else if(i + 1 == j) {
                        dp[i][j] = 2;
                    } else if(dp[i+1][j-1] != 0) {
                        dp[i][j] = dp[i+1][j-1] + 2;
                    }
                }
                if(len < dp[i][j]) {
                    len = dp[i][j];
                    start = i;
                }
            }
        }
        return s.substring(start, start + len);
    }
}

分割回文串 Ⅳ

https://leetcode.cn/problems/palindrome-partitioning-iv

在这里插入图片描述


我们可以使用 boolean 类型的 dp 表保存所有子串是否是回文串的信息

题目要求该字符串能否被划分为三个子串,我们可以利用二层循环,0 ~ i 为第一个字符串,i +1 ~ j 为第二个字符串,j + 1 ~ n - 1为第三个字符串,即 dp[0][i] && dp[i+1][j] && dp[j+1][n-1] 为 true 的时候直接返回 true

class Solution {
    public boolean checkPartitioning(String s) {
        int n = s.length();
        boolean[][] dp = new boolean[n][n];
        for(int i = n - 1; i >= 0; i--) {
            for(int j = i; j < n; j++) {
                if(s.charAt(i) == s.charAt(j)) {
                    if(i == j || i + 1 == j) {
                        dp[i][j] = true;
                    } else {
                        dp[i][j] = dp[i+1][j-1];
                    }
                }
            }
        }         
        for(int i = 0; i < n-1; i++) {
            for(int j = i+1; j < n-1; j++) {
                if(dp[0][i] && dp[i+1][j] && dp[j+1][n-1]) {
                    return true;
                }
            }
        }
        return false;
    }
}

分割回文串 Ⅱ

https://leetcode.cn/problems/palindrome-partitioning-ii

在这里插入图片描述


我们先通过 boolean[][] dp 来 获取字符串所有子串是否为回文串的信息

接着我们再定义一个状态表 f,f[i] 表示 0 ~ i 这个字符串最少分割次数
填表过程中要同时使用两张表的信息,当 dp[0][i] == true,说明 0 - i 这个字符串本身就是一个回文串,不需要分割,赋值为 0
如果 dp[0][i] 不是 true,那么我们要通过第二层 j 循环来判断,如果 dp[j+1][i] = true 的话,我们要看 0 - j 这个字符串最少分割次数,再 j 循环中取最小值。

class Solution {
    public int minCut(String s) {
        int n = s.length();
        boolean[][] dp = new boolean[n][n];
        for(int i = n-1; i >= 0; i--) {
            for(int j = i; j < n; j++) {
                if(s.charAt(i) == s.charAt(j)) {
                    if(i == j || i + 1 == j) {
                        dp[i][j] = true;
                    } else {
                        dp[i][j] = dp[i+1][j-1];
                    }
                }
            }
        }
        int[] f = new int[n];
        for(int i = 0; i < n; i++) {
            if(dp[0][i]) {
                f[i] = 0;
            } else {
                for(int j = i - 1; j >= 0; j--) {
                    if(dp[j+1][i]) {
                        f[i] = f[i] == 0 ? f[j] + 1 : Math.min(f[i], f[j] + 1);
                    }
                }
            }
        }
        return f[n-1];
    }
}

最长回文子序列

https://leetcode.cn/problems/longest-palindromic-subsequence

在这里插入图片描述


dp[i][j] 表示 i 到 j 这个字符串的最长回文子序列的长度

当 s[i] == s[j] 的时候,三种情况,第一种 i == j 【就是一个字符】,赋值为 1, 第二种 i + 1 == j 【相邻两个字符】,赋值为2,第三种 i + 1 < j ,说明 i 和 j 之间还要字符串,dp[i][j] = dp[i+1][j-1] + 2

如果 s[i] != s[j] 的话,需要分情况讨论,子序列包含 j 所对应的字符,则 dp[i][j] = dp[i+1][j] ,第二种就是 子序列不包含 j 所对应的字符,dp[i][j] = dp[i][j-1],二者取最大值即可

返回 dp[0][n-1],表示 0 ~ n-1 的字符串的最长子序列的长度即为题目要求。

class Solution {
    public int longestPalindromeSubseq(String s) {
        int n = s.length();
        int[][] dp = new int[n][n];
        for(int i = n - 1; i >= 0; i--) {
            for(int j = i; j < n; j++) {
                if(s.charAt(i) == s.charAt(j)) {
                    if(i == j || i + 1 == j) {
                        dp[i][j] = j - i + 1;
                    } else {
                        dp[i][j] = dp[i+1][j-1] + 2;
                    }
                } else {
                    dp[i][j] = Math.max(dp[i+1][j], dp[i][j-1]);
                }
            }
        }
        return dp[0][n-1];
    }
}

让字符串成为回文串的最少插入次数

https://leetcode.cn/problems/minimum-insertion-steps-to-make-a-string-palindrome

在这里插入图片描述


dp[i][j] 表示 i 到 j 这个字符串成为回文子串的最少插入次数

当 s[i] == s[j] 的时候,i == j 或者 i+ 1 == j 的话,说明这个字符串本身就是回文串,不需要插入字符,所以 dp[i][j] = 0,当 i + 1 < j 的时候,我们要查看 i + 1 到 j - 1 这个字符串最少插入次数,即 dp[i][j] = dp[i+1][j-1]

如果 s[i] != s[j] 的话,第一种就是插入 s[i] ,dp[i][j] = 1 + dp[i+1][j]
第二种就是插入 s[j],dp[i][j] = 1 + dp[i][j-1]

class Solution {
    public int minInsertions(String s) {
        int n = s.length();
        int[][] dp = new int[n][n];
        for(int i = n - 1; i >= 0; i--) {
            for(int j = i; j < n; j++) {
                if(s.charAt(i) == s.charAt(j)) {
                    if(i == j || i + 1 == j) {
                        dp[i][j] = 0;
                    } else {
                        dp[i][j] = dp[i+1][j-1];
                    }
                } else {
                    dp[i][j] = Math.min(dp[i+1][j], dp[i][j-1]) + 1;
                }
            }
        }
        return dp[0][n-1];
    }
}

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【Linux】从零开始:编写你的第一个Linux进度条小程序

Linux相关知识点可以通过点击以下链接进行学习一起加油&#xff01;初识指令指令进阶权限管理yum包管理与vim编辑器GCC/G编译器make与Makefile自动化构建GDB调试器与Git版本控制工具 &#x1f308;个人主页&#xff1a;是店小二呀 &#x1f308;C语言专栏&#xff1a;C语言 &am…

01_Machine Vision_LSI及傅立叶变换

outline 图像分解和线性时不变系统二维傅立叶变换图像采样 图像分解和线性时不变系统 图像数学表达 图像由基本的像素点组成&#xff0c;如果将每一个像素点看作一个脉冲&#xff0c;则每个像素点的值可以看作是脉冲的幅值&#xff0c;这样图像就可以看作是由一系列脉冲组成…

Win11下搭建Kafka环境

目录 一、环境准备 二、安装JDK 1、下载JDK 2、配置环境变量 3、验证 三、安装zookeeper 1、下载Zookeeper安装包 2、配置环境变量 3、修改配置文件zoo.cfg 4、启动Zookeeper服务 4.1 启动Zookeeper客户端验证 4.2 启动客户端 四、安装Kafka 1、下载Kafka安装包…

自动化xpath定位元素(附几款浏览器xpath插件)

在 Web 自动化测试、数据采集、前端调试中&#xff0c;XPath 仍然是不可或缺的技能。虽然 CSS 选择器越来越强大&#xff0c;但面对复杂 DOM 结构时&#xff0c;XPath 仍然更具灵活性。因此&#xff0c;掌握 XPath&#xff0c;不仅能提高自动化测试的稳定性&#xff0c;还能在爬…

尝试一下,交互式的三维计算python库,py3d

py3d是一个我开发的三维计算python库&#xff0c;目前不定期在PYPI上发版&#xff0c;可以通过pip直接安装 pip install py3d 开发这个库主要可视化是想把自己在工作中常用的三维方法汇总积累下来&#xff0c;不必每次重新造轮子。其实现成的python库也有很多&#xff0c;例如…

手机向电脑传输文件方法有哪些?

手机和电脑已经成为我们日常生活和工作中不可或缺的工具&#xff0c;而它们之间的文件传输需求也日益增加。为了帮助大家更高效地完成这一任务&#xff0c;本文将介绍三种常用的手机向电脑传输文件方法&#xff0c;方便您根据不同场景选择合适的方式。 方法1.数据线 当您有数…

【ESP32】ESP-IDF开发 | WiFi开发 | HTTP服务器

1. 简介 1.1 HTTP HTTP&#xff08;Hyper Text Transfer Protocol&#xff09;&#xff0c;全称超文本传输协议&#xff0c;用于从网络服务器传输超文本到本地浏览器的传送协议。它可以使浏览器更加高效&#xff0c;使网络传输减少。它不仅保证计算机正确快速地传输超文本文档…

生成式聊天机器人 -- 基于Pytorch + Global Attention + 双向 GRU 实现的SeqToSeq模型 -- 下

生成式聊天机器人 -- 基于Pytorch Global Attention 双向 GRU 实现的SeqToSeq模型 -- 下 训练Masked 损失单次训练过程迭代训练过程 测试贪心解码(Greedy decoding)算法实现对话函数 训练和测试模型完整代码 生成式聊天机器人 – 基于Pytorch Global Attention 双向 GRU 实…

DeepSeeek如何在Window本地部署

一、Ollama Ollama 是一个开源的本地化大语言模型&#xff08;LLM&#xff09;运行工具&#xff0c;专注于简化大模型在本地环境中的部署、管理和交互。它支持多种主流开源模型&#xff08;如 Llama 2、Mistral、Phi-2 等&#xff09;&#xff0c;并提供了命令行和 API 接口&am…

01-SDRAM控制器的设计——案例总概述

本教程重点▷▷▷ 存储器简介。 介绍 SDRAM 的工作原理。 详细讲解SDRAM 控制的Verilog 实现方法。 PLL IP和FIFO IP 的调用&#xff0c;计数器设计&#xff0c;按键边沿捕获&#xff0c;数码管控制。 完成SDRAM控制器应用的完整案例。 Signal Tap 调试方法。 准备工作▷…

实验5 配置OSPFv2验证

实验5 配置OSPFv2验证 1.实验目的 &#xff08;1&#xff09;OSPFv2 验证的类型和意义。 &#xff08;2&#xff09;配置基于区域的 OSPFv2 简单口令验证和 MD5 验证的方法。 &#xff08;3&#xff09;配置基于链路的 OSPFv2 简单口令验证和 MD5 验证的方法。 2.实验准备 配置…

Office/WPS接入DeepSeek等多个AI工具,开启办公新模式!

在现代职场中&#xff0c;Office办公套件已成为工作和学习的必备工具&#xff0c;其功能强大但复杂&#xff0c;熟练掌握需要系统的学习。为了简化操作&#xff0c;使每个人都能轻松使用各种功能&#xff0c;市场上涌现出各类办公插件。这些插件不仅提升了用户体验&#xff0c;…

基于STM32HAL库的万年历系统

目录 前言 项目分析 CubeMX配置 工程文件结构 App文件夹 Lib文件夹 库文件代码 myrtc.c myrtc.h oled库&字符库 knob.c knob.h 业务逻辑代码 task_main.c task_main.h 前言 本篇博客来做一个简易的万年历系统&#xff0c;需要用到旋转编码器和0.96寸OLED屏幕…

【Matlab优化算法-第14期】基于智能优化算法的VMD信号去噪项目实践

基于智能优化算法的VMD信号去噪项目实践 一、前言 在信号处理领域&#xff0c;噪声去除是一个关键问题&#xff0c;尤其是在处理含有高斯白噪声的复杂信号时。变分模态分解&#xff08;VMD&#xff09;作为一种新兴的信号分解方法&#xff0c;因其能够自适应地分解信号而受到…

蓝耘智算平台与DeepSeek R1模型:推动深度学习发展

公主请阅 前言何为DeepSeek R1DeepSeek R1 的特点DeepSeek R1 的应用领域DeepSeek R1 与其他模型的对比 何为蓝耘智算平台使用蓝耘智算平台深度使用DeepSeek R1代码解释&#xff1a;处理示例输入&#xff1a;输出结果&#xff1a; 前言 在深度学习领域&#xff0c;创新迭代日新…

5、大模型的记忆与缓存

文章目录 本节内容介绍记忆Mem0使用 mem0 实现长期记忆 缓存LangChain 中的缓存语义缓存 本节内容介绍 本节主要介绍大模型的缓存思路&#xff0c;通过使用常见的缓存技术&#xff0c;降低大模型的回复速度&#xff0c;下面介绍的是使用redis和mem0&#xff0c;当然redis的语义…

windows蓝牙驱动开发-调试及支持的HCI和事件

调试蓝牙配置文件驱动程序 开发蓝牙配置文件驱动程序时&#xff0c;可以使用驱动程序验证程序来协助其调试。 若要启用验证检查&#xff0c;必须为 Bthusb.sys 启用驱动程序验证程序。 如果不执行此操作&#xff0c;将禁用验证检查。 若要完全利用验证检查&#xff0c;请确保…

深度求索(DeepSeek)的AI革命:NLP、CV与智能应用的技术跃迁

Deepseek官网&#xff1a;DeepSeek 引言&#xff1a;AI技术浪潮中的深度求索 近年来&#xff0c;人工智能技术以指数级速度重塑全球产业格局。在这场技术革命中&#xff0c;深度求索&#xff08;DeepSeek&#xff09;凭借其前沿的算法研究、高效的工程化能力以及对垂直场景的…

xxl-job使用nginx代理https后,访问出现403异常问题解决

在nginx代理为https之前&#xff0c;xxl-job使用http访问是没有问题的&#xff0c;但是换为https后&#xff0c;访问就有以下报错&#xff1a; 很多接口都出现了403异常 DataTables warning: table idjob_list - Ajax error. For more information about this error, please s…

kafka 3.5.0 raft协议安装

前言 最近做项目&#xff0c;需要使用kafka进行通信&#xff0c;且只能使用kafka&#xff0c;笔者没有测试集群&#xff0c;就自己搭建了kafka集群&#xff0c;实际上笔者在很早之前就搭建了&#xff0c;因为当时还是zookeeper&#xff08;简称ZK&#xff09;注册元数据&#…