文章目录
前序
- 闲扯之前先放图,丫丫的靓图
感觉数据结构就是我迈不过的一道坎,看网课,看书,看博客…学的过程中,感觉是自己会了(我是在自我欺骗)。但是自己下来写的时候,却像茶壶里煮饺子一样写不出来;甚至在做有关数据结构的题,有的知道怎么做,但就是写不出代码来,Debug一天也搞不出来,真的是特别难受!
现在,数据结构相关的我只会冒泡和优化,基础快排,二叉树 (回顾一下才能写出来)。然后,就没了…自己感觉这一块真的好难搞,但是基础的基础,必须要牢牢掌握。会了又忘,忘了又会,做题依然跪!所以,每天至少刷一道题吧在LeetCode或牛客上.
这道题我当时的想法有点类似第二种解法,思路是依次拿到子串,然后往后遍历,看下一个字符在不在串里。搞了一个List
,然后CharAt
,然后改了一天,依旧搞不出来。这是我看LeetCode的题解时的理解,代码是题解参考,并不是我自己写的。这篇博客就当是自己的理解笔记吧.
1. 题目描述
给定一个字符串,请你找出其中不含有重复字符的 最长子串 的长度
示例 1:输入: “abcabcbb”
输出: 3
解释: 因为无重复字符的最长子串是 “abc”,所以其长度为 3
示例 2:输入: “bbbbb”
输出: 1
解释: 因为无重复字符的最长子串是 “b”,所以其长度为 1
示例 3:
输入: “pwwkew”
输出: 3
解释: 因为无重复字符的最长子串是 “wke”,所以其长度为 3
请注意,你的答案必须是子串的长度,“pwke” 是一个子序列,不是子串
2. 题解
基础解法
思路:
首先,我觉得做这道题第一步想到的是字符窜的分割,想到了charAt()
,然后用什么来存放子串?List
,Set
,Map
都是可以的。我当初想到就是用ArrayList
,但是有一个重要的条件就是无重复,所以选择set
是比较合适的。
然后,要怎么拿到一个子串,并和子串后面的字符比较,看这个字符是不是在这个子串中,最后再记录最长子串的长度
这是我当时的思路,但是无奈写不出来
- 基础易理解,时间复杂度为O(n3)
public class Solution {
public static int lengthOfLongestSubstring(String s) {
int n = s.length();
int ans = 0;
for (int i = 0; i < n; i++) {
for (int j = i + 1; j < n; j++) {
if (strUnique(s, i, j)) {
ans = Math.max(ans, j - i);
}
}
}
return ans;
}
public static boolean strUnique(String s, int start, int end) {
Set < Character > set = new HashSet < > ();
for (int k = start; k < end; k++) {
Character ch = s.charAt(k);
if (set.contains(ch)) {
return false;
}
set.add(ch);
}
return true;
}
public static void main(String[] args) {
String str = "pwwekw";
System.out.println(lengthOfLongestSubstring(str));
}
}
画个草图解释吧
优化解法(滑动窗口)
- 上面解法的优化,时间复杂度为O(n)
- 通过"窗口"(子串的更新来寻找最长子串)
public class Solution2 {
public static int LongestSubstring(String s) {
Set<Character> set = new HashSet<>();
int n = s.length();
int ans = 0; int i = 0; int j = 0;
while(i < n && j < n) {
if(!set.contains(s.charAt(j))) {
set.add(s.charAt(j++));
ans = Math.max(ans, j-i);
}else {
set.remove(s.charAt(i++));
}
}
return ans;
}
public static void main(String[] args) {
String str = "pwwekw";
System.out.println(LongestSubstring(str));
}
}