1. 程式人生 > >求字串的最長無重複字元子串(C++)

求字串的最長無重複字元子串(C++)

題目:

         給定一個字串str,返回str的最長無重複字元子串的長度。

         如:"abcd" 返回4  "abcb" 返回3

         要求:若字串的長度為N 演算法的時間複雜度為O(N)。

思路:

         下面給出的演算法 時間複雜度為O(N) 空間複雜度為O(M) 其中 :

         N為字串的長度 M是字串中字元編碼的範圍(ASCII碼最大值)。

         首先定義以下2個變數:

mp<char, int> —— 儲存某個字元最近出現的位置。

         pre                  —— 表示遍歷到str[i]時 以str[i - 1]字元結尾的情況下最長無重複子串開始的前一個位置。


         maxSubLen    —— 記錄以每個字元結尾的情況下,最長無重複子串長度的最大值。

  初始時 pre = -1 maxSubLen = 0

           mp[str[i]] 表示遍歷完str[0]-str[i-1]後 str[i]字元最近一次出現的位置 設為A。

           pre + 1    表示以str[i - 1]字元結尾的情況下 最長無重複子串的開始位置。

           討論:

           A >   pre             以str[i]結尾的最長無重複子串範圍即為: str[A + 1] ~ str[i]


           A <= pre             以str[i]結尾的最長無重複子串範圍即為: str[pre + 1] ~ str[i]

            令:maxEdIdx = max(A, pre);

           執行完上述操作後,更新pre【pre 和 A的較大值】 更新maxSubLen【maxSubLen 和 maxEdIdx 的較大值

           重複上述操作,直至所有字元遍歷完。

            貼程式碼:

<span style="font-size:12px;">#include <iostream>
#include <string>

using namespace std;

int longestSubstring(string A, int n) 
{
	int mp[256];

	memset(mp, -1, 256 * sizeof(int));

	int pre = -1, maxSubLen = 0;

	for (int i = 0; i < n; ++i)
	{
		pre = max(pre, mp[A[i]]);
		maxSubLen = max(maxSubLen, i - pre);

		mp[A[i]] = i;
	}

	return maxSubLen;
}

int main(void)
{
	string str = "aabcdb";

	cout<<longestSubstring(str, str.length())<<endl;

	return 0;
}</span>