题目
给定一个字符串,请你找出其中不含有重复字符的 最长子串 的长度。如:
输入: “abcbabcd”
输出: 4
解释: 因为无重复字符的最长子串是 “abcd”,所以其长度为 4。
思路
一开始容易往暴力遍历的方向想,但是实际上运用窗口的思想就很容易解决。无重子串的定义是连续且各异的字符,需要满足连续,而起止位置不定,长度是随着起止位置变化的,因而想象为一个可以左右浮动宽度变化的窗口,这个窗口包含的字符就是所要的串。为了保证窗口不出现重复字符,可以将窗口后的下一位(图中虚线框)与窗口(图中实线框)内的已有字符遍历比较,无相同可直接将窗口下一位纳入,扩大窗口,而出现相同则需要由前削减窗口(图中点线框),窗口起始位置(start)移动到重复字符的下一位,再将窗口下一位纳入。由图可见这是个窗口终止位置(end)递增的过程,终止条件是窗口终止位置(end)到达最后一个字符(strlen()-1)。
代码
#include<stdio.h>
#include<string.h>int main()
{char *p = new char[512]{};int ret = scanf("%s", p);int start = 0, end = start - 1, lenmax = end - start + 1, i;//lenmax为最大窗口长度int maxSubstringStart = 0, maxSubstringEnd = 0;while (end != strlen(p)-1){//默认无重bool redundant = false;for (i = start; i <= end; i++){if (p[end + 1] == p[i]){//有重redundant = true;break;}}if (redundant){//由前削减窗口start = i + 1;end++;}else{//往后扩大窗口end++;int len = end - start + 1;//当前窗口长度if (lenmax < len){lenmax = len;maxSubstringStart = start;maxSubstringEnd = end;}}}//结果输出for (int i = 0; i < strlen(p); i++){if (maxSubstringStart <= i&&i <= maxSubstringEnd){putchar(p[i]);continue;}putchar(' ');}printf("\n");printf("%d\n", lenmax);delete[] p;return 0;
}