算法10.0
3. 无重复字符的最长子串 - 力扣(LeetCode)
解法一:
暴力解法:暴力枚举+哈希表(判断字符是否重复出现)
枚举所有的子串 然后统计长度之后取最大值
引入数据结构里面的哈希表:遍历的时候扔到哈希表里 如果继续遍历的时候发现有这个字符了 那么停止操作
解法二:
滑动窗口+哈希表
暴力解法有没有可以优化的地方?
分析这个优化的过程:
left指针 每一次枚举的起始位置 right指针 能到多远 还有一个哈希表
模拟暴力过程 之后
发现的规律是:(具体问题具体分析规律)
如何想到滑动窗口 为什么要用滑动窗口才是最重要的 滑动窗口的代码本身不难
为什么跳过这个重复的字符才是重点
因为left往后走 必然会遇到left往后走前的重复情况 这时候 长度都不如left往后走之前
所以没有必要在这个情况里走了 直接跳过重复字符 寻找新的可能
left走完之后 right没有必要回来
因为已经遍历过 这段字符不是重复的(前面left跳过重复字符 后面的一定不重复)
(观察发现指针是同向移动的 可以尝试使用滑动窗口来解决问题)
下面是效果图和代码:
class Solution {public int lengthOfLongestSubstring(String ss) {char[] s = ss.toCharArray();//将字符串ss转换为一个字符数组int[] hash = new int[128]; int left = 0,right = 0 , n = ss.length();int ret = 0;while(right<n){hash[s[right]]++; //进入窗口while(hash[s[right]] > 1)hash[s[left++]]--;//先移出hash表ret = Math.max(ret ,right - left+1);//更新结果right++; //让下一个字符进入窗口}return ret;}
}
//xiyu251015&1#2*2// 128可以映射常见的所有的字符
//用数组模拟哈希表 0,0 表示ascii值为0的字符出现了0次
//原来默认的题目给的String s也可以修改为 ss
//更新结果的时候 还是那句代码代替一个方法