C++中至少包含k個重複字元的最長子字串
假設我們有一個字串s,我們需要找到該字串的最長子字串T的長度(只包含小寫字母),使得T中的每個字元出現的次數不少於k次。例如,如果字串是“ababbc”並且k=2,則輸出將是3,最長子字串將是“ababb”,因為有兩個'a'和三個'b'。
為了解決這個問題,我們將遵循以下步驟:
- 建立一個名為longestSubstring()的遞迴函式,它接收字串s和大小k。
- 如果k=1,則返回字串的大小。
- 如果字串的大小小於k,則返回0。
- 建立一個大小為26的陣列c,並將其填充為-1。
- n := 字串的大小。
- 對於範圍0到n的i
- 如果c[s[i] – ‘a’] = -1,則c[s[i] – ‘a’] := 1,否則將c[s[i] – ‘a’]加1。
- badChar := ‘*’
- 對於範圍0到25的i
- 如果c[i]不等於-1且c[i]小於k,則badChar := i + ‘a’並退出迴圈。
- 如果badChar = ‘*’,則返回n。
- v := 透過使用badChar分割原始字串而得到的另一個字串陣列。
- ans := 0
- 對於範圍0到v大小的i
- ans := ans和longestSubstring(v[i], k)的最大值。
- 返回ans。
示例(C++)
讓我們看下面的實現以更好地理解:
#include <bits/stdc++.h> using namespace std; class Solution { public: vector <string> splitString(string s, char x){ string temp = ""; vector <string> res; for(int i = 0; i < s.size(); i++){ if(s[i] == x){ if(temp.size())res.push_back(temp); temp = ""; } else temp += s[i]; } if(temp.size())res.push_back(temp); return res; } int longestSubstring(string s, int k) { if(k == 1)return s.size(); if(s.size() < k )return 0; vector <int> cnt(26, -1); int n = s.size(); for(int i = 0; i < n; i++){ if(cnt[s[i] - 'a'] == -1) cnt[s[i] - 'a'] = 1; else cnt[s[i] - 'a']++; } char badChar = '*'; for(int i = 0; i < 26; i++){ if(cnt[i] != -1 && cnt[i] < k){ badChar = i + 'a'; break; } } if(badChar == '*')return n; vector <string> xx = splitString(s, badChar); int ans = 0; for(int i = 0; i < xx.size(); i++)ans = max(ans, longestSubstring(xx[i], k)); return ans; } }; main(){ Solution ob; cout << ob.longestSubstring("ababbc", 2); }
輸入
"ababbc" 2
輸出
5
廣告