数据结构基础day9

news2024/12/23 14:31:35

题目:187. 重复的DNA序列

解法1:哈希表

class Solution {
public:
    vector<string> findRepeatedDnaSequences(string s) {
        vector<string> ans;
        unordered_map<string, int> mp;
        int n=s.size(), L=10;
        for(int i=0; i<=n-L; ++i){	//从开头遍历到最后一个长度为10的子串开头
            string temp = s.substr(i,L);
            if(++mp[temp]==2){	//当数量==2时即可加入答案序列
                ans.push_back(temp);
            }
        }
        return ans;
    }
};

解法2:哈希表+滑动窗口+位运算

好长,不想看

题目:5. 最长回文子串

解法1:暴力解法

遍历每一个子串,当其是回文子串且长度最大,存储初始位置和长度。
时间复杂度O(n^3),空间复杂度O(1)

class Solution {
public:
    bool isPalindrome(string s, int left, int right){	//判断s字符串中left到right位置的子串是否为回文串
        while(left<right){
            if(s[left] != s[right]) return false;
            ++left; --right;
        }
        return true;
    }

    string longestPalindrome(string s) {
        int n = s.size();
        if(n<2) return s;	//特判

        int maxLen = 1;	//最大长度可以是一个字母
        int begin = 0;	//初始位置

        for(int i=0; i<n-1; ++i){	//遍历头,注意遍历到n-1
            for(int j=i+1; j<n; ++j){	//遍历从i开始的子串的尾,
                if(j-i+1>maxLen && isPalindrome(s, i, j)){	//当子串长度大于当前最大长度,且子串为回文串
                    maxLen = j-i+1;	//更新最大长度
                    begin = i;	//更新起始位置
                }
            }
        }

        return s.substr(begin, maxLen);	//返回s的最大长度回文子串
    }
};

解法2:动态规划

相当于在暴力解法的基础上空间换时间,时间复杂度O(n^2),空间复杂度O(n)
状态定义(定义子问题):一个字符串是否是回文串看去掉两头字符后的字符串是否是回文串,因此子问题定义为:dp[i][j]表示s[i,...,j]为回文子串
状态转移方程(描述子问题之间的联系)dp[i][j] = (s[i]==s[j]) && (dp[i+1][j-1]=true)
初始化:边界条件就是当子串长度为1的时候,显然是回文子串,比如,ij的一个子串在i和j位置的字符相同时,判断去掉ij位置字符后的子串长度是否是回文子串,一致判断到去掉ij位置字符后的子串长度小于2,即j-1-(i+1)+1<2 -> j-i<3
输出dp[i][j]表示ij的子串是否是回文子串,判断j-i+1是否大于maxLen,如果大于,记录maxLenbegin=i
优化空间:见解法3中心拓展法
PS:注意都是先确定起始位置和长度,最后再截取最长回文子串
在这里插入图片描述

class Solution {
public:
    string longestPalindrome(string s) {
        int n = s.size();
        if(n<2) return s;	//特判

        int maxLen = 1;	//最大回文子串长度
        int begin = 0;	//最大回文子串起始位置

        vector<vector<int>> dp(n, vector<int>(n));	//dp定义,true是非0数,false是0
        for(int i=0; i<n; ++i){	//初始定义,每个字符单独都是回文子串,对角线为true
            dp[i][i] = true;
        }
        for(int j=1; j<n; ++j){	//从左上角开始遍历,注意从1开始,先遍历列
            for(int i=0; i<j; ++i){	//后遍历行,到对角线(j)为止
                if(s[i]!=s[j]) dp[i][j]=false;	//如果i和j位置的字符不相同,则直接false
                else{	//i和j位置字符相同
                    if(j-i<3){  //边界:j-1-(i+1)+1<2 -> j-i<3
                        dp[i][j] = true;
                    }else{	//继续判断i+1到j-1的子串
                        dp[i][j] = dp[i+1][j-1];
                    }
                }
                if(dp[i][j]==true && j-i+1>maxLen){	//检查i到j子串长度是否大于maxLen
                    maxLen = j-i+1;	//更新最大回文子串长度
                    begin = i;	//更新最大回文子串初始位置
                }
            }
        }

        return s.substr(begin, maxLen);	//截取最长回文子串
    }
};

解法3:中心扩展法

时间复杂度:O(n^2),空间复杂度:O(1)
枚举中心位置的个数2(n-1),每个中心向两边扩散看是否为回文子串,偶数回文子串和奇数回文子串

class Solution {
public:
    int ExpandfromCentre(string s, int i, int j){	//从中心开始扩展,检查扩展子串是否是回文子串
        int n = s.size();
        int left = i, right = j;
        while(left>=0 && right<n){
            if(s[left]==s[right]){
                --left;
                ++right;
            }else{
                break;
            }
        }   //不符合i和j位置的字符相同时退出循环,因此返回的回文子串的长度为j-1-(i+1)+1=j-i-1,这里是left和right!!!
        return right-left-1;
    }

