这是我参与8月更文挑战的第7天,活动详情查看:8月更文挑战
题目
给定一个字符串 s
,请你找出其中不含有重复字符的 最长子串 的长度。
来源:力扣(LeetCode) 链接:leetcode-cn.com/problems/lo…
示例:
输入: s = "abcabcbb"
输出: 3
解释: 因为无重复字符的最长子串是 "abc",所以其长度为 3。
示例 2:
输入: s = "bbbbb"
输出: 1
解释: 因为无重复字符的最长子串是 "b",所以其长度为 1。
示例 3:
输入: s = "pwwkew"
输出: 3
解释: 因为无重复字符的最长子串是 "wke",所以其长度为 3。
请注意,你的答案必须是 子串 的长度,"pwke" 是一个子序列,不是子串。
实现方案1 :暴利破解
实现步骤:
- 定义变量
maxLength
表示最大长度 - 使用双指针截取不包含重复的字符串
- 计算子串长度,保留较大值到
maxLength
public int lengthOfLongestSubstring(String s) {
int len = s.length();
if (s == null || s.length() == 0) {
return 0;
}
int maxLength = 1;
for (int start = 0; start < len; start++) {
for (int end = start + 1; end < len; end++) {
String subStr = s.substring(start, end);
if (subStr.indexOf(s.charAt(end)) != -1) {
break;
}
int subLen = end - start + 1;
if (subLen > maxLength) {
maxLength = subLen;
}
}
}
return maxLength;
}
实现方案2 :哈希表 + 双指针
实现逻辑:
- 定义哈希表,临时存储子串字符和查重
- 遍历字符串,通过双指针循环定位子串
- 判断右指针数据是否在哈希表中存在
- 否:记录到哈希表,并向右移动,并计算长度
- 是:删除哈希表中的元素,并移动左指针
- 最后再次重复检查右指针元素是否还存在
- 判断右指针数据是否在哈希表中存在
- 每次计算子串长度,比较并保留最大值
int hash(char key) {
return key;
}
public int lengthOfLongestSubstring3(String s) {
int len;
// 源字符串长度
if (s == null || (len = s.length()) == 0) {
return 0;
}
// 最长不重复子串的长度
int res = 0;
// 子串最左端字符索引
int left = 0;
// 子串最右端字符索引
int right = 0;
// 1.定义哈希表,支持ASCII码表的全部字符
char[] chs = new char[128];
// 2.遍历字符串的所有字符
while (right < len) {
char rightChar = s.charAt(right); // 右指针字符
char c = chs[(chs.length - 1) & hash(rightChar)]; // hash算法
if (rightChar != c) { // 未重复出现
// 2.1.双指针定位子串索引:右指针自增
right++;
// 将不重复字符记录到哈希表中
chs[(chs.length - 1) & hash(rightChar)] = rightChar;
// 3.每次记录子串长度,并计算最大值
int size = right - left; // 每个不重复子串的长度
res = res > size ? res : size;
} else { // 重复出现
// 2.2.双指针定位子串索引:左指针自增。从哈希表中移出最左侧字符:赋默认值
char leftChar = s.charAt(left++);
chs[(chs.length - 1) & hash(leftChar)] = '\u0000';
}
}
return res;
}
github 地址
其他
广大 倔友 大佬们,如果看了文章!!! 请不要吝啬你们的点评!!! 如果有更好的解题思路 或者 我解题中不足的地方,文章书写不行的地方,希望大家能 给我评论指点一二!! 感谢大家!!