计蒜客 最长不重复子串

来源:互联网 发布:半身裙淘宝店好一点 编辑:程序博客网 时间:2024/05/20 10:15
题干:

给定一个字符串,找到最长的子串,要求该子串中没有重复的字符。

例如:

字符串abcabcbb的不含重复字符的 最长 子串为abc,长度为 3

bbbbbb的不含重复字符的 最长 子串为b,长度为 1

输入格式

输入包含多行,每一行对应一个长度不超过 100100100 的输出,直到遇到结束符为止。每行依次输入字符串s

输出格式

输出不含重复字符的 最长 子串的长度。

这里先排坑:

1、输出为多行,所以要使用一个hasnext()判断输入是否结束

2、暂定输入只有26个小写字母

3、采用动态规划+hash的算法

思路:

定义一个数组ans[],元素为以当前字符为最后一个字符的子串的长度,初始化为0,ans[0]=1。

hash数组hash[],value值为元素在字符串中的位置i。元素初始化为-1,第一个元素的hash为0。

一个标记last_start:记录当前子串的起始位置---非常有用!通过判定last_start和hash重复出现字符的位置可以确认是否真的冲突了(因为字符可以出现多次,只要当前子串中没有即可)

import java.util.*;public class jsk {public static void main(String[] arg){Scanner in=new Scanner(System.in);while(in.hasNext()){String a=in.nextLine();int []hash=new int[26];for(int i=0;i<26;i++)hash[i]=-1;char[] s=a.toCharArray();int l=s.length;int []ans=new int[l];  //以该字符为最后一个字符的子串长度hash[s[0]-'a']=0;ans[0]=1;int last_start=0;for(int i=1;i<=l-1;i++){int x=s[i]-'a';if(hash[x]==-1){hash[x]=i;    //哈希value值为 字符在数组的位置ans[i]=ans[i-1]+1;   //第一次遇到这个字符 加入子序列 长度加1}else {if(hash[x]>=last_start) //当前子串的起点在冲突字符前,需要截断。{ans[i]=i-hash[x];last_start=hash[x]+1;hash[x]=i;}else{ans[i]=ans[i-1]+1;//未冲突,但是已经遍历过这个字符hash[x]=i;}}}int answer=0;for(int i=0;i<l;i++){if(ans[i]>answer)answer=ans[i];}System.out.println(answer);}}}




原创粉丝点击