    string longestPalindrome(string s) {
        int n = s.size();
        if(n<2) return s;	//特判

        int maxLen = 1;	//最大回文子串长度
        int begin = 0;	//最大回文子串起始位置

        for(int i=0; i<n-1; ++i){	//枚举中心位置
            int oddLen = ExpandfromCentre(s, i, i);	//最大奇数回文子串长度
            int evenLen = ExpandfromCentre(s, i, i+1);	//最大偶数回文子串长度
            if(max(oddLen, evenLen) > maxLen){	//更新maxLen和begin
                maxLen = max(oddLen, evenLen);
                begin = i-(maxLen-1)/2;	//注意这里是推导出来的
            }
        }
        
        return s.substr(begin, maxLen);	//截取最长回文子串
    }
};

从i和maxLen倒推begin有点麻烦,可以选另一个写法:

class Solution {
public:
    pair<int, int> ExpandfromCentre(string s, int i, int j){	//注意函数类型是pair
        int n = s.size();
        int left = i, right = j;
        while(left>=0 && right<n){
            if(s[left]==s[right]){
                --left;
                ++right;
            }else{
                break;
            }
        }   //不符合i和j位置的字符相同时退出循环,因此返回的回文子串的长度为j-1-(i+1)+1=j-i-1,这里是left和right!!!
        return {left+1, right-1};	//注意返回值和{}
    }

    string longestPalindrome(string s) {
        int n = s.size();
        if(n<2) return s;	//特判

        int maxLen = 1;	//最大回文子串长度
        int begin = 0;	//最大回文子串起始位置

        for(int i=0; i<n-1; ++i){
            auto [odd_l, odd_r] = ExpandfromCentre(s, i, i);	//注意加[]
            auto [even_l, even_r] = ExpandfromCentre(s, i, i+1);
            if(odd_r-odd_l+1 > maxLen){
                maxLen = odd_r-odd_l+1;
                begin = odd_l;
            }
            if(even_r-even_l+1 > maxLen){
                maxLen = even_r-even_l+1;
                begin = even_l;
            }
        }
        
        return s.substr(begin, maxLen);	//截取最长回文子串
    }
};

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

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

相关文章

【fluent UDF】warning: unused variable警报:存在未使用的变量

一、问题背景 在编译UDF时&#xff0c;出现如下错误 curing_heat_v3.c: In function ‘iter_ending’: curing_heat_v3.c:105:14: warning: unused variable ‘volume_sum’ [-Wunused-variable] real volume_sum0.0; curing_heat_v3.c:104:14: warning: unused variable ‘…

【Python零基础学习入门篇②】——第二节:Python的常用语句

⬇️⬇️⬇️⬇️⬇️⬇️ ⭐⭐⭐Hello&#xff0c;大家好呀我是陈童学哦&#xff0c;一个普通大一在校生&#xff0c;请大家多多关照呀嘿嘿&#x1f601;&#x1f60a;&#x1f618; &#x1f31f;&#x1f31f;&#x1f31f;技术这条路固然很艰辛&#xff0c;但既已选择&…

网络编程之简单socket通信

一.什么是Socket? Socket&#xff0c;又叫套接字&#xff0c;是在应用层和传输层的一个抽象层。它把TCP/IP层复杂的操作抽象为几个简单的接口供应用层调用以实现进程在网络中通信。 socket分为流socket和数据报socket&#xff0c;分别基于tcp和udp实现。 SOCK_STREAM 有以下…

苦学58天,最后就这结果......

背景 非计科大专一枚&#xff0c;当初学的机械自动化专业。大学完全可以说是玩过来的&#xff0c;临近毕业开始慌了&#xff0c;毕业后一直没能找到工作&#xff0c;在高中同学&#xff08;211 计科&#xff09;的引领下&#xff0c;入坑程序员&#xff0c;学的软件测试。 从…

Lombok简介

Lombok简介 1、lombok简介2、springboot整合lombok 1、lombok简介 Lombok是一个第三方的Java工具库&#xff0c;会自动插入编辑器和构建工具。Lombok提供了一组非常有用的注解&#xff0c;用来消除Java类中的大量样板代码&#xff0c;比如setter和getter方法、构造方法等。只需…

Vue(简单了解Cookie、生命周期)

一、了解Cookie 类似于对象响应携带数据 输入用户名密码跳转到指定页面 点击指定页面中其中一个按钮跳转到另一个指定页面&#xff08;再不需用输入用户名密码&#xff09; 例如现在很多浏览器实现七天免密登录 简单理解&#xff1a;就是在网站登录页面之后&#xff0c;服务…

新建Django项目

1. 创建项目 使用Django提供的命令&#xff0c;可以创建一个Django项目实例需要的配置项——包括数据库配置、Django配置和应用程序配置的集合。新建Django项目命令的语法格式如下&#xff1a; django-admin startproject 工程名称例如&#xff1a;想要在D:\的pythonProject目…

Mysql 存储过程 / 存储函数

目录 0 课程视频 1 基本语法 1.0 作用 ->在数据库中 封装sql语句 -> 复用 -> 减少网络交互 ->可接收参数返回数据 1.1 创建 1.2 调用 1.3 查看 1.4 删除 1.5 ; 封号结束符 改成 $$ 双刀符合结束语句 -> 因为打包封号结束有冲突 1.6 在cmd 中定义 存储过…

