【字节专场】leetcode3. 无重复字符的最长子串

3. 无重复字符的最长子串

给定一个字符串,请你找出其中不含有重复字符的 最长子串 的长度。

示例 1:

输入: "abcabcbb"
输出: 3 
解释: 因为无重复字符的最长子串是 "abc",所以其长度为 3。
示例 2:

输入: "bbbbb"
输出: 1
解释: 因为无重复字符的最长子串是 "b",所以其长度为 1。
示例 3:

输入: "pwwkew"
输出: 3
解释: 因为无重复字符的最长子串是 "wke",所以其长度为 3。

方法一:滑动窗口

首先明确是求最长子串而不是最长子序列,子串是必须得连续的,这里稍微模拟一下,以“pwwkew”为例,
查看p是否已经在集合中,否,更新ans,
查看w是否已经在集合中,否,更新ans,
查看w是否已经在集合中,是,那么w重复了,所以需要更新左边界,从左开始移除元素,直到w不在集合中,再插入,然后更新ans…

public int lengthOfLongestSubstring(String s) {
    int len = s.length();
    int i = 0, j = 0;	//窗口为[i, j),也就是初始化为空
    int ans = 0;
    Set<Character> set = new HashSet<>();
    while (i<len && j<len){
        if (!set.contains(s.charAt(j))){
            set.add(s.charAt(j));
            ans = Math.max(ans, j-i+1);
            j++;
        }
        else {
            set.remove(s.charAt(i));
            i++;
        }
    }
    return ans;
}

方法二:优化的滑动窗口

使用一个Map<Character, Integer>,key存字符,value存key在字符串中的下标+1,这样当扩展窗口碰到key已经存在时,就可以快速更新左边界为max(i, map.get(s.charAt(j))),虽然这里可能map内存的元素多余当前窗口的大小,但并不不会影响。

public int lengthOfLongestSubstring(String s) {
    int n = s.length(), ans = 0;
    Map<Character, Integer> map = new HashMap<>();
    for (int j = 0, i = 0;j<s.length();j++){
        if (map.containsKey(s.charAt(j))){
            i = Math.max(i, map.get(s.charAt(j)));
        }
        ans = Math.max(j-i+1, ans);
        map.put(s.charAt(j), j+1);
    }
    return ans;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值