求字符串中最长无重复字符的子串
生活随笔
收集整理的這篇文章主要介紹了
求字符串中最长无重复字符的子串
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
題目:求一個字符串中最長的沒有重復字符的子串。
思路:用hash表從i遍歷查看包含i的最長 無重復子串。
int max_unique_substring2(char * str) {int i,j;int begin;int maxlen = 0;int hash[256];int n = strlen(str);for(i=0; i<n; ++i){memset(hash,0,sizeof(hash)); hash[str[i]] = 1;for(j=i+1; j<n; ++j){if(hash[str[j]] == 0)hash[str[j]] = 1;elsebreak;}if(j-i > maxlen){maxlen = j-i;begin = i;}}printf("%.*s\n", maxlen, &str[begin]);return maxlen; }動態規劃:
dp[i]表示以a[i]為結尾的最長不重復子串長度,初始狀態dp[0]=1; ?現在判斷包含str[i]元素的最長不重復子串了,
主要是判斷包含str[i[元素最長子串的起始位置。如果他與他前面的最長不重復子串都沒有相同的字符,那么他也可以加入這個子串中,構成一個新的子串。 ?最終目的還是注意每個最長子串的起始位置。
/* LNRS dp */ int dp[30];void LNRS_dp(char * arr, int size) {int i, j;int <strong>last_start </strong>= 0; // 上一次最長子串的起始位置maxlen = maxindex = 0;dp[0] = 1;for(i = 1; i < size; ++i){for(j = i-1; j >= last_start; --j) // 遍歷到上一次最長子串起始位置{if(arr[j] == arr[i]){dp[i] = i - j;<strong>last_start</strong> = j+1; // 更新last_startbreak;}else if(j == <strong>last_start</strong>) // 無重復{dp[i] = dp[i-1] + 1;}}if(dp[i] > maxlen){maxlen = dp[i];maxindex = i + 1 - maxlen;}}output(arr); }Hash
很多情況下,在描述一個字符串時,都是英文字母組成的字符,因此可能出現的元素是有限的(26個),因此就有了第二種想法,Hash。
這種想法在于使用一個大小為26的數組visited[]記錄每個字符是否出現,然后枚舉最長不重復子串的起點。代碼如下:
void LNRS_hash(char* s){char visited[26];int i, j;int maxlen = 0;int maxIndex;int len = strlen(s);memset(visited, -1, 26);for (i = 0; i < len; i++){visited[s[i] - 'a'] = 1;for(j = i+1 ; j < len; j++){if(visited[s[j]-'a'] == -1) //該字符沒有出現{visited[s[j]-'a'] = 1;if(j - i+1> maxlen){maxlen = j - i+1;maxIndex = i;//最長不重復子串的起點}}elsebreak;}memset(visited, -1, 26);}printf("%d\n", maxlen);}
總結
以上是生活随笔為你收集整理的求字符串中最长无重复字符的子串的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 判断一个数组是否是另一个数组的子集
- 下一篇: 0-1背包问题(一维数组解法)