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

题目描述

给定一个字符串,请找出最长的不包含重复字符的子串。
请注意子串和子序列的区别:

子串一定是连续的一段
子序列不一定是连续的一段,但下标要求是递增的

样例
给定 "abcabcbb",答案是"abc",长度是3.
给定 "bbbbb",答案是"b",长度是1.
给定 "pwwkew",答案是"wke",长度是3.
 

分析:

(双指针扫描) O(n)  为了代码的简洁,把String s放到char[ ] c中;
 1、定义两个指针 i,j,(i<=j),表示当前扫描到的子串是 [ i , j ](闭区间)。扫描过程中维护一个哈希表HashMap<Character,Integer> ,表示 [ i , j ]中每个字符出现的次数。

2、线性扫描时,每次循环的流程如下:

  • 指针 j 向后移一位, 同时将哈希表中 key 为chars[ j ]的value值计数加一;
  • 假设 j 向后移动之前的区间 [ i , j ] 中没有重复字符,则 j 移动后,只有 chars[ j ] 可能出现2次。因此我们不断向后移动 i,直至区间 [ i , j ] 中 chars[ j ] 的个数等于1为止;

复杂度分析:由于 i , j 均最多增加n次,且哈希表的插入和更新操作的复杂度都是 O(1),因此,总时间复杂度 O(n)

Java实现:

import java.util.HashMap;

/**
 * @ClassName:Solution
 * @description:
 * @Author: why
 * @Date: 2019/4/20
 */
public class Solution {

    public int lengthOflongestSubString(String s){

        int res=0;

        char[] chars=s.toCharArray();

        HashMap<Character,Integer>map=new HashMap<>(16);

        for (int i=0,j=0;j<chars.length;j++){

            //value+1
            if (map.get(chars[j])!=null){
                map.put(chars[j],map.get(chars[j])+1);
            }else {
                map.put(chars[j],1);
            }

            if (map.get(chars[j])>1){

                while (i<j){
                    map.put(chars[i],map.get(chars[i])-1);

                    i++;

                    if (map.get(chars[j])==1){
                        break;
                    }
                }

            }
            res=Math.max(res,j-i+1);
        }
        return res;
    }
}

测试结果:

987 / 987 个通过测试用例

状态:通过

执行用时:43 ms

提交时间:0 分钟之前

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值