Java最长连续不重复子串_【Java】 剑指offer(48) 最长不含重复字符的子字符串

本文参考自《剑指offer》一书,代码采用Java语言。

题目

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

思路

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

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

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

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

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

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

注意:每次最大长度和字母出现位置要记得更新。

测试算例

1.功能测试(一个或者多个字符,全部字符不同/相同)

2.特殊测试(null,空字符串)

Java代码

//题目:请从字符串中找出一个最长的不包含重复字符的子字符串,计算该最长子

//字符串的长度。假设字符串中只包含从'a'到'z'的字符。

public class LongestSubstringWithoutDup {

public static int maxLength(String str) {

if(str==null || str.length()<=0)

return 0;

int preLength=0; //即f(i-1)

int curLength=0; //即f(i)

int maxLength=0;

int[] pos= new int[26]; //用于存放字母上次出现的位置

for(int i=0;i

pos[i]=-1;

for(int i=0;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;

}

public static void main(String[] args) {

System.out.println(maxLength("arabcacfr")==4);

System.out.println(maxLength("a")==1);

System.out.println(maxLength("aaa")==1);

System.out.println(maxLength("abcdef")==6);

System.out.println(maxLength("")==0);

System.out.println(maxLength(null)==0);

}

}

收获

1.函数f(i)为:以第i个字符为结尾的不含重复字符的子字符串的最大长度。而不是以第i个字符作为开头。第i个字符作为结尾可以方便与下一个字符进行联系。

2.学会用长度为26的数组来存放26个字母所在的位置下标。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值