Longest Substring Without Repeating Characters---LeetCode进阶路③

59 篇文章 0 订阅
8 篇文章 0 订阅
  • 题目描述

Given a string, find the length of the longest substring without repeating characters.

Example 1:

Input: "abcabcbb"
Output: 3 
Explanation: The answer is "abc", with the length of 3. 

Example 2:

Input: "bbbbb"
Output: 1
Explanation: The answer is "b", with the length of 1.

Example 3:

Input: "pwwkew"
Output: 3
Explanation: The answer is "wke", with the length of 3. 
             Note that the answer must be a substring, "pwke" is a subsequence and not a substring.
  • 思路分析

输出最大无重复字符的子字符串长度,很常规的数据结构题目。

最粗暴的BF算法就可以解决,当然时间复杂度会是O(n^2)这样的闹心样子。

小陌想到的方法是,建立数组存储字符串,从头开始捋,遇到重复的字符则从下一个元素开始下一轮的子字符串寻找,即每个子字符串从相应起点开始到下一个有重复字符位置。

小陌特别想分享下被圈粉的大神思路 :用HashSet维护当前字符串,左右两端一起搞。

例如我们从左边先开始,只要没有出现重复字符就继续左移;一旦出现重复字符,就换一条路,从右边开始。中间所忽略的那些,它们是有重复或者更短,值得“忽略”。而在左右开弓的情况下,至多对元素访问一遍,时间复杂度仅为O(n)。

大神的思路阐述:“基本思路是维护一个窗口,每次关注窗口中的字符串,在每次判断中,左窗口和右窗口选择其一向前移动。同样是维护一个HashSet, 正常情况下移动右窗口,如果没有出现重复则继续移动右窗口,如果发现重复字符,则说明当前窗口中的串已经不满足要求,继续移动有窗口不可能得到更好的结果,此时移动左窗口,直到不再有重复字符为止,中间跳过的这些串中不会有更好的结果,因为他们不是重复就是更短。”

  • 源码附录:

1.小陌的方法

class Solution {
    public int lengthOfLongestSubstring(String s) {
        if(s == null || s.length() == 0){
            return 0;
        }
        
        int[] count = new int[256];
        int start = 0;
        int end = 1;
        int longest = 1;
        
        Arrays.fill(count,-1);
        count[s.charAt(0)] = 0;
        
        while(end < s.length()){
            if(count[s.charAt(end)] >= start){
                start = count[s.charAt(end)] + 1;
            }
            
            longest = Math.max(longest,end - start + 1);
            count[s.charAt(end)] = end;
            end ++;
        }
        
        return longest;
    }
}

 

2.大神的方法 (大神地址https://blog.csdn.net/linhuanmars/article/details/19949159

  class Solution {
    public int lengthOfLongestSubstring(String s) {
        if(s == null || s.length() == 0){
            return 0;
        }
        
        HashSet<Character> hs = new HashSet<Character>();
        int start = 0;
        int end = 0;
        int longest = 0;
        
        while(end < s.length()){
            if(hs.contains(s.charAt(end))){
                longest = Math.max(longest,end - start);
                while(s.charAt(start) != s.charAt(end)){
                    hs.remove(s.charAt(start));
                    start ++;
                }
                start ++;
            }
            else{
                hs.add(s.charAt(end));
            }
            
            end ++;
        }

        longest = Math.max(longest,end - start);
        return longest;
    }
  }

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值