Leetcode 4.18

news2024/12/25 9:25:35

Leetcode

  • 1.无重复字符的最长子串
  • 2.最长回文子串
  • 3.整数反转
  • 4.字符串转换整数 (atoi)
  • 5.正则表达式匹配

1.无重复字符的最长子串

无重复字符的最长子串
滑动窗口,先让右指针右移,如果发现这个子串有元素和右指针当前元素重复。
则:

  1. 左指针右移,直到移除重复元素为止。
  2. 怎么计算是否有重复?用unordered_map维护子串个数,删除的话数量响应减少,如果count == 0 则将元素erase
  3. 随时更新ans长度,用mp.size()可以轻松算出长度
class Solution {
public:
    int lengthOfLongestSubstring(string s) {
        int ans = 0;
        if (s.size() <= 1) return s.size();
        int l = 0, r = 0;
        unordered_map<char, int> mp;
        while (l <= r && r < s.size()) {
            //当有重复元素时,移动左指针,直到删除了左侧重复元素
            while (mp.count(s[r]) != 0) {
                //重复元素左侧元素都得依次删除
                mp[s[l]]--;
                if (mp[s[l]] == 0) mp.erase(s[l]);
                l++;
            }

            //添加右侧元素,此时已经不重复了
            mp[s[r]]++;
            ans = max(ans, (int)mp.size());  
            r++;
        }
        return ans;
    }
};

2.最长回文子串

最长回文子串
两个要点:

  1. 判断是否为回文串 —> 分奇偶数,l,r指针分别指向头尾,观察r–,l++是否相等
  2. 是否为最长—> 可以用ans维护最长的个数

暴力解法:可以双重循环,依次判断是否为回文串。

class Solution {
public:
    string longestPalindrome(string s) {
        int n = s.size();
        string ans = s.substr(0, 1);
        if (n <= 1) return s;
        for (int i = 0; i < n; i++) {
            for (int j = i; j < n; j++) {
                if (j - i + 1 > ans.size() && ispalindorme(s, i ,j)) {
                    ans = s.substr(i, j - i + 1);
                }
            }
        }
        return ans;
    }
    bool ispalindorme(string s, int l, int r) {
        while (r >= l) {
            if (s[l] != s[r]) {
                return false;
            }
            l++, r--;
        }
        return true;
    }
};

中心扩散法:
给定一个字符串,从中间到两边扩散,判断从左到右范围内最长的回文子串长度。
考虑到奇偶数的不同情况,需要调用两次中心扩散函数。

class Solution {
public:
    string res;
    string longestPalindrome(string s) {
        int n = s.size();
        if (n <= 1) return s;
        for (int i = 0; i < n; i++) {
            extandformmid(s, i, i);
            extandformmid(s, i, i+1);
        }
        return res;
    }

    void extandformmid(string& str, int left, int right) {
        while (left >= 0 && right < str.size() && str[left] == str[right]) {
            left--;
            right++;
        }
        if (right - left - 1 > res.size()) {
            res = str.substr(left + 1, right - left - 1);
        }
    }
};

3.整数反转

整数反转
用ans保存反转后的答案。
在处理数字的过程中判断ans是否有溢出情况发生。
在这里插入图片描述
在这里插入图片描述

class Solution {
public:
    int reverse(int x) {
        int ans = 0;
        while (x) {
            if (ans < INT_MIN / 10 || ans > INT_MAX / 10) {
                return 0;
            }
            ans = ans * 10 + (x % 10);
            x= x / 10;
        }
        return ans;
    }
};

4.字符串转换整数 (atoi)

字符串转换整数 (atoi)
去除前导空格—> while删除
检查正负号—> 有则按照符号,无则为正
读入字符—> ans = ans * 10 + digt
整数范围—>如果下一次ans * 10会溢出,则直接返回这次的结果

