dp刷题(二)分割回文串(详细推导+O(N^3)=>O(N^2)优化)

news2024/12/26 11:13:38

目录

分割回文串-ii_牛客题霸_牛客网 ​编辑

描述

示例1

思路

状态F(i):即为第i个字符时所需要切割的最小次数

状态转移方程:F(i) = min(F(i), F(j)+1)

优化:

注意点




分割回文串-ii_牛客题霸_牛客网

描述

给出一个字符串s,分割s使得分割出的每一个子串都是回文串

计算将字符串s分割成回文分割结果的最小切割数

例如:给定字符串s="aab",

返回1,因为回文分割结果["aa","b"]是切割一次生成的。

示例1

输入:"aab"

返回值:1

思路

首先明确我们需要返回切割字符串的最小次数,那么定义一个

状态F(i):即为第i个字符时所需要切割的最小次数

当i指向3时,如何判断它的分割次数呢,那我得需要重新定义一个指针j从i前面开始遍历

当j指向1位置时,后续AB不为回文,当j指向2时,后续字符B为回文,

                                                          即需要给2位置后进行一次分割

即就完成了F(3)的最小分割划分,即F(3)=F(2)+1那么这个3 和 2分别对于i与j的话

状态转移方程:F(i) = F(j)+1

 我们继续进行划分:当i指向4时,j从1开始,发现ABA为一个回文串,即F(4)=F(1)+1 = 1;

                                 当j指向2位置时,后续BA不为一个回文

                                 当j指向3位置时,后续A为一个回文 即F(4) = F(3)+1 = 2;

                                 那么F(4)的值应该为多少呢?肯定是更小的1;

                                 所以我们在状态转移时需要进行就小选取,不断更新F(i)

状态转移方程:F(i) = min(F(i), F(j)+1)

我们继续划分:当i指向5位置时,j从1开始,发现后续不为回文

                          当j指向2位置时,后续不为回文

                          当j指向3时,后续AA为一个回文F(5) = F(3)+1 = 2

                          当j指向4时,后续A为一个回文 F(5) = F(4)+1 = 2

                          我们发现 F(5)最小值为2,结果就是2嘛?

                        我的AABAA一个整体都是回文,所以在j进行遍历之前首先判断1~i 是否为回文

        int minCut(string s) {
        // write code here
        int len = s.size();
        if(s.empty() || isPal(s, 0, len-1))
            return 0;
        vector<int> dp(len+1);
        for(int i = 1; i <= len; i++)
            dp[i] = i-1;
        for(int i = 2; i <= len; i++)
        {
            // 首先判断1~i是否回文
            if(isPal(s, 0, i-1))
            {
                dp[i] = 0;
                continue;
            }
            for(int j = 1; j < i; ++j)
            {
                // 再【j, i】满足回文条件下进行更新dp
                if(isPal(s, j, i-1))
                {
                    //状态转移方程:F(i) = min(F(i), F(j)+1)
                    dp[i] = min(dp[i], dp[j]+1);
                }
            }
        }
        return dp[len];
        }
           
        // 回文判断函数
        bool isPal(string s, int begin, int end)
        {
            while(begin < end)
            {
            if(s[begin]!=s[end])
            return false;
            begin++;
            end--;
            }
            return true;
        }

优化:

下图中在时间复杂度为O(N^2)的双重for循环嵌套内部中又多了一个判断回文字符串的函数,该函数内部时间复杂度为O(N),所以整个函数运行时的时间复杂度为O(N^3)

 如何进行优化呢,如果能够去掉if判断内部函数,可以直接访问字符串关于回文方面的信息,那么时间复杂度就由O(N^3)降为O(N^2)

 用一个二维矩阵存放这个字符串中的每个字符串之间关于回文串的信息。

注意点

① 定义bool类型的n*n的矩阵,以矩阵类型返回,在mincut函数内部定义二维数组进行接受

② 推出来的状态转移方程:由俩边向内层进行转移,所以需要访问到内部Mat矩阵的(i+1,j-1)位置元素,所以在是从一个半三角而且是从下至上进行建立

    vector<vector<bool>> GetMat(string s)
    {
        int len = s.size();
        vector<vector<bool>> Mat(len, vector<bool> (len, false));
        for(int i = len-1; i >=0; i--)
        {
            for(int j = i; j < len; j++)
            {
                if(i==j)
                    Mat[i][j] = true;
                else if(i+1 == j)
                    Mat[i][j] = (s[i]==s[j]);
                else
                    Mat[i][j] = s[i]==s[j]&&Mat[i+1][j-1];
            }
        }
        return Mat;
    }

整体使用:


