LeetCode-3. 无重复字符的最长子串-非常经典的题-滑动窗口

1.题目

 

2.思路

滑动窗口的思想:用双指针实现。

初步版本:用哈希表记录区间[i, j]之间不重复的数字,当出现重复数字之后,i ++, j = i.相当于每次重新new 一个哈希表来存储,这样其实有大量重复计算,最坏的可能是O(n * n),比如用例 abcdefa.

改进版本:首先只用一个哈希表,当出现重复数字后,删除map中第i个字符,如果发现还有重复数字,那么继续删。相当于这个滑动窗口,右边j 要加入,必须让左边的i挨个删除。

为什么在哈希表中是逐个删除是s[i]?而不是直接让i 移动到 和nums[j]相同的位置?

因为需要让位置i 到 跟nums[j]相同的位置j ‘中间的所有数字都从哈希表中删除。如果直接移动i 到j',那么哈希表中就依然还保存了区间外的数,这是不对的。在测试用例的时候也可以多测试几个特殊的,主要就是考虑各种边界条件。

全为空: “ ”

全都不等: “abcdef"

全部相等:”aaaaa"

连在一起的相等:“abbcd"

最后一个数才相等:”abcda"

还有就是自己随机输入很长的数:“asdhiasofhjdvf”

class Solution {
    public int lengthOfLongestSubstring(String s) {
        int ans = 0 ;
        int n = s.length();
        if(n == 0) return 0;
        Map<Character, Integer>map = new HashMap();
        int j = 0;
        for(int i = 0 ; i < n; i++){
            while(j < n && map.getOrDefault(s.charAt(j), - 1) == -1){
                map.put(s.charAt(j), j);
                j++;
            }
            ans = Math.max(ans, j - i);
            if(j == n)break;
            // 这一行非常关键!!!为什么是删除当前i的值?而不是直接把i移动到有重复数字的位置
            map.remove(s.charAt(i));
        }

        return ans;
    }   
}

3.结果

4.感想

刷这题四五遍了,老是领悟不到滑动窗口的精髓。一边进,一边出,用map维持i - j 之间的数。知识就是不过脑子,感觉只有输出知识才能真正的记住知识。多动手,多动嘴!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值