【贪心算法-LeetCode3:无重复字符的最长子串(Java实现)】

news2024/9/21 18:47:37

无重复字符的最长子串

  • 一、题目描述
    • 1.题目内容
    • 2.样例
  • 二、解决方案
    • 1.算法流程
    • 1)分析
  • 2)算法流程
    • 2.Java代码
    • 1)核心代码
    • 2)完整测试代码

个人社区:https://bbs.csdn.net/forums/smile
个人主页:https://blog.csdn.net/qq_43665602
欢迎各位志同道合的朋友,一起学习!

一、题目描述

1.题目内容

给定一个字符串 s ,请你找出其中不含有重复字符的 最长子串 的长度。

2.样例

在这里插入图片描述

二、解决方案

看见这种求最优解的问题,可以尝试使用贪心算法,尤其对于集合覆盖问题、区间问题以及分配问题。

贪心算法:求局部最优(当前最优),以使最终结果为最优解或者近似最优解。

本题目的是求出给定字符串S中不含重复字符的最长子串,很自然地可以想到,我们可以通过逐步求解当前无重复最长子串,最后得到字符串S中不含重复字符的最长子串。
需要注意子串必须是连续的,要与子序列区分。

1.算法流程

1)分析

以样例1和样例2为例,我通过图解分析一下求解无重复字符最长子串的过程:
样例1,S=“abcabcbb”,从字符串开头开始分别以当前字符为起点,确定此时的无重复字符的最长子串:
(1)i=0:起点为a,最长子串为abc,长度为3;
(2)i=1:起点为b,最长子串为bca,长度为3;
(3)i=2:起点为c,最长子串为cab,长度为3;
(4)i=3:起点为a,最长子串为abc,长度为3;
(5)i=4:起点为b,最长子串为bc,长度为2;
(6)i=5:起点为c,最长子串为cb,长度为2;
(7)i=6:起点为b,最长子串为b,长度为1;
(8)i=7:起点为b,最长子串为b,长度为1;
可看到第一次确定的子串长度为3,此后子串长度均小于等于3,所以最长子串为abc,其长度为3。
在这里插入图片描述
样例2,S=“pwwkew”,从字符串开头开始分别以当前字符为起点,确定此时的无重复字符的最长子串:
(1)i=0:起点为p,最长子串为pw,长度为2;
(2)i=1:起点为w,最长子串为w,长度为1;
(3)i=2:起点为w,最长子串为wke,长度为3;
(4)i=3:起点为k,最长子串为kew,长度为3;
(5)i=4:起点为e,最长子串为ew,长度为2;
(6)i=5:起点为w,最长子串为w,长度为1;
在这里插入图片描述

可看到第三次确定的子串长度为3,此后子串长度均小于等于3,所以最长子串为wke,其长度为3。
从上面的图示中可以清晰看到最长子串的确定过程,由此可归纳出我们的算法流程,便于代码编写。

2)算法流程

选择策略:确定当前最长无重复子串,遇到重复字符即说明可确定当前最长无重复子串.

  • (1)依次遍历字符串,使用集合存储每个元素(这里使用HashSet);
  • (2)如果集合中存在当前指向的字符,说明有重复:比较此时maxLen与set.size的大小决定是否更新maxLen;
  • (3)循环(1-2),如果遇到更长子串,则更新maxLen; 如果剩余子串长度小于等于maxLen则停止遍历;

需要注意特殊情况:如果字符串为空串或者其长度为1,说明其最长无重复子串为其本身。

2.Java代码

1)核心代码

class Solution {
    /**
     * 选择策略:当前最长无重复子串,遇到重复字符就重置
     */
    public int lengthOfLongestSubstring(String s) {
        if (s.length()<=1){  // 如果字符串为空串或者其长度为1,说明其最长无重复子串为其本身
            return s.length();
        }
        int n=s.length();
        Set<Character> withoutRepeat=new HashSet<>();  // 存储当前子串
        int i=0,maxLen=0;
        while (i<n){  // 依次遍历每个字符
            withoutRepeat.clear();  // 存储新的子串需要重置Set
            int j=i; 
            while (j<n){ // 寻找当前字符开始的最长子串
                if(withoutRepeat.contains(s.charAt(j))){  // 遇到重复字符就停止寻找
                    break;
                }
                withoutRepeat.add(s.charAt(j));
                j++;
            }
            if((j-i+1)>maxLen){  // 确定是否更新maxLen,j-i+1为当前子串长度
                maxLen=j-i;
            }
            if (maxLen>=(n-i+1)){ // 如果剩余子串长度小于等于maxLen则停止遍历
                break;
            }
            i++;
        }
        return maxLen;
    }
}

