无重复字符的最长子串 - [中等难度算法]

Given a string, find the length of the longest substring without repeating characters.

Example 1:

Input: "abcabcbb"
Output: 3
Explanation: The answer is "abc", with the length of 3.

Example 2:

Input: "bbbbb"
Output: 1
Explanation: The answer is "b", with the length of 1.

Example 3:

Input: "pwwkew"
Output: 3
Explanation: The answer is "wke", with the length of 3.
Note that the answer must be a substring, “pwke” is a subsequence and not a substring.

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/longest-substring-without-repeating-characters
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

【我的思路】稍微慢一些。
以“bacab”为例, 现在我要分别求

  1. 以第一个b结尾的最长字符串
  2. 以第一个a结尾的最长字符串
  3. 以c结尾的最长字符串
  4. 以第二个a结尾的最长字符串
  5. 以第二个b结尾的最长字符串

现在我直接求第5项:

  • 先找上一个b在哪,然后我得到了一个候选字符串(acab),同时又得到了一个字符串的左的边界(我代码中的limit)。
  • 再把i指针左移,找上一个a在哪,又得到一个候选字符串(ca 加上 b),又得到了一个左边界(这个左边界靠右, 所以更新limit)
  • 再把i指针左移,找上一个c在哪,发现没有,那就从头开始算,又得到了一个候选字符串(bac+ab)
  • 取候选字符串中最短的即为该步骤的解。以第二个b结尾的最长字符串是cab。
  • 描述的解
#include <iostream>
#include <string>
using namespace std;

class Solution {
public:
    /**
      我的代码
    */
	int lengthOfLongestSubstring(string s) {
		int len = s.length();
		int* lastIndex = new int[len];
		// 查找与本字符相同的上一个字符的位置
		for (int i = 0; i < len; ++i) {
			lastIndex[i] = -1;
			for (int j = i - 1; j >= 0; --j) {
				if (s[j] == s[i]) {
					lastIndex[i] = j;
					break;
				}
			}
		}
		// 针对每个字符, 计算所有可能解, 并取其中最短的解
		int maxLength = 0;
		for (int i = 0; i < len; ++i) {
			int limit = lastIndex[i];
			int cLength = len;
			int weight = 0;
			for (int j = i; j > limit; --j) {
				int l = j - lastIndex[j] + weight;
				if (l < cLength) cLength = l;
				int newLimit = lastIndex[j];
				if (newLimit > limit) limit = newLimit;
				weight++;
			}
			// 到这一步, 本字符的长度是cLength
			if (cLength > maxLength) maxLength = cLength;
		}
		delete[] lastIndex;
		return maxLength;
	}

	/**
	  LeetCode上别人的代码
	  i 相当于我的 limit+1。
	  i 是字符串的左边界,j 是字符串的右边界。
	*/
	int lengthOfLongestSubstring2(string s) {
		int  size, i = 0, j, k, max = 0;
		size = s.size();
		for (j = 0; j < size; j++) {
			for (k = i; k < j; k++)
				if (s[k] == s[j]) {
					i = k + 1;	// 使得i一定在与j相同的上一个字符的右边。
					break;		// 特别巧妙, 只找相邻的
				}
			if (j - i + 1> max)
				max = j - i + 1;
		}
		return max;
	}
};

int main() {
	Solution s;
	int z = s.lengthOfLongestSubstring2("kkkkkkk");
	return 0;
}
发布了80 篇原创文章 · 获赞 22 · 访问量 5万+

猜你喜欢

转载自blog.csdn.net/u010099177/article/details/100833082