leetcode 第3题 无重复字符的最长字串
题目描述
给定一个字符串,请你找出其中不含有重复字符的 最长子串 的长度。
【注意】 区分字串和子序列,子串必须相邻,子序列不一定
解法
1. 滑动窗口1
用一个数组实现hashmap, key为字符,value为字符最后出现的位置,初始化为 -1。
数组大小:因为ASCii表只有256个字符,然而键盘只能表示128个,所以用128也行。
用一个 left 变量来指向滑动窗口的左边界,初始化为 -1,表示无重复字符串从 left 后面开始。
- 遍历字符串:
- 如果遍历到的字符没有在hashmap中,则扩大右边界
- 如果遍历到的字符存在于hashmap中,分两种情况:
- 如果该字符在滑动窗口中,需要把已在窗口内的字符去掉,再将遍历到的该字符加进来
- 如果该字符不在滑动窗口中,则直接加到窗口中
维护一个 res结果,没次出现的窗口和res 比较,获取最终结果
int lengthOfLongestSubstring(char * s){
int window[256];
memset(window, -1, sizeof(window));
int left = -1;
int res = 0;
int len = strlen(s);
for (int i = 0; i < len; i++) {
left = fmax(left, window[s[i]]);
window[s[i]] = i;
res = fmax(res, i - left);
}
return res;
}
2. 滑动窗口2
原理同1
head 标记滑动窗口右边界,rear 标记滑动窗口左边界,初始化为0
window数组作为hashmap,初始化为0,当出现一个字符时,记录这个字符的index+1;
int lengthOfLongestSubstring(char * s){
int max = 0;
int temp_max = 0;
int head = 0;
int rear = 0;
int window[128] = {0};
int length = strlen(s);
if (length == 0) {
return 0;
}
while (head <= length - 1) {
if (window[ s[head] ] != 0) {
if (window[ s[head] ] > rear) {
rear = window[ s[head] ];
}
}
temp_max = head - rear + 1;
if (temp_max > max) {
max = temp_max;
}
window[ s[head] ] = head + 1;
head++;
}
return max;
}