无重复字符的最长子串 与 滑动窗口

题目描述如下:

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

这一题用暴力算法遍历也可以, 但是时间会超过leetcode的要求.
读题可以总结题目有如下特点:

  1. 输出结果在原字符串中是连续排列的
  2. 每次需要读取的只在头/尾部, 中间部分内容提供比较时用

这时候考虑用滑动窗口的方式就可以显著地减少操作次数.

代码如下:

import java.util.*;

public class demo {
    public static void main(String[] args) {
        String str = "pwwkew";
        char[] ch = str.toCharArray();
        // map用于存放已有字符的指向地址, 主要使用到map的key的唯一性
        Map<Character, Integer> map = new HashMap<>();
        // index为指向尾部的游标, 初始的时候在0之前.
        int index = -1;
        int maxLen = 0;
        // i为指向头部的游标, 不断遍历前进
        for(int i =0; i < ch.length; i++){
            // 加入之前有走到过的字符就会存在于map中, key为字符, value为该字符最后一次出现的位置
            if(map.containsKey(ch[i])){
                // 此处取最大值是为了判断当前重复值是否再当前窗体内, 如果在当前窗体内则把尾巴游标缩进到map.get(ch[i]), 否则则维持上一次尾部位置
                index = Math.max(index, map.get(ch[i]));
            }
            // 每次移动头部都计算长度, 注意我们的游标尾部是从-1开始的, 而且index指向的是上一个重复的字符所在位置, 所以只需要i-index, 不需要再+1
            maxLen = Math.max(maxLen, i-index);
            // 把最后一次出现这个坐标放入map
            map.put(ch[i], i);
        }
        System.out.println(maxLen);
    }
}

以上这段代码需要注意的是尾部游标的位置是包含重复字符的位置的, 所以初始值是-1, 求最大长度的时候只需要i-index(头-尾), 不需要再+1.

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值