LeetCode | Longest Substring Without Repeating Characters

Given a string, find the length of the longest substring without repeating characters. For example, the longest substring without repeating letters for "abcabcbb" is "abc", which the length is 3. For "bbbbb" the longest substring is "b", with the length of 1.

思路:用head与tail维护一个窗口,HashSet来记录窗口中的字符。tail向后遍历,当遍历到重复的字符时停下,然后移动head,让head跳过与tailChar重复的那个字符,即从左侧缩小窗口,跳过与tailChar冲突的那个字符,使窗口中不再包含重复字符。(因为substring得是连续的字符串,故单纯向右移动head即可)此时head成为新窗口的左边界,然后再移动tail看新窗口的Length能否超过上个窗口

//因为head与tail都只向右移动,对每个元素最多遍历两次。而hashset使contains/add/remove具有常数时间复杂度
//故算法复杂度为O(2n)=O(n),空间复杂度为O(size of set)
public class Solution {
    public int lengthOfLongestSubstring(String s) {
        
        if(s==null || s.length()==0){
            return 0;
        }
        
        HashSet<Character> set = new HashSet<Character>();  //窗口子串中的字符集合
        int head = 0; 
        int tail = 0;                                       //用head与tail维护一个窗口
        int maxLength = 0;
        
        for(tail=0; tail<s.length(); tail++){
            char tailChar = s.charAt(tail);
            if(!set.contains(tailChar)){         //tailChar与窗口子串的字符不重复,直接加入set然后下次遍历即可
                set.add(tailChar);
            }else{                               //如果tailChar在窗口子串中已经有了,就得停下来
            
                if(tail-head > maxLength){       //更新maxLength
                    maxLength = tail-head;
                }
                
                while(s.charAt(head) != tailChar){   //移动head,使head-tail段的窗口中不再有重复字符
                    set.remove(s.charAt(head));      //例abcabcd,当运行到head=0,tail=3时,不执行此循环,仅head++
                    head++;                          //而若abccbcd,运行到head=0,tail=3时,把head+2,再执行head++,
                }
                
                head++;                              //跳过冲突字符的最后一跃
            }
        }
        
        //可能窗口位于s的末尾,则循环终止时,maxLength是前面各个窗口中最长的,不包含最后的这个窗口
        return Math.max(maxLength, tail-head);
    }
}

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值