『题目』:
最长不重复子串就是从一个字符串中找到一个连续子串,该子串中任何两个字符都不能相同,且该子串的长度是最大的。
Input
输入包含多个测试用例,每组测试用例输入一行由小写英文字符a、b、c、…x、y、z组成的字符串,字符串长度不大于10000。
Output
对于每组测试用例,输出最大长度的不重复字符串。
『输入输出』:
输入 | 输出 |
---|---|
absd | 4 |
abba | 2 |
abdffd | 4 |
『题解』:
这道题第一眼的想法是滑动窗口,因为要的是连续子串不重复,所以包含重复字符的那个串都是没用的,所以可以通过滑动窗口来解决,如下面例子最大长度为4。
迭代次数 | 包含的字符串 | 最大长度 |
---|---|---|
初始化 | abdffd | 0 |
0 | a | 1 |
1 | ab | 2 |
2 | abd | 3 |
3 | abdf | 4 |
4 | abdff -> f | 1 |
5 | fd | 2 |
『注意』:
该想法没有在OJ上测试过,若有错误请指点
『实现』:
import java.util.Scanner;
/**
* Author:
* Gavinjou大笨象
* Date:
* 2019-05-01
* Description:
* 最长不重复子串
* 滑动窗口
*/
public class zuichang {
//字符标号记录
private static int[] num;
//字符串
private static byte[] cha;
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
num = new int[26];
//获取字符a的ASCII码大小
byte a = (byte) 'a';
while(true)
{
// 求出最大长度
int length = 0;
// 目前的长度
int nowLength = 0;
String s = sc.nextLine();
// 迟取法最左边坐标
int j = 0;
//清空空间
for(int i = 0;i < 26;i++)
{
num[i] = -1;
}
//获取字符串长度
cha = s.getBytes();
//遍历每个字符
for(int i = 0;i < cha.length;i++)
{
//计算字符的坐标
int index = cha[i] - a;
//如果这个字符出现过
if(num[index] > -1)
{
//把上一次字符这个字符前的所有字符都删除
int tmp = num[index];
for(int k = j;k <= tmp;k++)
{
num[k] = - 1;
}
//最左边的视口继续加1
j = tmp + 1;
//目前窗口最大的长度
nowLength = i - tmp ;
}
else
{
//如果字符没出现过,就+1
nowLength++;
//计算最大长度
length = Math.max(length,nowLength);
}
//标记字符一次的位置
num[index] = i;
}
System.out.println(length);
}
}
}