废话不多说,直接开干
/**
* 直接分析
*/
public int lengthOfLongestSubstring(String s) {
if (s == null || s.length() == 0) return 0;
Set<Character> charSet = new HashSet<>();
int len = 0;
for (int i = 0; i < s.length() - 1; i++) {
char now = s.charAt(i);
charSet.add(now);
boolean hasOne = false;
int _len = 0;
for (int j = i + 1; j < s.length(); j++) {
char right = s.charAt(j);
if (now == right || charSet.contains(right)) {
hasOne = true;
_len = j - i;
if (_len > len) len = _len;
break;
}
charSet.add(right);
}
charSet.clear();
if (!hasOne) {
_len = s.length() - i;
if (_len > len) len = _len;
}
}
if (len == 0)
len = s.length();
return len;
}
写的太垃圾。直接看题解
官方题解代码
public int lengthOfLongestSubstring(String s) {
// 哈希集合,记录每个字符是否出现过
Set<Character> occ = new HashSet<Character>();
int n = s.length();
// 右指针,初始值为 -1,相当于我们在字符串的左边界的左侧,还没有开始移动
int rk = -1, ans = 0;
for (int i = 0; i < n; ++i) {
if (i != 0) {
// 左指针向右移动一格,移除一个字符
occ.remove(s.charAt(i - 1));
}
while (rk + 1 < n && !occ.contains(s.charAt(rk + 1))) {
// 不断地移动右指针
occ.add(s.charAt(rk + 1));
++rk;
}
// 第 i 到 rk 个字符是一个极长的无重复字符子串
ans = Math.max(ans, rk - i + 1);
}
return ans;
}
作者:LeetCode-Solution
链接:https://leetcode-cn.com/problems/longest-substring-without-repeating-characters/solution/wu-zhong-fu-zi-fu-de-zui-chang-zi-chuan-by-leetc-2/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
跟着题解思路,自己琢磨了一下,直接上代码
public int lengthOfLongestSubstring(String s) {
// 滑动窗口解法
Set<Character> occ = new HashSet<>();
int n = s.length();// 边界
int l = 0, r = -1;// 窗口边界,r为-1代表在l的左侧
int max = 0;
// 原理,拿到一个字符时,
for (int i = 0; i < n; i++) {
// 代表 窗口的右边界已经移动到不能移动了
// 那么这时候把左边界字符移除掉,继续尝试移动窗口右边界
if (i != 0) {
occ.remove(s.charAt(i - 1));
}
// 拼命的移动窗口的右边界
// 如果下一个移动的目标位置不是总边界并且没有重复出现,那么移动
// 否则进行下次循环
while (r + 1 < n && !occ.contains(s.charAt(r + 1))) {
occ.add(s.charAt(r + 1));
r++;
}
// 右边界已经尽力了,获取一下当前最大串的长度,如果是最大,存起来
max = Math.max(max, (r - i + 1));
}
return max;
}
真的是山外有山,人外有人啊。这道题先研究到这里,继续刷题。
刷大部分的题,有一个思维的基本面,才能有一个良好的大局观。