用途: 用于解决找出符合某条件连续的数据。
1. 解决数组遍历问题时,利用其遍历的起点与终点。
2.用数组内元素ascall和当前位置(或出现的次数)建立新数组。新数组下标为该字符ascall、大小为出现的位置或次数。
3. 用一次循环筛选出符合特定条件的连续数据。
题目:
给定一个字符串,请你找出其中不含有重复字符的 最长子串 的长度。
示例 1:
输入: "abcabcbb"
输出: 3
解释: 因为无重复字符的最长子串是 "abc",所以其长度为 3。
示例 2:
输入: "bbbbb"
输出: 1
解释: 因为无重复字符的最长子串是 "b",所以其长度为 1。
示例 3:
输入: "pwwkew"
输出: 3
解释: 因为无重复字符的最长子串是 "wke",所以其长度为 3。
请注意,你的答案必须是 子串 的长度,"pwke" 是一个子序列,不是子串。
来源:力扣(LeetCode)
链接:
https://leetcode-cn.com/problems/longest-substring-without-repeating-characters
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

思路分析
看到这个题目,笔者第一个想法就是通过两个for循环将其暴力解决掉。然后发现是一个通过一个for循环就能筛选出答案的,他们把这个算法称为滑动窗口(不知道哪个大佬最先取的这个名字)。
这里讲解一下思路:
第一步:先将所有的字符选择一个方式归类(便于后续遍历),这里的归类采用以每个字母的ascall值作为下标,其数组值为字符出现在题中的坐标信息。
第二步:开始遍历字符串,筛选的条件为遍历到的字符下标必须小于起始坐标,因为遍历的字母,如果已经出现在我们正在筛选的区间内,那么它的值必然大于区间首坐标值。此时则放弃之前的筛选,重头再来。
第三步:输出最大长度。
流程图

源码:
/* "abcabcbb" */
#include <string.h>
int lengthOfLongestSubstring(char * s){
int string[128] = { -1, -1 };
int i = 0, max_len = 0, start = 0;
memset(string, -1, sizeof(string));
for(i = 0; s[i] != 0; i++){
if(string[s[i]] < start) { //忽略起点之前的坐标信息
int temp_len = i - start + 1;
if(temp_len > max_len) {
max_len = temp_len;
}
} else { //遇见重复的字母
start = string[s[i]] + 1; //重置起点坐标
}
string[*(s+i)] = i; //不断更新字母坐标信息
}
return max_len;
}2020-06-22