class Solution {
public:
    int myAtoi(string s) {
        int ans = 0; int flag = 1;
        int index = 0, n = s.size();
        //删除空格
        while (index < n && s[index] == ' ') index++;
        //检查符号
        if (index < n) {
            if (s[index] == '-') {
                flag = -1;
                index++;
            } else if (s[index] == '+'){
                flag = 1;
                index++;
            }
        }
        //读入字符
        while (index < n && isdigit(s[index])) {
            int dig = s[index] - '0';
            //注意这里严格按照推理所得的公式计算
            if (ans > (INT_MAX - dig) / 10) {
                return flag == 1 ? INT_MAX : INT_MIN;
            }
            ans = ans * 10 + dig;
            index++;
        }
        return ans * flag;
    }
};

5.正则表达式匹配

正则表达式匹配
子串匹配的题目,不由自主的先想DP。

DP分两步:
定义状态
定义状态转移方程

  • 状态
    dp[i][j]表示s[…i]与p[…j]是否能够匹配。dp[s.size()-1][p.size()-1]即为本题答案。

  • 状态转移

    • p[j - 1] = '*' 时, dp[i][j] 在当以下任一情况为 true 时等于 true:

      • dp[i][j - 2]: 即将字符组合 p[j - 2] * 看作出现 0 次时,能否匹配。
      • dp[i - 1][j]s[i - 1] = p[j - 2]: 即让字符 p[j - 2] 多出现 1 次时,能否匹配。
      • dp[i - 1][j]p[j - 2] = '.': 即让字符 '.' 多出现 1 次时,能否匹配。
    • p[j - 1] != '*' 时, dp[i][j] 在当以下任一情况为 true 时等于 true

      • dp[i - 1][j - 1]s[i - 1] = p[j - 1]: 即让字符 p[j - 1] 多出现一次时,能否匹配。
      • dp[i - 1][j - 1]p[j - 1] = '.': 即将字符 . 看作字符 s[i - 1] 时,能否匹配。

p[j-1] == '*'的情况下
1. dp[i][j-2] == True # * 匹配0次,然后s不变,让p[(j-1)-1]匹配0次,相当于消除了一个字符,这里之所以用 [j-2] 是因为相当于 *号和它前面的个字符被丢掉了
2. p[j-2] == s[i-1] and dp[i-1][j] == True # * 匹配多次,这里的多次是可以让前面的1次累加起来的,所以相当于让 * 匹配1次,这里之所以是dp[i-1][j]是因为匹配了一次s中的最后一个字符,所以可以相当于丢掉s中的字符,但是p中的 *和它前面的字符并没有被消耗掉,因为*号可以匹配任意次
3. p[j-2] == '.' and dp[i-1][j] == True # 这里要注意 这里表示*号前面是个'.''.'可以匹配任意字符,所以'.*'可以表示成 … 是上面2中的 p[j-2] == s[i-1] 一种特例
在这里插入图片描述
在这里插入图片描述

class Solution {
public:
    bool isMatch(string s, string p) {
        int n = s.size() + 1, m = p.size() + 1;
        vector<vector<bool>> dp(n, vector<bool> (m, false));
        int i = 1, j = 1;
        //空字符串可以匹配
        dp[0][0] = true;

        // 初始化首行
        for(int j = 2; j < m; j += 2)
            dp[0][j] = dp[0][j - 2] && p[j - 1] == '*';


        for(int i = 1; i < n; i++) {
            for (int j = 1; j < m; j++) {
                if (p[j - 1] == '*') {
                    if (dp[i - 1][j] && s[i - 1] == p[j - 2]) {
                        dp[i][j] = true;
                    //上上个元素为. , 让.多出现几次
                    } else if (dp[i - 1][j] && p[j - 2] == '.') {
                        dp[i][j] = true;
                    //j - 2,指上一个元素为0
                    } else if (dp[i][j - 2]) {
                        dp[i][j] = true;
                    }
                } else {
                    //匹配上了
                    if (dp[i - 1][j - 1] && s[i - 1] == p[j - 1]) {
                        dp[i][j] = true;
                    //是'.'
                    } else if (dp[i - 1][j - 1] && p[j - 1] == '.') {
                        dp[i][j] = true;
                    }
                }
            }
        }
        //
        return dp[n - 1][m - 1];
    }
};

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

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

