3 最长不重复子串Longest Substring Without Repeating Characters算法优化


蓝雨原创,转载请注明出处。contact author: qinglanyu_jun@foxmail.com

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.

Solution 1 滑动窗口法

窗口左指针 i i i,右指针 j = i + 1 j=i+1 j=i+1;右指针依次从字符串左侧到最右侧滑动。只要指针j指向的字符在窗口内 ( k ) (k) (k),则移动左指针到重复元素 k k k的右侧 ( k + 1 ) (k+1) (k+1);否则移动右指针,增加窗口长度。窗口右指针滑动至字符串最右侧时,经过的最大窗口宽度即为最大不重复子串的长度。

code
class Solution {
#define MAX(a, b) ((a)>(b)?(a):(b))
public:
	int lengthOfLongestSubstring(string s) {
		int m = 0;
		if (s.length() == 0) return m;
		if (s.length() > 0) m = 1;
		for (unsigned i = 0, j = i + 1; j < s.length(); ++j) {
			unsigned k = i;	         //--------------
			for (; k < j; ++k) {     //
				if (s[k] == s[j]) {  //  此处判断是否重复出现可以再优化
					i = k + 1;       //
					break;           //
				}                    //---------------
			}
			if (k == j)	{
				m = MAX(m, j - i + 1);
			}
		}
		return m;
	}
};

该方法不需要额外的存储空间,复杂度为 O ( 1 ) O(1) O(1),时间复杂度为 O ( n 2 ) O(n^{2}) O(n2)

执行结果:通过
执行用时: 8ms,在所有C++提交中击败了94.40%的用户
内存消耗: 7MB,在所有C++提交中击败了100.00%的用户

Solution 2 滑动窗口法+桶(数组)优化

在上面的方案1中,判断原子串的元素 s [ j ] s[j] s[j]是否已经出现在子串中时,每次都遍历完整个子串 s [ i , j ) s[i, j) s[i,j),显然在时间上还可以优化。此处添加一个有限元素的数组 s u b sub sub来临时存储出现过的字符。即是一种以空间换时间的方案。

code
class Solution {
#define MAX(a, b) ((a)>(b)?(a):(b))
public:
	int lengthOfLongestSubstring(string s) {
		// s[i, j) is the window
		int m = 0, len = 0;
		vector<int> sub(128, -1);	// for 128 characters
		for (int i = 0, j = 0; j < s.length(); ++j)
		{
			// when s[j] belongs to s[i, j)
			if (sub[s[j]] >= i)
			{
				i = sub[s[j]] + 1;
				len = j - i;
			}

			sub[s[j]] = j;
			len++;
			m = MAX(m, len);
		}
		return m;
	}
};

该方法只需遍历一遍原字符串,需要一个定长的数组来存储所有可能出现的字符,空间复杂度为 O ( Σ ) O(\Sigma) O(Σ),其中 Σ \Sigma Σ为可能出现的字符数,时间复杂度为 O ( n ) O(n) O(n)

执行结果:通过
执行用时: 8ms,在所有C++提交中击败了94.53%的用户
内存消耗: 7.7MB,在所有C++提交中击败了100.00%的用户

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

轻蓝雨

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值