原题
给定一个字符串,请你找出其中不含有重复字符的 最长子串 的长度。
示例 1:
输入: “abcabcbb”
输出: 3
解释: 因为无重复字符的最长子串是 “abc”,所以其长度为 3。示例 2:
输入: “bbbbb”
输出: 1
解释: 因为无重复字符的最长子串是 “b”,所以其长度为 1。示例 3:
输入: “pwwkew”
输出: 3
解释: 因为无重复字符的最长子串是 “wke”,所以其长度为 3。
请注意,你的答案必须是 子串 的长度,“pwke” 是一个子序列,不是子串。来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/longest-substring-without-repeating-characters
解法
暴力
class Solution {
public:
int lengthOfLongestSubstring(string s) {
int size = s.size(), ans = 0, k, i, j;
// 本质还是滑动窗口!
for (i = 0; i < size; ++i) {
for (j = i + 1; j < size; ++j) {
for (k = i; k < j; ++k) {
/**
* 比如:a b c a b c b b
* i = 0, j = 1, 我们要找的是 i 到 j 之间的最长无重复子串
*/
if (s[k] == s[j]) {
// 有重复,就退出
break;
}
}
if (k != j) {
/* 如果,中间有重复,第三层 for 会通过 break 退出,这里也要退出,要使
* i + 1
*/
break;
}
}
int tmp = j - i;
// 求出最长的无重复子串
if (ans < tmp) {
ans = tmp;
}
}
return ans;
}
};
python代码
class Solution:
def lengthOfLongestSubstring(self, s: str) -> int:
size = len(s)
if size == 1:
return 1
ans = 0
i = 0
j = i + 1
k = i
for i in range(0, size, 1):
for j in range(i + 1, size, 1):
for k in range(i, j, 1):
if s[k] == s[j]:
break
else:
k += 1
if k != j:
break
else:
j += 1
tmp = j - i
if ans < tmp:
ans = tmp
return ans
python暴力必超时啊😱
滑动窗口
不用 unordered_set
class Solution {
public:
int lengthOfLongestSubstring(string s) {
//三指针, mid指针用来判断left ~ right中间是否有重复元素,
// left跟right指针用来计算元素个数
int len = s.size(), max = 1, left = 0, right, mid;
if (len == 0) {
return 0;
}
for (right = 1; right < len; ++right) {
// 判断left ~ right中间有没有重复元素
for (mid = left; mid < right; ++mid) {
if (s[mid] == s[right]) {
// 如果有重复元素, 一切作废!
/**比如:
* a b c a b c b b
* left mid right
* 此时s[mid] == s[right]
* 说明不满足条件, left指针此时应该指向c元素, 即left = mid + 1
* 跳出判断子串重复循环!
*/
left = mid + 1;
break;
}
}
if (right - left + 1 > max) {
/**比如:
* 0 1 2 3 4 5 6 7
* a b c a b c b b
* left right
* 此时满足题意, 子串长度为 2 - 0 + 1, 即right - left + 1
* 更新max即可
*/
max = right - left + 1;
}
}
return max;
}
};
python代码
class Solution:
def lengthOfLongestSubstring(self, s: str) -> int:
size = len(s)
maxValue = 1
low = 0
high = 1
mid = low
if size == 0:
return 0
for high in range(1, size, 1):
for mid in range(low, high, 1):
if s[mid] == s[high]:
low = mid + 1
break
if high - low + 1 > maxValue:
maxValue = high - low + 1
return maxValue
使用 unordered_set
class Solution {
public:
int lengthOfLongestSubstring(string s) {
unordered_set<char> appear;
int size = s.size();
int right = -1, ans = 0;
for (int i = 0; i < size; ++i) {
if (i != 0) {
appear.erase(s[i - 1]);
}
while (right + 1 < size && !appear.count(s[right + 1])) {
appear.insert(s[right + 1]);
++right;
}
ans = max(ans, right - i + 1);
}
return ans;
}
};
python代码
class Solution:
def lengthOfLongestSubstring(self, s: str) -> int:
appear = set()
n = len(s)
right, ans = -1, 0
for i in range(n):
if i != 0:
appear.remove(s[i - 1])
while right + 1 < n and s[right + 1] not in appear:
appear.add(s[right + 1])
right += 1
ans = max(ans, right - i + 1)
return ans
总结
多刷题,做多了都是套路,哈哈哈🤣🤣🤣
诗情画意
卜算子·咏梅 陆游 驿外断桥边,寂寞开无主。已是黄昏独自愁,更着风和雨。 无意苦争春,一任群芳妒。零落成泥碾作尘,只有香如故。