zoukankan      html  css  js  c++  java
  • 剑指Offer对答如流系列

    面试题48:最长不含重复字符的子字符串

    题目描述

    请从字符串中找出一个最长的不包含重复字符的子字符串,计算该最长子字符串的长度。假设字符串中只包含从'a'到'z'的字符。

    例如,在字符串“arabcacfr”中,最长的不含重复字符的子字符串是“acfr”,长度为4.

    问题分析

    遇到问题,先分析问题,由分析的结果确定所运用的算法。

    一般而言,我们都会在纸上动笔画画,罗列一些基本的情况。这道题分析之后,可以找到关系式。

    定义函数f(i)为:以第i个字符为结尾的不含重复字符的子字符串的最大长度。

    (1)当第i个字符之前未出现过,则有:f(i)=f(i-1)+1

    (2)当第i个字符之前出现过,记该字符与上次出现的位置距离为d

    • 如果d<=f(i-1),则有f(i)=d;

    • 如果d>f(i-1),则有f(i)=f(i-1)+1;

    可以从第一个字符开始遍历,定义两个int变量preLength和curLength来分别代表f(i-1)和f(i),并创建一个长度为26的pos数组来存放26个字母上次出现的位置,即可根据上述说明进行求解。

    问题解决

        public int  maxLength(String str) {
            if(str==null || str.length()<=0) {
                return 0;
            }
            // 即f(i-1)
            int preLength=0;
            // 即f(i)
            int curLength;
            int maxLength=0;
            // 用于存放字母上次出现的位置
            int[] pos= new int[26];
            Arrays.fill(pos, 0);
    
            for(int i=0;i<str.length();i++) {
                int letterNumber = str.charAt(i)-'a';
                if(pos[letterNumber]<0 || i-pos[letterNumber]>preLength) {
                    curLength=preLength + 1;
                } else {
                    curLength=i-pos[letterNumber];
                }
                pos[letterNumber]=i;
                if(curLength>maxLength) {
                    maxLength=curLength;
                }
                preLength=curLength;
            }
            return maxLength;
        }
    
  • 相关阅读:
    zkw费用流
    luogu5212/bzoj2555 substring(后缀自动机+动态树)
    后缀数据结构模板2
    后缀数据结构模板1
    通用动态树(Link-Cut Tree)模板
    上下界网络流总结
    多项式多点求值
    拉格朗日反演
    多项式板子·新
    luogu2387 [NOI2014]魔法森林
  • 原文地址:https://www.cnblogs.com/JefferyChenXiao/p/12246532.html
Copyright © 2011-2022 走看看