【剑斩OFFER】算法的暴力美学——无重复字符的最长字串
一、题目描述
二、算法原理
⏩️解法:利用规律使用"滑动窗口"来解决问题。
⏩️1.定义两个指针都指向字符串的开始。
⏩️2.定义一个哈希一开始初始化为false,表示没有表中没有该字符。
⏩️3.判断:如果哈希表里面没有该字符就 hash[s[right]] = true。然后 right++ 右移,在移动的过程中,如果发现有字符在哈希表中了,left 要右移过第一个和 right 指向的字符后面的字符。
⏩️上面的图中 right 指向的 a 已经在哈希表中了,所以:
⏩️ 原因:请看下图:
⏩️这两种情况的长度都小于 left 指向 d 的长度,所以 left 只能指向 b 来寻找最大的长度,而且right 也不用回去一个判断,因为 right 回去指向 b 此时 left 和 right 也指向 b ,但是最终 right 肯定要经过 a 的,再说 left 已经跳过 a 了,证明 left 到 right 的区间是没有重复的字符的,right 往后找就行。
❌️注意:left 在移动的过程中要把哈希表含有经过的字符变成 false,代表着后面 left 到 right 区间的字符是不含有前面的字符的。
⏩️4、更新结果
⏩️不管 right 在移动的过程怎么样都要记录下最长的字符串。
三、代码实现
class Solution {
public:int lengthOfLongestSubstring(string s) {int hash[128] = {0};int left = 0, right = 0, n = s.size();int ret = 0;while(right < n){hash[s[right]]++;while(hash[s[right]] > 1)//表示遇到重复性字符{hash[s[left++]]--;//left右移动同时经过的字符出现的次数变为0}ret = max(ret,right - left + 1);//无论怎么样都要更新结果right++;}return ret;}
};
探索性代码:
class Solution {
public:int lengthOfLongestSubstring(string s) {bool hash[128] ={false};int left = 0 ,ret = 0;for(int right = 0; right < s.size();right++){if(hash[s[right]] == false){hash[s[right]] = true;}else{while(s[left] != s[right]){hash[s[left++]] = false;//移动的过程中,left指向的字符不能在hash表中,因为后面的字符不一定有前面的字符。} left++;}ret = max(ret,right - left + 1);}return ret;}
};