forked from haoel/leetcode
-
Notifications
You must be signed in to change notification settings - Fork 0
/
LongestSubstringWithAtLeastKRepeatingCharacters.cpp
109 lines (92 loc) · 2.8 KB
/
LongestSubstringWithAtLeastKRepeatingCharacters.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
// Source : https://leetcode.com/problems/longest-substring-with-at-least-k-repeating-characters/
// Author : Hao Chen
// Date : 2016-09-08
/***************************************************************************************
*
* Find the length of the longest substring T of a given string (consists of lowercase
* letters only) such that every character in T appears no less than k times.
*
* Example 1:
*
* Input:
* s = "aaabb", k = 3
*
* Output:
* 3
*
* The longest substring is "aaa", as 'a' is repeated 3 times.
*
* Example 2:
*
* Input:
* s = "ababbc", k = 2
*
* Output:
* 5
*
* The longest substring is "ababb", as 'a' is repeated 2 times and 'b' is repeated 3
* times.
***************************************************************************************/
const int NO_OF_CHARS = 256;
/* if every character appears at least k times, the whole string is ok.
* Otherwise split by a least frequent character.
*
* Because it will always be too infrequent and thus can't be part of any ok substring
* and make the most out of the splits.
*/
class Solution {
public:
int longestSubstring(string s, int k) {
//deal with edge cases
if (s.size() == 0 || s.size() < k) return 0;
if (k==1) return s.size();
//declare a map for every char's counter
int count[NO_OF_CHARS];
memset(count , 0, sizeof(count));
//counting every char
for (char ch : s) {
count[ch]++;
}
int i=0;
for ( i=0; i<NO_OF_CHARS; i++) {
if (count[i] !=0 && count[i] < k) break;
}
//all of the chars meet the requirement
if ( i >= NO_OF_CHARS ) return s.size();
// find the most infrequent char
char least = 0;
for (int c = 0; c < NO_OF_CHARS; c++) {
if (count[c] == 0) continue;
if (least == 0) {
least = c;
} else if ( count[c] < count[least]) {
least = c;
}
}
//split the string and run them recursively
vector<string> subs;
split(s, least, subs);
int res = 0;
for (string str: subs) {
res = max(res, longestSubstring(str, k));
}
return res;
return 0;
}
private:
inline int max(int x, int y) { return x>y? x:y; }
inline void split(const string &s, char delim, vector<string> &elems) {
stringstream ss;
ss.str(s);
string item;
while (getline(ss, item, delim)) {
cout << item << endl;
elems.push_back(item);
}
}
inline vector<string> split(const string &s, char delim) {
vector<string> elems;
split(s, delim, elems);
return elems;
}
};