力扣hot100——第6天:32最长有效括号、33搜索旋转排序数组、34在排序数组中查找元素的第一个和最后一个位置

news2024/11/15 13:41:38

文章目录

  • 1.32最长有效括号
    • 1.1.题目
    • 1.2.解答
  • 2.33搜索旋转排序数组
    • 2.1.题目
    • 2.2.解答
  • 3.34在排序数组中查找元素的第一个和最后一个位置【代码随想录已刷】

1.32最长有效括号

参考:力扣题目链接;题解1,题解2

1.1.题目

在这里插入图片描述

1.2.解答

这道题目官方的题解讲解的就非常清除了,现在摘录如下:

在这里插入图片描述注意:注意dp数组的定义,dp[i]一定是以i为结尾的字符子串,也就是必须包含s[i]

尤其注意第二种情况,也就是s[i-1] = ')'的时候,此时当前的s[i] = ')'无法跟s[i-1]匹配直接构成一个有效的字符子串,所以s[i]需要到前面去寻找,看是否有和它匹配的(。所以问题就变成,我该去前面的什么位置寻找呢?肯定不能随便选一个(的位置就和他匹配,因为这样会导致这个匹配的(和当前的s[i]之间的字符串不一定是合法的括号字符子串。

所以我们寻找之前的(的前提就是先让中间的字符串是一个合法的字符子串。也就是先去考虑s[i-1]')',因为他已经在上一步经过计算了,不管以它结尾的字符子串是不是一个合法的括号字符子串,都可以找到它对应的字符串的头字符。那么我们分两种情况假设:

  • 假设以它结尾的字符和之前的某个头(构成了一个合法的括号字符子串,也就是上面题解中说的sub_s。所以这个sub_s对应的头字符串的位置就是i-1 - dp[i-1] + 1,其中i-1s[i-1]的位置,dp[i-1]是以s[i-1]=')'为结尾的合法括号字符子串的长度,最后再+1是因为我们要找到s[i-1]对应的头字符(。比如长度是2的子串,当前尾巴-2之后位置是头字符串的前一个位置,所以我们要再+1移动到后面的一个位置,才是头字符(的位置。但是实际上最后我们想找的位置是s[i]对应的头位置,所以最后还需要再-1向前移动一位,因此最后和s[i]对应的头(的位置就是i-1 - dp[i-1]
  • 假设以它结尾的字符没有和之前的某个(构成一个合法的括号字符子串,也就是dp[i-1] = 0。那么和s[i]对应的头(的位置就是i-1 - dp[i-1] = i-1,很显然此时结果就是s[i-1] = ')',不是(,所以不满足要求。但是不影响我们后面的计算。

在找到了s[i]对应的有可能合法的最前面的头字符之后,我们就要判断:

  • 如果这个位置的字符是(,即s[i-1-dp[i-1]] = '(',那么当前的s[i]可以和这个字符构成有效括号字符子串,所以此时从i-1-dp[i-1]i位置的子串就构成了一个有效的字符子串。但是此时注意:以i-1-dp[i-1]-1的子串也有可能仍旧可以构成有效的子串,所以最后以i结尾的有效子串的长度 = i-1-dp[i-1]i的长度 + 以i-1-dp[i-1]-1为结尾的子串的长度。

  • 如果这个位置的字符是),那么前面一顿计算都白费了,此时s[i] = ')'不能和这个位置的)构成有效的子串,所以dp[i] = 0

最后给出代码如下,其实并不是很难。关键是要注意,计算了当前结尾的子串的长度之后,不要忘了加上i-1-dp[i-1]-1结尾的子串的长度。

int longestValidParentheses(string s)
{
    // 定义dp数组,并且全部初始化成0
    vector<int> dp(s.size(), 0);  // string.length()和string.size()结果是一样的,不存在任何区别
    int result = 0;   // 记录最长的长度

    // 开始遍历,执行动态规划
    for(int i = 1; i < s.size(); i++)   // i = 0的位置不管是什么子串,肯定都不是有效括号,所以直接跳过即可
    {
        if(s[i] == ')')  // 只有)需要处理,因为以(结尾的子串一定不能构成有效的子串
        {
            // 前一个是(,则i和i-1直接可以构成一个(),所以有效子串长度就是i-2结尾的有效子串长度+2
            if(s[i-1] == '(')
            {
                if(i >= 2)  // 防止数组索引越界
                    dp[i] = dp[i-2] + 2;
                else
                    dp[i] = 2;
            }   
            // 前一个是),则需要判断i-1结尾的有效子串
            else
            {
                // i-1结尾的子串长度是0,说明i-1结尾的就无法构成子串,由于i结尾的一定包含i-1,
                // 所以也无法构成子串。因此这里我们只需要考虑构成子串的情况,即dp[i-1] > 0
                if(dp[i-1] == 0)
                {
                    dp[i] = 0;   // 可省略,由初始化赋值
                }
                else
                {
                    // 当前)和前面的(构成匹配,同时要注意防止数组索引越界,比如())这种情况
                    if(i-1-dp[i-1] >= 0 && s[i-1-dp[i-1]] == '(')  
                    {
                        // i-1-dp[i-1]-1结尾的有效子串长度 + i-1结尾的有效子串长度 + 2
                        if(i-1-dp[i-1]-1 >= 0)   // 防止数组索引越界
                            dp[i] = dp[i-1-dp[i-1]-1] + dp[i-1] + 2;
                        else
                            dp[i] = dp[i-1] + 2;
                    }
                    else
                    {
                        dp[i] = 0;
                    }
                }
            }
        }
        else
        {
            dp[i] = 0;   // 可省略,由初始化赋值
        }

        result = max(result, dp[i]);
    }

    return result;
}

上述代码可以发现非常繁杂,主要是把dp[i] = 0的情况也写出来了, 实际上这个不用写用初始化赋值的0也可以。另一个就是在访问数组元素的时候需要时刻判断防止越界,这个问题可以通过增加判断和三元运算符来解决,因此简化代码如下:

int longestValidParentheses(string s)
{
    // 定义dp数组,并且全部初始化成0
    vector<int> dp(s.size(), 0);  // string.length()和string.size()结果是一样的,不存在任何区别
    int result = 0;   // 记录最长的长度

    for(int i = 1; i < s.size(); i++)
    {
        if(s[i] == ')')
        {
            if(s[i-1] == '(')
                dp[i] = (i >= 2 ? dp[i-2] : 0) + 2;
            else
            {
                if(i-1-dp[i-1] >= 0 && s[i-1-dp[i-1]] == '(')
                    dp[i] = (i-1-dp[i-1]-1 >= 0 ? dp[i-1-dp[i-1]-1] : 0) + dp[i-1] + 2;
            }
        }

        result = max(result, dp[i]);
    }

    return result;
}

2.33搜索旋转排序数组

参考:力扣题目链接;题解1,题解2

2.1.题目

在这里插入图片描述

2.2.解答

题解1和题解2给出的解答都比较好,这里摘录题解1的讲解如下,其中说了一句二分的本质就是根据是否满足性质进行二分

在这里插入图片描述
最后给出代码如下:

int search(vector<int> &nums, int target)
{
    if(nums.empty())
        return -1;
    if(nums.size() == 1)
        return (nums[0] == target ? 0 : -1);

    // [left, right] 二分数组,以mid划分数组为[left, mid-1], middle, [mid+1, right]
    // 三种情况:左升序、右无序;左升序、右升序;左无序、右升序
    int left = 0;
    int right = nums.size() - 1;
    while (left <= right)
    {
        int middle = left + (right - left)/2;
        if(nums[middle] == target)
            return middle;
        else
        {
            // 左升序,则应该用左区间去判断边界
            // 注意一定要<=,比如[3,1]中寻找1这种情况。主要就是数组长度为2时,由于/2是向下取整,
            // 所以结果是left = middle。
            if(nums[left] <= nums[middle])   
            {
                // 结果不在左区间中
                if(target < nums[left] || target > nums[middle])   
                    left = middle + 1;
                else    // 结果在左区间中
                    right = middle - 1;     
            }
            else   // 右升序
            {
                // 结果不在右区间中
                if(target < nums[middle] || target > nums[right])  
                    right = middle - 1;
                else
                    left = middle + 1;
            }
        }
    }

    return -1;  // 实际执行不到这里
}

注意:代码中的if(nums[left] <= nums[middle])必须是<=,而不能是<,这样的话有一个测试用例[3, 1]中寻找1会输出索引为-1,也就是没找到,这样是错误的。具体自己还没想明白为什么会这样。。。

3.34在排序数组中查找元素的第一个和最后一个位置【代码随想录已刷】

参考:力扣题目链接;自己的博客总结

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

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

相关文章

FAT12文件系统

简介 FAT12文件系统是指&#xff1a;在磁盘上规定一种特定的存储格式&#xff0c;这种存储格式高效方便&#xff0c;功能强大&#xff0c;因此形成了统一的规定。 基础知识 具体来说FAT12文件系统为1.44M的软盘设计。1.44M的软盘有2880个扇区&#xff0c;一个扇区有512个字节&…

大数据下一代变革之必研究数据湖技术Hudi原理实战双管齐下-后续

文章目录集成Flink编程示例打包运行CDC入湖概述MySQL 启用 binlog初始化MySQL 源数据表准备Jar包依赖flink读取mysql binlog写入kafkaflink读取kafka数据并写入hudi数据湖调优MemoryParallelismCompaction集成Hive集成步骤Flink同步HiveHive Catalog集成Flink 编程示例 本节通…

[附源码]计算机毕业设计springboot右脑开发教育课程管理系统

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

微服务框架 SpringCloud微服务架构 10 使用Docker 10.4 容器命令案例1

微服务框架 【SpringCloudRabbitMQDockerRedis搜索分布式&#xff0c;系统详解springcloud微服务技术栈课程|黑马程序员Java微服务】 SpringCloud微服务架构 文章目录微服务框架SpringCloud微服务架构10 使用Docker10.4 容器命令案例110.4.1 直接开干10.4.2 总结10 使用Docke…

03_openstack之项目及用户管理

目录 一、环境准备 二、项目管理 1、项目介绍 2、创建项目 三、用户管理 1、用户介绍 2、创建用户 一、环境准备 部署openstack私有云环境&#xff0c;步骤&#xff1a;02_openstack私有云部署_桂安俊kylinOS的博客-CSDN博客 以下操作均基于上述环境 二、项目管理 1、…

[附源码]计算机毕业设计springboot在线票务系统

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

基于采样的规划算法之RRT家族(三):RRT*

RRT算法是边随机产生节点边生长一棵路径树,当这棵树与目标点相遇,便从相遇点回溯到起点得到路径解。对于新产生的随机节点,原始RRT算法将路径树上距离它最近的节点作为它的父节点,并不能保证新节点通过该父节点就是最短路径。并且,就算新节点连接是最优的,也无法保证未来…

快速统计文本数字之和

实例需求&#xff1a;A列到F列为文本数据&#xff0c;每个单元格中包含3个数字&#xff0c;数字之间使用竖线分隔&#xff0c;现需要计算每个单元格中的数字之后。 例如F15单元格内容为10┃5┃18&#xff0c;则需要计算10、5、18三个数字之和&#xff0c;结果为33&#xff0c;…

【RTS】李宇翔 monibuca 讲座 学习

不解码,如何跳帧、追帧。启动工程,方便二次开发 按需引入引擎和插件流媒体应用 监控 : 物联网。转发 :用于会议,里面有很多会控逻辑,不同于流媒体本身。 起源于 FLASH视频会议 cs fms ams ,red5crtmpserver 很多问题 streaming服务器很难开发monaserver 基础上开发monib…

事业编招聘:新华社2023校园招聘正式启动

新华社是党中央一手创办和领导的新闻舆论机构&#xff0c;随着中国人民的革命事业和社会主义建设事业的发展而成长壮大&#xff0c;是一个具有光荣历史和优良传统作风的新闻机构。 新华社作为党中央喉舌、耳目、智库&#xff0c;是党的新闻舆论工作主力军、主渠道、主阵地。 …

【随笔记】分享一下26个常用的IDEA插件

文章目录1. Chinese Language2. Atom Material Icon3. Rainbow Brackets4. Translation5. Codota6. GenerateAllSetter7. GsonFormatPlus8. Alibaba Java Coding Guidelines9. Free Mybatis Tool10. maven-search11. Maven Helper12. CodeGlance Pro13. MyBatisCodeHelperPro14…

[附源码]计算机毕业设计学生在线考试系统Springboot程序

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

[附源码]计算机毕业设计颐养天年辅助平台Springboot程序

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

[附源码]JAVA毕业设计健康生活网站(系统+LW)

[附源码]JAVA毕业设计健康生活网站&#xff08;系统LW&#xff09; 目运行 环境项配置&#xff1a; Jdk1.8 Tomcat8.5 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&…

114页5万字字智能交通大数据综合服务平台建设方案

目录 1.项目概述 1 1.1 项目名称 2 1.2 项目承担单位 2 1.3 建设方案编写单位 2 1.4 建设方案编制依据 2 1.5 建设目标、规模、周期 4 2.项目建设的必要性和可行性 6 2.1 现状及成果 6 2.1.1 xxx县交通运输局 6 2.2.2 公路管理领域 7 2.2.3 港航管理领域 7 2.2.4 工程质监领域 …

URL转发请求

URL转发请求目录概述需求&#xff1a;设计思路实现思路分析1.一种方法2.第二种方法&#xff1a;参考资料和推荐阅读Survive by day and develop by night. talk for import biz , show your perfect code,full busy&#xff0c;skip hardness,make a better result,wait for ch…

谷粒商城十二性能压测

在分布式开发中&#xff0c;我们将每一一种服务都抽取成一个独立的模块&#xff0c;微服务模块在真正的上线之前&#xff0c;甚至是上线以后&#xff0c;我们都要进行压力测试&#xff0c;才能投入正常的使用。 压力测试是为了我们的系统在当前软硬件环境下&#xff0c;最大的…

uni-app引入海康威视h5player实现视频监控的播放

uni-app引入海康威视h5player实现视频监控的播放知识储备工具下载webplayer.htmlh5player.vue知识储备 uni-app web-view组件相关知识&#xff1a;点击学习。海康威视相关工具下载&#xff1a;点击跳转下载。web-view组件不全屏显示&#xff1a;uni-app web-view 如果设置不全…

[附源码]计算机毕业设计医学图像管理平台Springboot程序

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

XXL-Job集群部署

文章目录一、调度中心集群部署1. 优点2. 集群需要满足的条件3. 集群部署方案二、任务执行器的集群配置2.1. 集群地址配置2.2. 执行器名称配置2.3. 执行器端口三、路由策略一、调度中心集群部署 1. 优点 调度中心支持集群部署&#xff0c;提升调度系统容灾和可用性&#xff1b…