class Solution {
public:
    /**
     * 
     * @param s string字符串 
     * @return int整型
     */
    // bool isPal(string s, int begin, int end)
    // {
    //     while(begin < end)
    //     {
    //         if(s[begin]!=s[end])
    //         return false;
    //         begin++;
    //         end--;
    //     }
    //     return true;
    // }
    vector<vector<bool>> GetMat(string s)
    {
        int len = s.size();
        vector<vector<bool>> Mat(len, vector<bool> (len, false));
        for(int i = len-1; i >=0; i--)
        {
            for(int j = i; j < len; j++)
            {
                if(i==j)
                    Mat[i][j] = true;
                else if(i+1 == j)
                    Mat[i][j] = (s[i]==s[j]);
                else
                    Mat[i][j] = s[i]==s[j]&&Mat[i+1][j-1];
            }
        }
        return Mat;
    }
    
    int minCut(string s) {
        // write code here
        int len = s.size();
        if(s.empty())
        return 0;
        vector<int> dp(len+1);
        for(int i = 1; i <= len; i++)
            dp[i] = i-1;
        vector<vector<bool>> Mat = GetMat(s);
        for(int i = 2; i <= len; i++)
        {
            if(Mat[0][i-1])
            {
                dp[i] = 0;
                continue;
            }
            for(int j = 1; j < i; ++j)
            {
                if(Mat[j][i-1])
                {
                    dp[i] = min(dp[i], dp[j]+1);
                }
            }
        }
        return dp[len];
    }
};

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

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

相关文章

Android---Bottom Sheet

目录​​​​​​​ Bottom Sheet BottomSheetBehavior BottomSheetDialog 完整 Demo Bottom Sheet Bottom Sheet 是 Design Support Library 23.2 版本引入的一个类似于对话框的控件&#xff0c;可以暂且叫做底部弹出框。Bottom Sheet 中的内容默认是隐藏起来的&#xff0…

Python爬虫登录后token处理

今天继续给大家介绍Python爬虫相关知识&#xff0c;本文主要内容是Python爬虫登录后token处理。 一、网页token及token作用 在上文Python爬虫登录后cookie处理中&#xff0c;我们介绍过使用使用Python爬虫解决cookie及网页登录访问问题。 然而&#xff0c;有的网站&#xff0…

一文读懂Linux内核进程及调度时机原理

前言0.1 进程概要进程是对物理世界的建模抽象&#xff0c;每个进程对应一个 task_struct 数据结构&#xff0c;这个数据结构包含了进程的所有的信息。在 Linux 内核中&#xff0c;不会区分线程和进程的概念&#xff0c;线程也是通过进程来实现的&#xff0c;线程和进程的唯一区…

Leetcode:257. 二叉树的所有路径(C++)

目录 问题描述&#xff1a; 实现代码与解析&#xff1a; 递归&#xff1a; 原理思路&#xff1a; 迭代&#xff08;前序&#xff09;&#xff1a; 思路原理&#xff1a; 问题描述&#xff1a; 给你一个二叉树的根节点 root &#xff0c;按 任意顺序 &#xff0c;返回所有…

计算机网络第一章

目录 1.概念 2.标准化工作及其相关组织 3.速率相关的性能指标 4.分层的基本原则&#xff1a; 5.参考模型 1.OSI七层参考模型 2.TCP/IP参考模型 3.五层参考模型 1.概念 计算机网络是网络中的一个分支&#xff0c;组成包括了计算机系统&#xff0c;通信设备&#xff0c;线路…

app逆向 || xx合伙人登陆参数

声明 本文仅供学习参考&#xff0c;如有侵权可私信本人删除&#xff0c;请勿用于其他途径&#xff0c;违者后果自负&#xff01; 如果觉得文章对你有所帮助&#xff0c;可以给博主点击关注和收藏哦&#xff01; 本文适用于对安卓开发和Java有了解的同学 前言 本人最近一直在…

学习笔记5:关于操作符与表达式的求值

目录​​​​​​​ 一.移位操作符 1.左移操作符 2.右移操作符 二.位操作符 1.位运算基本知识 2.位运算的巧妙运用 三.其他操作符 1.算术操作符 2.单目操作符 3.关于逻辑操作符 四.表达式求值 隐式类型转换 (1)整形提升(短整型家族数据的二进制序列补位转换) (2).算…

【最新】SpringBoot集成Dubbo3

最近在学习dubbo&#xff0c;构建一个简单的springboot集成dubbo&#xff0c;中间也是出了好多问题&#xff0c;在这记录下整体的过程。 1. 构建SpringBoot环境 一个简单的聚合工程 dubbo-consumer&#xff1a;是服务消费方dubbo-provider&#xff1a;是服务提供方dubbo-inte…

机器学习笔记之前馈神经网络(二)非线性问题