2)完整测试代码

import java.util.HashSet;
import java.util.Set;

/**
 * LeetCode3:无重复字符的最长子串
 */
public class WithoutRepeat {
    public static void main(String[] args) {
        String s = "abcabcbb";
//        String s = "bbbbbb";
//        String s = "pwwkew";
//        String s = "au";
        System.out.println(new RepeatSolution().lengthOfLongestSubstring(s));
    }
}

class RepeatSolution {
    /**
     * 选择策略:当前最长无重复子串,遇到重复字符就重置
     * @param s
     * @return
     */
    public int lengthOfLongestSubstring(String s) {
        if (s.length()<=1){
            return s.length();
        }
        int n=s.length();
        Set<Character> withoutRepeat=new HashSet<>();
        int i=0,maxLen=0;
        while (i<n){  // 依次遍历每个字符
            withoutRepeat.clear();
            int j=i;  // 寻找当前字符开始的最长子串
            while (j<n){
                if(withoutRepeat.contains(s.charAt(j))){
                    break;
                }
                withoutRepeat.add(s.charAt(j));
                j++;
            }
            if((j-i+1)>maxLen){
                maxLen=j-i;
            }
            if (maxLen>=(n-i+1)){
                break;
            }
            i++;
        }
        return maxLen;
    }
}

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

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

相关文章

STM32G070RBT6基于STM32CubeMX创建定时器中断控制LED闪烁

STM32G070RBT6基于STM32CubeMX创建定时器中断控制LED闪烁&#x1f4cd;相关篇《【硬件开源电路】STM32G070RBT6开发板》&#x1f33a;配置内容演示&#xff1a; &#x1f4da;功能介绍 &#x1f4d1;通过STM32CubeMX配置定时器1和定时器3分别作为两个led的定时闹钟。这里作为…

单片机原理及应用实验一交通信号系统(基于Proteus仿真)

1.实验内容与要求 交通信号系统是保障交通安全高效的重要设施。51单片机价格低廉、体积小、低功耗、抗干扰性好等优点&#xff0c;适用于交通信号系统中&#xff0c;本实验利用51单片机IO口的开关量的输入输出功能及内部CPU运算功能&#xff0c;设计一个简易的交通信号灯系统&…

生成.keystore 安卓签名

需要有openssl.exe和keytool.exe支持 signapk.jar手动签名命令 java -jar signapk.jar pl.x509.pem pl.pk8 smartrecord_3.5.8.apk smartrecord_3.5.8-signed.apk除了直接使用signapk.jar签名外&#xff0c;还可以将签名文件生成keystore文件&#xff0c;然后配置编译器给apk进…

数据分析 | Pandas 200道练习题,每日10道题,学完必成大神(5)

文章目录前期准备1. 将create Time列设置为索引2. 生成一个和df长度相同的随机数DataFrame3. 将上一题生成的DataFrame与df合并4. 生成的新的一列new值为salary列减去之前生成的随机数列5. 检查数据中是否含有空值6. 将salary类型转换成浮点数7. 计算salary 大于10000的次数8. …

多线程之线程池

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录前言一、什么是线程池二.为什么要有线程池引入&#xff1a;为什么从池子里取&#xff0c;比创建线程速度要快什么是用户态&#xff0c;什么是内核态最终结论&#xf…

aws 负载均衡clb/nlb/alb

目录 概述 传统负载均衡器&#xff08;Classic Load Balancer&#xff09; DNS解析 健康检查&#xff08;Health Check) 监听器&#xff08;Listeners&#xff09; 连接耗尽&#xff08;Connection Draining&#xff09; 粘性会话/会话关联&#xff08;Sticky Sessions/…

(四)手写简单版MyBatis框架

文章目录环境搭建第一步&#xff1a;资源⼯具类第二步&#xff1a;定义SqlSessionFactoryBuilder类第三步&#xff1a;定义SqlSessionFactory类第四步&#xff1a;定义JDBC事务管理器第五步&#xff1a;定义数据源类第六步&#xff1a;定义MyMappedStatement类第七步&#xff1…