相关文章

OpenHarmony南向开发案例:【智能照相机】

样例简介 本Demo是基于Hi3516开发板&#xff0c;使用OpenHarmony3.0-LTS开发的应用。通过获取摄像头数据&#xff0c;实现预览拍照以及路视频等功能。并且通过后台AI服务识别唤醒词来进行语音控制拍照及录制视频。 应用运行效果图&#xff1a; 此为相机的预览界面。 样例原理…

#无FIFO驱动OV7670基于cubemx(草稿)

1.前言 之前在淘宝买了一个不带FIFO的OV7670&#xff0c;由于比赛和其他事一直搁置&#xff0c;现在有时间于是想玩一玩。我发现网上这个的教程多为标准库&#xff0c;有些甚至利用了DCMI&#xff08;数字摄像头接口&#xff0c;目前已知F4系列是有这个外设的&#xff09;。标…

ant-design-vue Table+Form表单实现表格内置表单验证,可自定义验证规则,触发必填项

代码示例如下&#xff1a; <!-- --> <template><a-button type"primary" style"padding-left: 10px; padding-right: 10px" click"handleAddRow"><template #icon><plus-outlined /></template>新增</…

SOT23-6封装单键触摸感应触发芯片TC233A

前言&#xff1a; 触摸芯片很多&#xff0c;现在触摸按键已经应用到很多行业&#xff0c;虽然不能覆盖所有的按键&#xff0c;但确实用的越来越多&#xff0c;国产的价格也便宜的令人发指&#xff0c;比如这个TC233A&#xff0c;也就一毛多一点。 TC233A概述 TC233A 是一个单…

【机器学习入门】推导超级详细,一文讲清楚支持向量机(SVM)【从原理到代码】

支持向量机(SVM)是机器学习中非常经典的一个模型&#xff0c;所以我就把这个作为第二个深入学习的机器学习模型&#xff0c;然后发现居然还挺难的&#xff08;调包侠流下无能泪水&#xff09;。 参考了很多博客&#xff0c;但是大部分博客都是讲一部分&#xff0c;要么数学部分…

Java面试八股之Iterator接口和Iterable接口

1. Java为什么不直接实现Iterator接口&#xff0c;而是实现Iterable? 这道题算是一道比较基础的题&#xff0c;面试官肯定也不是想让回答得多深入&#xff0c;只是考查对迭代器的了解程度&#xff0c;最好是看过源码&#xff0c;实际上迭代器的源码并不难。我们把注释折叠起来…

gpt-6有望成为通用工具

OpenAI CEO山姆奥特曼&#xff08;Sam Altman&#xff09;在最新的博客访谈中&#xff0c;提到gpt-6有望成为通用工具。 奥特曼还认为&#xff0c;目前的模型不够聪明&#xff0c;“使用GPT-2进行科学研究曾被认为是不切实际的想法。而如今&#xff0c;虽然人们使用GPT-4进行科…

C++异常学习

C语言传统的处理错误的方式 传统的错误处理机制&#xff1a; 终止程序&#xff0c;如assert&#xff0c;缺陷&#xff1a;用户难以接受。如发生内存错误&#xff0c;除0错误时就会终止程序。返回错误码&#xff0c;缺陷&#xff1a;需要程序员自己去查找对应的错误。如系统的…

【基础】在GCC中编译和链接不是一个命令

在 GCC&#xff08;GNU Compiler Collection&#xff09;中&#xff0c;编译和链接不是一个命令。编译是将源代码转换为目标代码的过程。它主要进行语法检查、词法分析、生成中间代码等操作。链接是将多个目标文件和库文件组合成一个可执行文件的过程。在 GCC 中&#xff0c;通…

