leetcode-3. Longest Substring Without Repeating Characters

本文介绍了一种求解字符串中最长无重复字符子串的算法实现,包括三种方法:使用双指针与哈希映射,哈希映射结合滑动窗口,以及哈希集合与滑动窗口。这些方法在不同情况下有各自的优点。

无重复元素的最长子串(不是子序列,子序列可以不连续,子串必须是一段连续)

题意:

给出一个字符串,输出他的无重复元素的最长子串的长度:
- 无重复元素
- 最长
- 子串的字符在父串中连续,不可以间隔

方法一

  1. 如果s长度小于等于1,直接输出其长度
  2. 遍历每一个字符,维护两个指针,left无重复子串的左边界,right为当前遍历到的字符
    • 当前字符在map中找到,left移到map中出现该字符的位置的下一个,更新map中该字符的出现位置
    • 未找到,将该字符及位置加入map
    • 当前子串长度为res和right-left+1中的较大值

leetcode3

    //方法二
    public int lengthOfLongestSubstring(String s) {
        int l = s.length();
        if (l <= 1) {
            return l;
        }
        Map<Character, Integer> map = new HashMap<>();
        int res = 0;
        for(int left = 0, right = 0; right < l; right++){
            char c = s.charAt(right);
            if (map.containsKey(c)) {
                left = Math.max(left, map.get(c) + 1);
            }
            map.put(c, right);
            res = Math.max(res, right - left + 1);
        }
        return res;
    }

方法二:重复时HashMap删除原位置i及之前的元素

hashMap也可以插入,也可以删除,但是HashMap是无序的,所以通过key删除,而不能通过i索引删除
- 当前字符串在map中出现过位置为i,清除i及其之前的所有字符,从此位置开始重新计算子串

    //方法三
    public int lengthOfLongestSubstring(String s) {

        int l = s.length();
        if (l <= 1) {
            return l;
        }
        Map<Character, Integer> map = new HashMap<>();
        int j = 0;
        int res = 0;
        for(int i = 0; i < l; i++){
            if (!map.containsKey(s.charAt(i))) {
                map.put(s.charAt(i), i);
                res = Math.max(res, map.size());
            }
            else {
                int end = map.get(s.charAt(i));
                for(; j <= end; j++)
                    map.remove(s.charAt(j));
                map.put(s.charAt(i), i);
            }
        }
        return res;
    }

方法三:==滑动窗口==。重复时Set删除原位置i及之前的元素,set为无序的,所以通过key删除,而不能通过i索引删除

是对方法二的改进,fast指针指向当前遍历位置,slow指针指向子串的开始位置
- 因为未用到map中的value:位置,所以hashMap可以改为hashSet,只存储字符即可
- 用while循环替代for,无需二层循环。找不到,存入并且找下一个;找到,移除slow位置的元素,因为fast不变,所以继续while循环,一直删除从slow删到fast位置的元素,此时fast元素不重复,执行if里的语句插入。

class Solution {
    public int lengthOfLongestSubstring(String s) {
        int res = 0;
        Set<Character> set = new HashSet<>();
        int slow = 0;
        int fast = 0;
        while(fast < s.length()){
            if(!set.contains(s.charAt(fast))){
                set.add(s.charAt(fast++));
                res = Math.max(res, set.size());
            }
            else{
                set.remove(s.charAt(slow++));
            }
        }
        return res;
    }
}
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值