LeetCode03 - 无重复字符的最长子串(Java 实现)
LeetCode03 - 无重复字符的最长子串(Java 实现)
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/longest-substring-without-repeating-characters
题目描述
给定一个字符串,请你找出其中不含有重复字符的 最长子串 的长度。
示例 1:
输入: "abcabcbb"
输出: 3
解释: 因为无重复字符的最长子串是 "abc",所以其长度为 3。
示例 2:
输入: "bbbbb"
输出: 1
解释: 因为无重复字符的最长子串是 "b",所以其长度为 1。
示例 3:
输入: "pwwkew"
输出: 3
解释: 因为无重复字符的最长子串是 "wke",所以其长度为 3。
请注意,你的答案必须是 子串 的长度,"pwke" 是一个子序列,不是子串。
相关知识点补充
Java 数组的下标可以是:
- 整型常量
- 整型变量
- 整型字符常量(字符的 ASCII 码)
- 整型表达式
例如:
int a[300],i;
// 下标是整型常量,整数 5
a[5] = 5;
// 下标是整型变量, i 现在数值 5, 就是数组元素 a[5]。
i = 5;
a[i] = 5;
// 下标是整型字符常量,等于 F 的 ASCII 码值,就是数组元素 a[70]。
a['F'] = 5;
// 下标是整型表达式,表达式运算结果是 5,就是数组元素 a[5]。
a['F' - 'A'] = 5;
怎么查看 ASCII 码的值?
// 比如查看 a 的 ASCII 值
System.out.println((int)'a');
// 结果为 97
System.out.println((int)'z');
// 结果为 122
Java 实现与实现思路
import java.util.HashMap;
import java.util.Map;
/**
* <p>
* 03:给定一个字符串,请你找出其中不含有重复字符的最长子串的长度。
*
* @author XiaoPengwei
* @since 2019-07-14
*/
public class LC03LongestSubstring {
public static void main(String[] args) {
// 该代表性示例,最长为 4,即 abcd
// String str = "abcabcdbcs";
String str = "abba";
int lengthByMethod1 = lengthOfLongestSubstringMethod1(str);
System.out.println("lengthByMethod1-->" + lengthByMethod1);
int lengthByMethod2 = lengthOfLongestSubstringMethod2(str);
System.out.println("lengthByMethod2-->" + lengthByMethod2);
}
/**
* 方法一:
* 求不含有重复字符的最长子串的长度
* 思路:创建一个 pre 数组表示长度,从左到右遍历字符串数组,查看
*
* @param s 字符串参数
* @return int 长度
*/
public static int lengthOfLongestSubstringMethod1(String s) {
// 数组没有赋值的时,所有元素会初始化为 0
// 字符为下标时,会将 ASCII 码作为下标
int[] pre = new int[128];
int max = 0, t = 0;
// i 表示当前处理的第 i 个字符
for (int i = 0; i < s.length(); i++) {
// c 为依次取出的单个字符
char c = s.charAt(i);
/* 如果 pre[c] 不等于 0 表示数组中该位置被修改过,也就代表前面有重复字符
*/
if (pre[c] != 0 && pre[c] > t) {
// 更新 max 最大值
// i - t 重复元素下标 - 上一次没重复的下标
max = Math.max(max, i - t);
// t 是为求下一个子串长度做准备,因为要求出的是最长的子串长度
// 更新 t,上一次没重复的下标
t = pre[c];
}
// 如果 pre[c] 为 0,或者 pre[c] <= t
pre[c] = i + 1;
}
return Math.max(max, s.length() - t);
}
/**
* 方法二:
* 定义一个 map 数据结构存储 (k, v),其中 key 值为字符,value 值为字符位置 +1,加 1 表示从字符位置后一个才开始不重复
* 我们定义不重复子串的开始位置为 start,结束位置为 end; [start, end] 可理解为滑动窗口
* 随着 end 不断遍历向后,会遇到与 [start, end] 区间内字符相同的情况,此时将字符作为 key 值,获取其 value 值,并更新 start,此时 [start, end] 区间内不存在重复字符
* 无论是否更新 start,都会更新其 map 数据结构和结果 max。
* 时间复杂度:O(n)
*
* @param s 字符串参数
* @return int 长度
* @author guanpengchn
* @link https://leetcode-cn.com/problems/two-sum/solution/hua-jie-suan-fa-3-wu-zhong-fu-zi-fu-de-zui-chang-z/
*/
public static int lengthOfLongestSubstringMethod2(String s) {
// max 表示所求的最大长度
int max = 0;
/* Map 中 key 值为字符,value 值为字符位置 +1,加 1 表示从字符位置后一个才开始不重复
* 同一个字符 key,在 map 中只存在一个。当重复时更新它的值。
*/
Map<Character, Integer> map = new HashMap<Character, Integer>();
/* start 指向不重复子串的第一个字符的下标。
* 当存在重复字符时 start 指向后面一个重复字符,指向下一个不重复子串的第一个字符的下标
*/
for (int start = 0, end = 0; end < s.length(); end++) {
char c = s.charAt(end);
if (map.containsKey(c)) {
/* 如果含有重复字符串,将滑动窗户的开始位置更新,后移
* map.get(c) 的值表示该出现重复的字符,上一次出现时下标+1
* 什么时候会出现 start<map.get(c)?
* 答:map.get(c) 该重复字符出现的位置不一定,如果重复字符出现的顺序和之前一样,
* 比如:abcabcd,先重 a,再重 b
* 什么时候会出现 start>map.get(c)?
* 答:第二次出现重复时,如果重复的字符在第一次出现重复的字符前面
* 比如 abba,先重 b,再重 a。出现 a 重复时,start 为 2 > map.get('a') 为 1
*/
start = Math.max(map.get(c), start);
}
/* 不管是否重复这里都会执行
* 每次执行判断一次滑动窗口长度是否超过当前最大长度,是则更新
* end - start + 1 表示滑动窗口长度,子串长度,不重复子串最短也为 1
* 为什么要 + 1?
* 当 start 和 end 指向一个是元素时,下标一样,end-start 为 0,此时存在一个不重复子串为 1 个元素
* 当 end 指向 start 后面相邻一个,end-start 为 1,此时不重复子串为 2 个元素
*/
max = Math.max(max, end - start + 1);
/* 不管是否重复这里都会执行
* 如果不重复,会新添加一个 key,值为:位置下标+1
* 如果重复,会更新这个 key 对应的值为:后面又重复出现的该字符的位置下标+1
*/
map.put(c, end + 1);
}
return max;
}
}
LeetCode03 - 无重复字符的最长子串(Java 实现)的更多相关文章
- leetcode刷题第三天<无重复字符的最长子串>
给定一个字符串,请你找出其中不含有重复字符的 最长子串 的长度. 示例 : 输入: "abcabcbb" 输出: 解释: 因为无重复字符的最长子串是 . 示例 : 输入: &quo ...
- [Swift]LeetCode3. 无重复字符的最长子串 | Longest Substring Without Repeating Characters
Given a string, find the length of the longest substring without repeating characters. Examples: Giv ...
- [LeetCode] 3. 无重复字符的最长子串
题目链接:(https://leetcode-cn.com/problems/longest-substring-without-repeating-characters/) 题目描述: 给定一个字符 ...
- day4——无重复字符的最长子串
// 小白一名,0算法基础,艰难尝试算法题中,若您发现本文中错误, 或有其他见解,往不吝赐教,感激不尽,拜谢. 领扣 第2题 今日算法 题干 //给定一个字符串,请你找出其中不含有重复字符的 最长子串 ...
- leetcode 刷题(3)--- 无重复字符的最长子串
给定一个字符串,找出不含有重复字符的最长子串的长度. 示例 1: 输入: "abcabcbb" 输出: 3 解释: 无重复字符的最长子串是 "abc",其长度为 ...
- Leetcode(三)无重复字符的最长子串
3. 无重复字符的最长子串 题目描述 给定一个字符串,请你找出其中不含有重复字符的 最长子串 的长度. 示例: 输入: "abcabcbb" 输出: 3 解释: 因为无重复字符的最 ...
- 无重复字符的最长子串-LeetCode-第3题-C++
题目:无重复字符的最长子串 题目描述:给定一个字符串,找出不含有重复字符的最长子串的长度. 最长不重复子串可能有很多个,但是其长度只有一种. 方法一:暴力搜索法 方法二:滑动窗口 哈希表:要查找一个元 ...
- 【LeetCode】3. 无重复字符的最长子串
给定一个字符串,请你找出其中不含有重复字符的 最长子串 的长度. 示例 1: 输入: "abcabcbb" 输出: 3 解释: 因为无重复字符的最长子串是 "abc&qu ...
- [LeetCode]无重复字符的最长子串
给定一个字符串,找出不含有重复字符的最长子串的长度. 示例 1: 输入: "abcabcbb" 输出: 3 解释: 无重复字符的最长子串是 "abc",其长度为 ...
随机推荐
- 安装glance
在控制节点上执行 controllerHost='controller' MYSQL_PASSWD='m4r!adbOP' GLANCE_PASSWD='glance1234!' 1.创建数据库 my ...
- list-style-type:none是加在ul还是li中呢?
很多时候我们都需要多对列表元素进行初始化,方法是给列表元素添加list-style-type: none,但作为小白的我是经常纠结一个问题:是把它加在ul中还是li中呢 我试了一下,加在ul和li都能 ...
- el-tree点击获取直接父级的属性
这里是可以一直往上获取它的直接父级的所有属性以及状态 通过这两个事件其中的一个 在方法里可以写上 methods:{ curCheck(data,state){ const curNode = thi ...
- 网络流三大算法【邻接矩阵+邻接表】POJ1273
网络流的基本概念跟算法原理我是在以下两篇博客里看懂的,写的非常好. http://www.cnblogs.com/ZJUT-jiangnan/p/3632525.html http://www.cnb ...
- 记:SpringBoot项目莫名出现ClassNotFoundException
最近某个开发环境的某个应用,隔三差五出现了某某页面找不到,网上百度找了些同类的问题都是说jstl包与默认tomcat里的包冲突,但都感觉和我的问题不是很搭配(因为相同框架的其他项目都可以正常允许) 报 ...
- Redis基础与持久化
Redis介绍 软件说明 Redis是一款开源的,ANSI C语言编写的,高级键值(key-value)缓存和支持永久存储NoSQL数据库产品. Redis采用内存(In-Memory)数据集(Dat ...
- STL string 常见用法详解
string 常见用法详解 1. string 的定义 //定义string的方式跟基本数据类型相同,只需要在string后跟上变量名即可 string str; //如果要初始化,可以直接给stri ...
- 学习实践:使用模式,原则实现一个C++数据库访问类
一.概述 在我参与的多个项目中,大家使用libMySQL操作MySQL数据库,而且是源码即复用,在多个项目中有多套相同或相似的源码,这样的复用方式给开发带来了不变,而且libMySQL的使用比较麻烦, ...
- hdfs架构详解(防脑裂fencing机制值得学习)
HDFS(Hadoop Distributed File System)是一个分布式文件存储系统,几乎是离线存储领域的标准解决方案(有能力自研的大厂列外),业内应用非常广泛.近段抽时间,看一下 HDF ...
- QT 获取字体大小
QFont font(androidFont); QFontInfo fInfo(font); qDebug()<<"FFFFFFFFFFFFFFFFFFFFFFFPPPSIZE ...