【Java - J - 48】最长不含重复字符的子字符串

题目描述

请从字符串中找出一个最长的不包含重复字符的子字符串,计算该最长子字符串的长度。假设字符串中只包含’a’~'z’的字符。
例如,在字符串“arabcacfr”中,最长的不含重复字符的子字符串是“acfr”,长度是4.

实现
  • 方法:动态规划
  • 预备:
    – 字符串“arabcacfr”,显然 f ( 0 ) = 1 f(0)=1 f(0)=1
    –定义函数: f ( i ) f(i) f(i) 表示以 i i i个字符为结尾的不包含重复字符的子字符串的最长长度, f ( i − 1 ) f(i-1) f(i1)已知
  • 思路:
    1、 第 i i i个字符没出现过, f ( i ) = f ( i − 1 ) + 1 f(i)=f(i-1)+1 f(i)=f(i1)+1
    计算f(1):r没出现过,f(1)=f(0)+1=2,目前最长不重复 ar
    2、 第 i i i个字符出现过,计算第 i i i个字符和上次出现的位置的距离 d d d
    d ≤ f ( i − 1 ) d≤f(i-1) df(i1)
    ----第i个字符串上次出现在f(i-1)对应的最长字符串之中,因此f(i)=d
    ----如,计算f(2),a字符,d=2即a出现在f(1)对应的最长不含重复字符的子字符串ar中,此时f(2)=d,即f(2)=2,对应ra(rar变为ra)
    d > f ( i − 1 ) d>f(i-1) d>f(i1)
    ----第i个字符串上次出现在f(i-1)对应的最长字符串之前,因此仍有 f(i)=f(i-1)+1
    ----如,计算f(8),r字符,它前一个f字符结尾的f(7)=3,对应acf;r在下标1出现过,d=7,>f(7),说明r不在f(7)对应的最长不含重复自字符串acf中,把r拼接到acf不会出现重复,f(8)=f(7)+1=4,对应acfr
public class C48_string_LongestSubstring {
    static int getLongestSubstr(String str) {
        int curLen = 0;
        int maxLen = 0;
        int[] strArr = new int[26];
        for (int i = 0; i < 26; i++) {
            strArr[i] = -1;
        }
        for (int i = 0; i < str.length(); i++) {
            int preIndex = strArr[str.charAt(i) - 'a'];
            if (preIndex < 0 || i - preIndex > curLen) { //没出现过或者d>f(i-1)
                curLen++;//f(i)=f(i-1)+1
            } else {//d<=f(i-1)
                if (curLen > maxLen) {
                    maxLen = curLen;//保存较大字符串个数
                }
                curLen = i - preIndex;// f(i)=d
            }
            strArr[str.charAt(i) - 'a'] = i;//赋值下标位置
        }
        if (curLen > maxLen) {
            maxLen = curLen;
        }
        return maxLen;
    }
}

Test
    public static void main(String[] args) {
        String str = "arabcacfr";
        System.out.println(getLongestSubstr(str));
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值