IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 数据结构与算法 -> letcode-动态规划解最长回文子串(消去二维数组) -> 正文阅读

[数据结构与算法]letcode-动态规划解最长回文子串(消去二维数组)

动态规划解最长回文子串

题目

示例 1:

输入:s = "babad"
输出:"bab"
解释:"aba" 同样是符合题意的答案。

示例 2:

输入:s = "cbbd"
输出:"bb"

示例 3:

输入:s = "a"
输出:"a"

示例 4:

输入:s = "ac"
输出:"a"

提示:

1 <= s.length <= 1000
s 仅由数字和英文字母(大写和/或小写)组成

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/longest-palindromic-substring

得到最长回文子串前,需要得到次最长子串。

例如字符串:cbbaabb ,它的最长回文子串为:bbaabb,得到该结果需要逐步确认: aa、baab 是回文,最终结论,bbaabb是回文子串。

类似此类需要依赖子问题结论的,求解都可以使用动态规划。

解题思路

有字符串:vxajkbbkja ,肉眼可判断最大回文为:ajkbbkja
如下图所示:我们只需要以中轴为起点,以途中红色箭头方向依次判断相等性,取到最长的即可。
(坐下部分对称,可以不必比较)

设横向为X, 纵向为Y,两个方向都从 字符v开始,字符a结束。延对称轴方向访问。
在这里插入图片描述

遍历如图红色箭头指向路径,如下每行对应一条红色箭头。
{0,0}
{1,0}
{1,1}{2,0}
{2,1}
{2,2}{3,1}
{3,2}
{3,3}{4,2}
{4,3}
{4,4}{5,3}
{5,4}
{5,5}{6,4}
{6,5}{7,4}{8,3}{9,2}
{6,6}{7,5}
{7,6}
{7,7}{8,6}
{8,7}
{8,8}{9,7}
{9,8}
{9,9}

最终得到相等的有点:{6,5}{7,4}{8,3}{9,2}
把它延对称轴映射:就可以得到最终的回文子串。

最终代码

我没有使用二维数组,所以节约了不少内存空间,由于增加了对特殊情况的判断,所以代码不是很简洁:

在这里插入图片描述


class Solution {
    

    public String longestPalindrome(String s) {
        char[] sArr = s.toCharArray();
        /** 记录当前步、最长步的起始位置和长度 */
        int maxLetf = 0, maxLen = 0, curLeft = 0, curLen = 0;
        /** 记录当前步、最长步的起点是否在对称轴上,如果在对称轴上,回文长度为奇数,否则回文长度为偶数 */
        boolean turnFlag = true, maxFlag = true;
        /** returnValue 记录回溯的位置,可以认为它是对横坐标 i 值的缓存,
        结合上一节,每条红线访问结束都需要回溯横坐标。  */
        int returnValue = 0;
        for(int i = 0; i < sArr.length;){
            int j = (turnFlag) ? i : i - 1;
            for(; j >= 0 && i < sArr.length; j--,i++){
                if (sArr[i] == sArr[j]) curLen++; 
                else break;
            }
            /** 起点不在对称轴上,把最终长度加1 */
            if (curLen != 0 && !turnFlag) curLen++;

            /** 当起点在对称轴上的时候,最大步长相等即记录为最长 */
            if (curLen > maxLen || (curLen == maxLen && turnFlag)){
                maxLen = curLen;
                maxLetf = curLeft;
                maxFlag = turnFlag;
            }
            /** 因为依次访问,所以起点间次在或不在对称轴上 */
            turnFlag = !turnFlag;
            if (turnFlag) i = returnValue;
            else i = ++returnValue;/** 前一次迭代不在对称轴上,下一次迭代起点在对称轴上,横坐标加1 */
            curLeft = i;/** 重置迭代起点 */
            curLen = 0;/** 清空步长 */
        }
        maxLetf = maxLetf - (--maxLen);
        maxLen = maxFlag ?  (maxLetf + maxLen + maxLen + 1) : (maxLetf + maxLen + maxLen);
        return s.substring(maxLetf, maxLen);
    }

}

设字符串长度为:N, X = N/2,如下公式表示需要对比的次数,可以很直观的得到结论,它就是二维表格一半格数近似和。

  • T(N) = X * (X - 1) / 2 + X * (X - 1) / 2 = X^2 - X = N ^2 / 4 - N/2;

  • 省略低次项和系数后:时间复杂度为:O(N^2)

  • 因为没有使用二维数据:可以认为空间复杂度是一个常数,求解字符串越长越能体现它的优点。

利用本题同样思路,可以解两个字符串的最大公共子串,异曲同工。

  数据结构与算法 最新文章
【力扣106】 从中序与后续遍历序列构造二叉
leetcode 322 零钱兑换
哈希的应用:海量数据处理
动态规划|最短Hamilton路径
华为机试_HJ41 称砝码【中等】【menset】【
【C与数据结构】——寒假提高每日练习Day1
基础算法——堆排序
2023王道数据结构线性表--单链表课后习题部
LeetCode 之 反转链表的一部分
【题解】lintcode必刷50题<有效的括号序列
上一篇文章      下一篇文章      查看所有文章
加:2021-10-27 13:04:40  更:2021-10-27 13:05:12 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/26 8:22:15-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码