3. Longest Substring Without Repeating Characters

  • 题目描述

  • 题目思路:

这道题要求的是最长的子串而不是最长的子序列,在LeetCode上也给了提示

Note that the answer must be a substring, "pwke" is a subsequence and not a substring.

先不考虑代码的问题,比如有一个字符串“abcabcbb”,要求找出其最长子串,可以一个一个字符的遍历,a,b,c,然后又出现了a,就把一开始已经遍历到的a去掉,变成b,c,a。然后遍历到b,就把已经遍历过的b去掉,变成c,a,b。重复这个过程,最终可以找到最长子串。

从上面的过程中可以看到,我们需要记录之前已经出现过的字符,可以统计字符出现的个数,但是这道题目,字符出现的顺序很重要,所以可以使用Hashmap来建立字符和位置之间的映射(一开始我也没有想到用Hashmap,是从网上查找资料才明白的)。之前我们手动找子串的过程实际是一个滑动窗口的过程,窗口内都是没有重复出现的字符,由于窗口在不断的向右滑动,因此只需要关心每一个字符最后出现的位置即可,并把这个位置和字符建立映射。

为了确定窗口的大小,就必须有一个left指针来指向窗口的前一个位置。然后i向右滑动,i - left就是当前窗口的大小(也是当前能找到的最长子串的长度)。

当窗口向右滑动,i++。遇到新的元素s[i],先判断该元素在Hashmap中有没有,如果没有,把当前的元素和他出现的位置插入到Hashmap中即可。如果Hashmap中已经有了该元素,那么就要更新left的值了,left应该更新为Hashmap中保存的s[i]的值。

  • C++代码实现:
class Solution 
{
public:
	int lengthOfLongestSubstring(string s) 
	{
		int left = -1;  //滑动窗口的左边界
		int res = 0;  //最长无重复子串的长度
		int n = s.size();
		unordered_map<char, int> hmap;
		for (int i = 0;i < n;i++)
		{
			if (hmap.count(s[i]) && hmap[s[i]] > left)
			{
				left = hmap[s[i]];
			}
			hmap[s[i]] = i;
			res = max(res,i - left);
		}
		return res;
	}
};

hmap.count(s[i])是查找s[i]在Hashmap中是否存在,他的返回值只有两种,若存在,则返回1,否则返回0。

  • 参考资料:

1 《[LeetCode] 3. Longest Substring Without Repeating Characters 最长无重复字符的子串》 https://www.cnblogs.com/grandyang/p/4480780.html

posted @ 2019-09-11 09:31  尚修能的技术博客  阅读(101)  评论(0编辑  收藏  举报