基于遗传算法卡车无人机旅行推销员问题(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

Leetcode刷题111. 二叉树的最小深度

给定一个二叉树&#xff0c;找出其最小深度。 最小深度是从根节点到最近叶子节点的最短路径上的节点数量。 说明&#xff1a;叶子节点是指没有子节点的节点。 示例 1&#xff1a; 输入&#xff1a;root [3,9,20,null,null,15,7] 输出&#xff1a;2 示例 2&#xff1a; 输入…

Python_机器学习_算法_第7章_7.拓展知识

Python_机器学习_算法_第7章_7.拓展知识 文章目录Python_机器学习_算法_第7章_7.拓展知识7.拓展知识7.1. 其他距离公式1 标准化欧氏距离2 余弦距离3 汉明距离【了解】4 杰卡德距离【了解】5 马氏距离【了解】7.2.再议数据分割1 留出法2 交叉验证法2.1 交叉验证法基本介绍2.2 KF…

ARM发布Cortex-X3和Cortex-A715

快速链接: . &#x1f449;&#x1f449;&#x1f449; 个人博客笔记导读目录(全部) &#x1f448;&#x1f448;&#x1f448; 付费专栏-付费课程 【购买须知】: 【精选】ARMv8/ARMv9架构入门到精通-[目录] &#x1f448;&#x1f448;&#x1f448; ARM公司发布了第二代 AR…

x86 smbus 下挂eeprom不能写问题

目录 背景 分析 驱动影响 SPD register 接口 只读 修改验证 总结 背景 x86 smbus上下挂一个eeprom&#xff0c;只能读取&#xff0c;不能写入。 写入命令采用&#xff1a; i2cset -y -f 0 0x50 0 0x33 即向总线0 下的0x50 地址的eeprom偏移量0 写入数据0x33&#xff0c; 命令…

哈夫曼树原理及Java编码实现

文章目录前言一、哈夫曼树原理二、哈夫曼编码&#xff08;Java题解&#xff09;参考资料前言 所有博客文件目录索引&#xff1a;博客目录索引(持续更新) 源代码&#xff1a;Gitee—Huffman.java、Github—Huffman.java 一、哈夫曼树原理 对于哈夫曼树的构造以及权值计算原理…

Java语言高级-10MySQL-第2节MySQL安装与使用

2、MySQL数据库软件 1、安装 详细见视频 2、卸载 1、去mysql的安装目录找到my.ini文件 “复制datadir “C:/programData/MySQL/MySQL Server 5.5/Data” 2、卸载MySQL 控制面板->程序卸载&#xff0c;但是此时并没有卸载干净 3、删除C:/ProgramData目录下得MySQL文件夹 注意…

java 内部类

小镇做题家 前段时间很火的一个话题“小镇做题家”&#xff0c;我没有具体了解&#xff0c;我以为是在鼓励一些努力拼搏的人。 某一天&#xff0c;禁不住好奇&#xff0c;我打开了百度百科&#xff0c;看了看小镇做题家的解释 就是指一些村里或者小镇的人&#xff0c;通过学习…

模板和泛型编程(上)

目录函数模板泛型编程函数模板概念及原理函数模板的实例化函数模板的匹配原则类模板类模板实例化函数模板 泛型编程 泛型编程&#xff08;Generic Programming&#xff09;最初提出时的动机很简单直接&#xff1a;发明一种语言机制&#xff0c;能够帮助实现一个通用的标准容器…

猿创征文|Python迭代器、生成器、装饰器、函数闭包

欢迎关注博主 Mindtechnist 或加入【Linux C/C/Python社区】一起探讨和分享Linux C/C/Python/Shell编程、机器人技术、机器学习、机器视觉、嵌入式AI相关领域的知识和技术。 Python迭代器、生成器、装饰器、函数闭包1. 迭代器 iterator☞迭代器协议☞Python中的for循环2. 生成器…

C语言qsort()函数针对:整型、单个字符、字符串、结构体,超详细讲解(多维度分析举例,小白一看就懂!!!!!)

目录 一、前言 二、qsort()函数 &#x1f351;qsort()函数简介 &#x1f349;qsort()函数中整型、double型、字符型的应用 &#x1f4a6;整型 &#x1f4a6; double型 &#x1f4a6;字符排序 &#x1f34e;qsort()函数在字符串中的应用 &#x1f4a6;在字符串中按首字母…

Android NDK开发基础

文章目录cmake语法基础cmake添加日志&#xff1a;cmake增加宏字符串比较cmake在build.gradle中传递编译参数到cmake通过javah生成native对应的c头文件jni和java之间字符串的相互操作JavaVM和JNIEnv字符串的编码native方法静态注册和动态注册静态注册动态注册extern cC中STATIC和…

SpringCloud Alibaba-Sentinel保姆级教程

文章目录1、Sentinel前奏1.1、服务雪崩效应1.2、常见容错方案1、隔离2、超时3、限流4、熔断5、降级1.3、常见容错组件1、Hystrix2、Resilience4J3、Sentinel2、Sentinel入门2.1、什么是Sentinel2.2、实战编码1、安装Sentinel服务端2、微服务引入Sentinel2.3、Sentinel流控模式1…