从零打卡leetcode之day 4--无重复最长字符串
题目描述:
给定一个字符串,找出不含有重复字符的最长子串的长度。
示例:
给定 "abcabcbb"
,没有重复字符的最长子串是 "abc"
,那么长度就是3。
给定 "bbbbb"
,最长的子串就是 "b"
,长度是1。
给定 "pwwkew"
,最长子串是 "wke"
,长度是3。请注意答案必须是一个子串,"pwke"
是 子序列 而不是子串。
解题过程:
方法一:暴力版本
显然,对于这道题我们可以像以往一样,遍历所有子串,对于这个方法,我相信大家都能想到,我就直接贴代码了。如下
//三个for暴力解决
public static int lengthOfLongestSubstring(String s) {
int max = 0;
int temp = 0;
char[] arr = new char[s.length()];
for(int i = 0; i < s.length(); i++){
arr[i] = s.charAt(i);
temp = 1;
for(int j = i + 1; j < s.length(); j++){
int flag = 0;//用来判断s[j]是否在arr中
for(int k = i; k < i + temp; k++){
if(arr[k] == s.charAt(j)){
flag = 1;
break;
}
}
if(flag == 1){ break;//重复
} else {
arr[i+temp] = s.charAt(j);
temp++;
}
}
if(temp > max){
max = temp;
}
}
return max;
}
前面两个for循环用来遍历所有子串,第三个for循环用来判断字符s.charAt(j)是否在子串中。
方法二:各种优化
优化策略1:大家想一个问题,对于第三个循环,我们在数组里查找该数组是否拥有某个字符,这个查找的过程的时间复杂度是O(n),我们是否有其他什么方法把查找的过程的复杂度降低到O(1)?
前几次我们都有用过hashMap来进行映射,实际上这里一样可以用hashMap来保存子串,然后再判断s.charAt(j)是否子串中,这样我们就可以把查找过程的复杂度降低到O(1)了。
优化策略2:假如给你一个字符串:
"abcdca"
我们在遍历子串的过程中,最开始我们从第一个元素'a'开始遍历,当我们遍历到'abcd'时,在继续查找的时候遇到'c',此时"abcd"里面已经有'c'了,此时该子串查找完毕。此时长度为4,继续下一个子串的查找。
注意:我们继续下一个子串查找的时候,是从第二个元素'b'开始的。可是大家想一个问题,真的有必要从第二个元素'b'开始查找吗?,假如我们从'b'开始的时候,遍历到"bcd",继续遍历时又会再次遇到'c',此时长度为3。比上一个子串4的长度小。
实际上,我们是没有必要从第二个元素开始查找的。我们直接从'd'开始查找就可以了,也就是说,如果 s[j]s[j] 在 [i, j)[i,j) 范围内有与 j'j′ 重复的字符。我们再下一次寻找子串时,直接从j'+1的位置开始就行了。如果你不是很理解为啥会这样的话,可以找一些元素模拟一下勒。
优化策略3:我们每次在寻找子串的时候,会把子串放进hashMap里,假如我们要寻找下一个子串的话,理论上是需要把hashMap里面的元素给清空,然后再用来放置新的子串的。
但实际上,是不需要这样子的,hashMap里面的元素是可以重复利用的。先上代码吧,然后我在画图解释下优化策略三。如下:
//用hashMap映射
public static int lengthOfLongestSubstring2(String s) {
int max = 0;//保存最长子串的长度
//用来记录子串是从哪个下标开始的
int i = 0;
Map<Character, Integer> map = new HashMap<>();
for(int j = 0; j < s.length(); j++){
if(map.containsKey(s.charAt(j))){
//从第一个重复元素的后一个开始
i = Math.max(map.get(s.charAt(j))+ 1, i);
}
//j - i + 1 表示计算此时子串的长度
max = Math.max(max, j - i + 1);
map.put(s.charAt(j), j);
}
return max;
}
假设字符串为"abcba",下面演示hashMap中元素的变化情况。
当j = 2。
当j = 3是,此时出现重复的字符(黄色的表示已经被代替的字符)。
当j = 4时。
j = 4时,hashMap有重复的字符a(下标为0的那个),为啥不会把i定位到下标为2的元素上?(因为它都已经遍历到从下标我为3的那里了,怎么可能还会倒回去)
这种方法的时间复杂度为O(n)。
完
从零打卡leetcode之day 4--无重复最长字符串的更多相关文章
- 从零打卡leetcode之day 2---两数相加
前言 就是要把leetcode刷完,每天一道题,每天进步一点点. 从零打卡leetcode之day 2 题目描述: 给定两个非空链表来表示两个非负整数.位数按照逆序方式存储, 它们的每个节点只存储单个 ...
- 从零打卡leetcode之day 1--两数之和
前言 就是要把leetcode的题刷完,每天一道题,每天进步一点点 从零打卡leetcode之day 1 题目描述: 给定一个整数数组和一个目标值,找出数组中和为目标值的两个数. 你可以假设每个输入只 ...
- Leetcode(3)无重复字符的最长子串
Leetcode(3)无重复字符的最长子串 [题目表述]: 给定一个字符串,请你找出其中不含有重复字符的 最长子串 的长度. 第一种方法:暴力 执行用时:996 ms: 内存消耗:12.9MB 效果: ...
- 【LeetCode题解】3_无重复字符的最长子串(Longest-Substring-Without-Repeating-Characters)
目录 描述 解法一:暴力枚举法(Time Limit Exceeded) 思路 Java 实现 Python 实现 复杂度分析 解法二:滑动窗口(双指针) 思路 Java 实现 Python 实现 复 ...
- leetcode题解#3:无重复字符的最长子串
leetcode题解:无重复字符的最长子串 题目 给定一个字符串,请你找出其中不含有重复字符的 最长子串 的长度. 示例 1: 输入: s = "abcabcbb"输出: 3 解释 ...
- Leetcode题库——3.无重复字符的最长子串
@author: ZZQ @software: PyCharm @file: lengthOfLongestSubstring.py @time: 2018/9/18 20:35 要求:给定一个字符串 ...
- leetcode刷题3.无重复字符的最长子串
题目:给定一个字符串,找出不含有重复字符的 最长子串 的长度. 示例: 给定 "abcabcbb" ,没有重复字符的最长子串是 "abc" ,那么长度就是3. ...
- LeetCode 第三题--无重复字符的最长子串
1. 题目 2.题目分析与思路 3.思路 1. 题目 输入: "abcabcbb" 输出: 3 解释: 因为无重复字符的最长子串是 "abc",所以其长度为 3 ...
- Leetcode(3)-无重复字符的最长子串
给定一个字符串,找出不含有重复字符的最长子串的长度. 示例: 给定 "abcabcbb" ,没有重复字符的最长子串是 "abc" ,那么长度就是3. 给定 &q ...
随机推荐
- <玩转Django2.0>读书笔记:模板和模型
1. 模板内置标签 Django常用内置标签 标签 描述 {% for %} 遍历输出变量的内容 {% if %} 对变量进行条件判断 {% csrf_token %} 生成csrf_token标签, ...
- CentOS,crontab的学习、使用、问题解决记录
参考:http://blog.csdn.net/luanwpp/article/details/7490871 参考: http://mp.weixin.qq.com/s?src=11&tim ...
- 将欢迎消息添加到PeopleSoft主页--登录事件
以下是如何为PeopleSoft应用程序设置Signon事件消息. 导航到PeopleTools>实用程序>管理> SignOn事件消息 在此页面上,您将看到当前处于活动状态或过去处 ...
- SpringMVC+Mybatis+MySQL8遇到的问题
搭建SpringMVC+Mybatis+MySQL8过程中遇到的坑. 1.数据库驱动要使用新版本,我的和mysql保持一致. 查看mysql版本:MySQL\bin>mysql -V 配置对应版 ...
- 判断DataTale中判断某个字段中包含某个数据
// <summary> /// 判断DataTale中判断某个字段中包含某个数据 /// </summary> /// <param name="dt&quo ...
- web项目如何使用Material Icons
使用文档链接 图标库 最简单的使用方法 引入 <link href="https://fonts.googleapis.com/icon?family=Material+Icons&q ...
- python枚举类型
笔记: 一:枚举类型的定义二:枚举类和普通类的区别 1:值不可变 2:具有防止相同标签得功能,不同标签的值可以相同! 三:枚举类型.枚举值.枚举名称 1:VIP.YELLOW.Value 获得标签的值 ...
- 总结css
一.背景 1. background-color: 背景颜色 2.background-image 设置图像为背景 url("http://images.cnblogs.com/cnb ...
- Python入门(白银篇)
一.变量.元组的赋值和循环删除 (1)多个变量同时赋值 #多个变量赋值a,b,c,d=1,2,3,4x=y=m=n=520print(a,b,c,d,x,y,m,n) (2)不引入第三方变量下,交换a ...
- 谈一谈从 Delphi 2009 之后就支援的重要功能 – 泛型 (Generic)
前言 在C++的语言基础当中,除了物件导向.事件驱动的概念之外,模版设计(Template)也是非常重要的一环.然而,C++的开发人员能够善用模版设计的并不多.模版设计这个好物,一般还有一个名称,就是 ...