IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 数据结构与算法 -> 【贪心算法-LeetCode3:无重复字符的最长子串(Java实现)】 -> 正文阅读

[数据结构与算法]【贪心算法-LeetCode3:无重复字符的最长子串(Java实现)】

个人社区: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;
    }
}
  数据结构与算法 最新文章
【力扣106】 从中序与后续遍历序列构造二叉
leetcode 322 零钱兑换
哈希的应用:海量数据处理
动态规划|最短Hamilton路径
华为机试_HJ41 称砝码【中等】【menset】【
【C与数据结构】——寒假提高每日练习Day1
基础算法——堆排序
2023王道数据结构线性表--单链表课后习题部
LeetCode 之 反转链表的一部分
【题解】lintcode必刷50题<有效的括号序列
上一篇文章      下一篇文章      查看所有文章
加:2022-10-31 12:25:10  更:2022-10-31 12:28:53 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/25 19:36:02-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码