文章目录
1、问题描述
1. 问题
给定一个字符串 s ,请你找出其中不含有重复字符的 最长子串 的长度。
2. 例子
示例 1:
输入: s = “abcabcbb”
输出: 3
解释: 因为无重复字符的最长子串是 “abc”,所以其长度为 3。
示例 2:
输入: s = “bbbbb”
输出: 1
解释: 因为无重复字符的最长子串是 “b”,所以其长度为 1。
示例 3:
输入: s = “pwwkew”
输出: 3
解释: 因为无重复字符的最长子串是 “wke”,所以其长度为 3。
请注意,你的答案必须是 子串 的长度,“pwke” 是一个子序列,不是子串。
示例 4:
输入: s = “”
输出: 0
2、暴力算法
首先,题目要求无重复,那么就涉及到比较,所有就需要两个指针 l e f t , r i g h t left,right left,right。首先,两个指针初始指向0号位,当right<n(n为字串长度)时,right与其左边的字串一一比较(也要进行循环判断),如果right与第i个字符相等,那么此时right右边字串长度length=right-left;下次循环时候,left=i+1。
1. 代码如下
class Solution {
public:
int lengthOfLongestSubstring(string s) {
int left = 0;
int right = 0;
int count = 0;//最长字串
int length = 0;//中间段的无重复字串长度
int n = s.size();
while(right < n) {
//right与其左边字符一一比较
for(int i = left; i < right; i++) {//left为与right没重复的字串起始点
if(s[i] == s[right]) {
left = i+1;//下次left与right没重复的字串起始点
break;//遇到相等,退出循环
}
//如果不相等,那么继续循环
}
//当循环结束,即可找到中间段最长无重复字串,将其与前面得到的最长字串进行比较,长的赋值给count
length = right-left+1;
count = max(count,length);
right++;//right右移,进行下一段循环
}
return count;
}
};
2. 复杂度:
时间复杂度小于
O
(
n
2
)
O(n^2)
O(n2),大于
O
(
n
)
O(n)
O(n);
空间复杂度
O
(
1
)
O(1)
O(1)
3、容器–哈希表法
算法思想和上面一样,只是这里使用容器unordered_map来处理;
1. unordered_map容器介绍参考来源
unordered_map 容器底层采用的是哈希表存储结构,根据关键字是否已经存在来判断字串长度。
2. 代码如下
class Solution
{
public:
int lengthOfLongestSubstring(string s)
{
int left = 0;//第一个指针
int right = 0;//第二个指针
int length = 0;//中间段字串长度
int count = 0;//最长字串长度
int n = s.size();//字串总长度
//c++的容器——unordered_map,它是一个关联容器,内部采用的是hash表结构,拥有快速检索的功能。
unordered_map<char,int>hash;//创建一个空容器
while(right < n){
char tempChar = s[right];
//当容器内key有重复,即新输入tempChar值和容器里面已存在的值(除最后一个=最后输入的值)相等,并且限制在left和right之间搜索
if(hash.find(tempChar) != hash.end() && hash[tempChar] >= left) {
left= hash[tempChar] + 1;//下次循环的计算起点(左值)
}
hash[tempChar] = right;//下次循环起点(右值)
length = right - left + 1;//中间字串长度
count = max(count,length);//更新最长的字串
right++;//进入下次循环
}
return count;
}
};
3. 复杂度:
时间复杂度小于
O
(
n
)
O(n)
O(n),
空间复杂度
O
(
n
)
O(n)
O(n)