Skip to content

Commit

Permalink
New Problem Solution"Longest Substring with At Least K Repeating Char…
Browse files Browse the repository at this point in the history
…acters"
  • Loading branch information
haoel committed Sep 7, 2016
1 parent cfe8809 commit 2f3a77d
Show file tree
Hide file tree
Showing 3 changed files with 216 additions and 0 deletions.
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ LeetCode

| # | Title | Solution | Difficulty |
|---| ----- | -------- | ---------- |
|395|[Longest Substring with At Least K Repeating Characters](https://leetcode.com/problems/longest-substring-with-at-least-k-repeating-characters/) | [C++](./algorithms/cpp/longestSubstringWithAtLeastKRepeatingCharacters/LongestSubstringWithAtLeastKRepeatingCharacters.cpp)|Medium|
|394|[Decode String](https://leetcode.com/problems/decode-string/) | [C++](./algorithms/cpp/decodeString/DecodeString.cpp)|Medium|
|393|[UTF-8 Validation](https://leetcode.com/problems/utf-8-validation/) | [C++](./algorithms/cpp/UTF8Validation/UTF8Validation.cpp)|Medium|
|392|[Is Subsequence](https://leetcode.com/problems/is-subsequence/) | [C++](./algorithms/cpp/isSubsequence/IsSubsequence.cpp)|Medium|
|391|[Perfect Rectangle](https://leetcode.com/problems/perfect-rectangle/) | [C++](./algorithms/cpp/perfectRectangle/PerfectRectangle.cpp)|Hard|
Expand Down
105 changes: 105 additions & 0 deletions algorithms/cpp/decodeString/DecodeString.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
// Source : https://leetcode.com/problems/decode-string/
// Author : Hao Chen
// Date : 2016-09-08

/***************************************************************************************
*
* Given an encoded string, return it's decoded string.
*
* The encoding rule is: k[encoded_string], where the encoded_string inside the square
* brackets is being repeated exactly k times. Note that k is guaranteed to be a
* positive integer.
*
* You may assume that the input string is always valid; No extra white spaces, square
* brackets are well-formed, etc.
*
* Furthermore, you may assume that the original data does not contain any digits and
* that digits are only for those repeat numbers, k. For example, there won't be input
* like 3a or 2[4].
*
* Examples:
*
* s = "3[a]2[bc]", return "aaabcbc".
* s = "3[a2[c]]", return "accaccacc".
* s = "2[abc]3[cd]ef", return "abcabccdcdcdef".
***************************************************************************************/

class Solution {
public:
string decodeString(string s) {
if (!isValid(s)) return "";

stack<string> _stack;
stack<int> _nstack;

string result;
string tmp;
int n=0;
for (int i=0; i<s.size(); i++) {

if ( isNum(s[i]) ) {
n = 0;
for(; isNum(s[i]); i++ ) {
n = n*10 + s[i] - '0';
}
}

if (s[i] == '[') {
tmp="";
_stack.push(tmp);
_nstack.push(n);
} else if (s[i] == ']') {
n = _nstack.top();
tmp="";
for (; n>0; n--) {
tmp += _stack.top();
}
_stack.pop();
_nstack.pop();
if ( ! _stack.empty() ) {
_stack.top() += tmp;
}else {
result += tmp;
}
} else {
if ( ! _stack.empty() ) {
_stack.top() += s[i];
} else {
result += s[i];
}

}
}

return result;
}

private:

//only check the following rules:
// 1) the number must be followed by '['
// 2) the '[' and ']' must be matched.
bool isValid(string& s) {
stack<char> _stack;
for (int i=0; i<s.size(); i++) {
if ( isNum(s[i]) ) {
for(; isNum(s[i]); i++);
if (s[i] != '[') {
return false;
}
_stack.push('[');
continue;
} else if (s[i] == ']' ) {
if ( _stack.top() != '[' ) return false;
_stack.pop();
}
}

return (_stack.size() == 0);
}

bool isNum(char ch) {
return (ch>='0' && ch<='9');
}
};

Original file line number Diff line number Diff line change
@@ -0,0 +1,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;
}
};

0 comments on commit 2f3a77d

Please sign in to comment.