Root mapping definition has unsupported parameters: [all : {analyzer=ik_max_wor

你们好&#xff0c;我是金金金。 场景 我正在使用Springboot整合elasticsearch&#xff0c;在创建索引(分词器) 运行报错&#xff0c;如下 排查 排查之前我先贴一下代码 import org.elasticsearch.action.admin.indices.create.CreateIndexRequest; // 注意这个包SpringBootTe…

利用FFmpeg 转换课程vtt 字幕到 srt字幕

字幕转换工具 经常学习udemy 视频课程的&#xff0c;可能知道&#xff0c;从网络下载的udemy 课程文件里面有时候字幕是vtt 格式的&#xff0c;有时候想导入到百度网盘里面&#xff0c;怎奈百度网盘&#xff0c;不支持vtt 字幕格式。有字幕的时候&#xff0c;会比较好多了。既可…

Ollama、FastGPT大模型RAG知识库结合使用案例

参考: https://ollama.com/download/linux https://doc.fastai.site/docs/intro/ https://blog.csdn.net/m0_71142057/article/details/136738997 https://doc.fastgpt.run/docs/development/custom-models/m3e/ https://concise-eater-d47.notion.site/Ollama-Fastgpt-b170…

# 从浅入深 学习 SpringCloud 微服务架构(二)模拟微服务环境

从浅入深 学习 SpringCloud 微服务架构&#xff08;二&#xff09;模拟微服务环境&#xff08;1&#xff09; 段子手168 1、打开 idea 创建父工程 创建 artifactId 名为 spring_cloud_demo 的 maven 工程。 --> idea --> File --> New --> Project --> Ma…

树莓派使用总结

手上拿到了一块Raspberry Pi 4B板子。研究一下怎么用。 安装系统 直接到官网【Raspberry Pi 】下载在线安装助手 安装好后&#xff0c;打开软件&#xff0c;选择好板子型号、系统、TF卡&#xff0c;一路下一步就行。 树莓派接口 直接查看官方的资料【Raspberry Pi hardwar…

Docker Volume (存储卷)

什么是存储卷? 存储卷就是将宿主机的本地文件系统中存在的某个目录直接与容器内部的文件系统上的某一目录建立绑定关系。这就意味着&#xff0c;当我们在容器中的这个目录下写入数据时&#xff0c;容器会将其内容直接写入到宿主机上与此容器建立了绑定关系的目录。在宿主机上…

接口压力测试 jmeter--增强篇(二)

前期准备 1. JMeter的插件的安装 下载Jmeter Plugins Manager对插件进行管理 &#xff08;1&#xff09;下载地址&#xff1a;https://jmeter-plugins.org/install/Install/ &#xff08;2&#xff09;下载后&#xff0c;将jar包放到jmeter包目录下/lib/ext目录下 &#xff0…

绝对隔离+底层限制,成就猎鹰蜜罐“牢不可破”的立体化安全

前言 自网络诞生以来&#xff0c;攻击威胁事件层出不穷&#xff0c;网络攻防对抗已成为信息时代背景下的无硝烟战争。然而&#xff0c;传统的网络防御技术如防火墙、入侵检测技术等都是一种敌暗我明的被动防御&#xff0c;难以有效应对攻击者随时随地发起的无处不在的攻击和威胁…

MySQL学习笔记3——条件查询和聚合函数

条件查询和聚合函数 一、条件查询语句二、聚合函数1、SUM&#xff08;&#xff09;2、AVG()、MAX()、MIN()3、COUNT&#xff08;&#xff09; 一、条件查询语句 WHERE 和 HAVING 的区别&#xff1a; WHERE是直接对表中的字段进行限定&#xff0c;来筛选结果&#xff1b;HAVIN…

BUG:vue表单验证校验不报错,必填都有信息,就是不能正常往下进行

vue表单验证未报错却出现异常 框架bug场景解决办法 框架 UI&#xff1a;element-UI 前端&#xff1a;vue2 bug场景 正常表单里面&#xff0c;有的信息要求必填或者加了一些限制&#xff0c;作为校验验证&#xff0c;只有走到校验才会执行其他行为&#xff0c;比如调用保存接…

在 Linux 终端中创建目录

目录 ⛳️推荐 前言 在 Linux 中创建一个新目录 创建多个新目录 创建多个嵌套的子目录 测试你的知识 ⛳️推荐 前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到网站 前言 在本系列的这一部…