基于 SpringBoot+Vue+Java 的财务管理系统(附源码,教程)

文章目录 一 简介第二.主要技术第三、部分效果图第四章 系统设计4.1功能结构4.2 数据库设计4.2.1 数据库E/R图4.2.2 数据库表 第五章 系统功能实现5.1管理员功能模块 一 简介 财务管理系统的需求和管理上的不断提升&#xff0c;财务管理系统的潜力将无限扩大&#xff0c;财务管…

Postman预请求脚本、测试脚本(pre-request scripts、tests常用工作总结)

文章目录 Postman预请求脚本&#xff08;pre-request scripts工作常用总结&#xff09;Postman预请求脚本Postman测试脚本预请求脚本和测试脚本有什么区别常用工作总结登录接口返回的是Set-Cookie标头 Postman预请求脚本&#xff08;pre-request scripts工作常用总结&#xff0…

Spring Boot配置文件及日志信息

目录 前言&#xff1a; Spring Boot优点 配置文件 配置文件格式 读取配置文件 properties配置文件格式 properties优缺点分析 yml配置文件格式&#xff08;另一种标记语言&#xff09; yml优缺点分析 Spring Boot 不同平台配置文件规则 日志信息 日志的功能 Sprin…

Springboot +Flowable,设置任务处理人的四种方式(一)

一.简介 学习下UserTask 设置用户的三种方式&#xff0c;至于如何设置用户组&#xff0c;下篇文章再聊。 现在&#xff0c;假设我有如下一个简单的流程图&#xff1a; 那么该如何设置这个用户节点的处理人&#xff1f; 二.第一种&#xff1a;指定具体用户 第一种方式&…

电路中噪声来源

电路包括不同的部件和芯片&#xff0c;所有都有可能成为噪声的来源。例如&#xff0c;电阻会带来热噪声&#xff0c;这个噪声为宽频噪声&#xff0c;几乎涵盖所有频率范围&#xff1b;运算放大器其芯片内部会产生噪声&#xff1b;而 ADC产生的量化噪声相较于其他器件&#xff0…

【】右值引用完美转发

文章目录 右值引用和左值引用左值和右值概念左值引用 && 右值引用右值引用使用场景和意义左值引用的使用场景**左值引用的短板:**右值引用和移动语义STL容器增加的接口move函数右值引用的其他使用场景 完美转发万能引用完美转发保持值的属性完美转发的使用场景 右值引用…

【Linux】进程信号 --- 信号产生 信号递达和阻塞 信号捕捉

&#x1f34e;作者&#xff1a;阿润菜菜 &#x1f4d6;专栏&#xff1a;Linux系统编程 文章目录 一、预备知识二、信号产生1. 通过终端按键产生信号1.1 signal()1.2 core dump标志位、核心存储文件 2.通过系统调用向进程发送信号3.由软件条件产生信号3.1 alarm函数和SIGALRM信号…

vue3通过ref拿element弹框中的组件问题

写在<el-dialog>中的组件&#xff0c;在一开始&#xff0c;弹框没有弹出来的时候&#xff0c;<el-dialog>中的组件是没有被渲染出来的&#xff0c;因此在<el-dialog>中使用ref标记某个组件&#xff0c;在el-dialog没有被渲染出来之前去拿的话&#xff0c;是拿…

ml常见代码片段

常用ML代码片段 变换一列 new_df[brand] new_df[prod_name].apply(lambda x: x.split()[0])变换2列 new_df[chip_total_sales] new_df.apply(lambda x: x[total_sales] * x[is_chip], axis 1) # 重要的是axis1groupby 计数&#xff0c;求和&#xff0c;取第一个值&#x…

C语言起源、特性和发展历程

本文从ALGOL 60语言谈起&#xff0c;简述C语言的起源和发展历程&#xff0c;然后对C语言的一些特性做了探讨&#xff0c;最后说说C语言为什么在众多编程语言中&#xff0c;起到了承上启下的作用。 本文介绍以下内容&#xff1a; C语言的起源C语言的发展C语言的特性C语言的重要…

外卖项目优化-01-redis缓存短信验证码、菜品数据

文章目录 外卖项目优化-01课程内容前言1. 环境搭建1.1 版本控制解决branch和tag命名冲突 1.2 环境准备 2. 缓存短信验证码2.1 思路分析2.2 代码改造2.3 功能测试 3. 缓存菜品信息3.1 实现思路3.2 代码改造3.2.1 查询菜品缓存3.2.2 清理菜品缓存 3.3 功能测试3.4 提交并推送代码…

AutoGPT安装教程

最近安装AutoGPT时遇到了一些问题&#xff0c;写下这篇文章记录一下 1 下载AutoGPT AutoGPT链接&#xff1a;https://github.com/Significant-Gravitas/Auto-GPT/tree/v0.2.2 下载AutoGPT 推荐下载stable 版本 2 申请openai 的api key 获取api的key&#xff0c;这里就不介…