机器学习笔记之前馈神经网络——非线性问题引言回顾&#xff1a;关于非线性问题解决非线性问题的三种方式引言 上一节介绍了从机器学习到深度学习的过渡&#xff0c;并介绍了深度学习的发展过程。本节将主要介绍如何使用神经网络处理非线性问题 回顾&#xff1a;关于非线性问…

决策树生成、决策树可视化、决策树算法api、泰坦尼克号乘客生存预测案例代码

一、决策树算法api class sklearn.tree.DecisionTreeClassifier(criterion’gini’,max_depthNone,random_stateNone) criterion&#xff1a;特征选择标准&#xff0c;"gini"或者"entropy"&#xff0c;前者代表基尼系数&#xff0c;后者代表信息增益&…

来自 GitHub 2022 的趋势和见解

《Github 2022 发展趋势和见解》发布了这件事小伙伴们知道了吧&#xff1f;这是每个程序员不能错过的年度报告&#xff0c;因为里面详细介绍了语言的发展趋势和热门领域的介绍。那就让我们来看看吧 目录 编程语言 地理分布 贡献时间分配 技术发展趋势 最受欢迎的存储库 …

GoogLeNet详解

入门小菜鸟&#xff0c;希望像做笔记记录自己学的东西&#xff0c;也希望能帮助到同样入门的人&#xff0c;更希望大佬们帮忙纠错啦~侵权立删。 ✨完整代码在我的github上&#xff0c;有需要的朋友可以康康✨ https://github.com/tt-s-t/Deep-Learning.git 目录 一、GoogLeNet…

C++入门——auto、范围for、nullptr

下一篇就要类和对象了&#xff0c;剩了点零碎的知识点就浅浅水一篇把 一. auto关键字 在早期C/C中auto的含义是&#xff1a;使用auto修饰的变量&#xff0c;是具有自动存储器的局部变量&#xff0c;但遗憾的 是一直没有人去使用它&#xff0c;这是由于变量本身就具备生命周期…

算法及时间、空间复杂度

算法 算法是对问题求解过程的一种描述&#xff0c;是为解决一个或一类问题给出的一个确定的、有限长的操作序列。严格说来&#xff0c;一个算法必须满足以下5个重要特性&#xff1a; &#xff08;1&#xff09;有穷性&#xff1a;对于任意一组合法的输入值&#xff0c;在执行有…

【数据结构与算法——C语言版】5. 排序算法(2)——冒泡排序

前言 上篇文章【数据结构与算法——C语言版】4. 排序算法&#xff08;1&#xff09;——选择排序我们介绍了排序算法中的选择排序&#xff0c;其时间复杂度是O(n2)&#xff0c;本篇文章我们将介绍另一种同样时间复杂度是O(n2)的排序算法——冒牌排序&#xff0c;这两种算法思路…

ChatGPT背后的开源AI框架Ray,现在值10亿美元

Ray 被 OpenAI、亚马逊等科技公司用来开发大模型&#xff0c;是最近异军突起的框架。 最近一段时间&#xff0c;文本生成的人工智能在互联网上掀起了一阵风暴&#xff1a;ChatGPT 因为可以对人们能想到的几乎任何问题提供非常详细、近乎逼真的回答而受到追捧。大模型应用的出现…

Mapper代理开发案例及MyBatis核心

本片文章需要参考我的前一篇文章&#xff1a;MyBatis入门案例引入总结&#xff0c;使用mapper代理开发的好处就是可以解决开发中硬编码的问题和简化后期的SQL执行。使用这种方式可以不用写接口的实现类&#xff0c;免除了复杂的方法&#xff0c;使得代码更加清晰易懂按照以前的…

vue的过渡动画(有vue的动画库和ui库的介绍)

一、概念 Vue 在插入、更新或者移除 DOM 时&#xff0c;提供多种不同方式的应用过渡效果。 二、默认过渡 <template><div><button click"isShow!isShow">显示/隐藏</button><transition appear><h1 v-show"isShow" cl…

过滤器和拦截器的使用及管理

参考&#xff1a;(70条消息) Spring过滤器和拦截器的区别_yjc0403的博客-CSDN博客https://www.cnblogs.com/colin220/p/9606412.htm概述过滤器&#xff1a;是在javaweb中&#xff0c;你传入的request、response提前过滤掉一些信息&#xff0c;或者提前设置一些参数&#xff0c;…

Anaconda安装之后Spyder打不开解决办法--目前有用 jupyter notebook 无法正常运行2023.1.7

纯纯小白&#xff0c;探索一天&#xff0c;终于成功&#xff0c;需要我的经历没有白费&#xff0c;让大家少走弯路。 问题描述 从官网下载Anaconda之后&#xff0c;安装&#xff0c;一切正常。打开Anaconda navigator在弹出窗口选择了更新&#xff08;我怀疑这就根源&#xf…