LeetCode #828. Count Unique Characters of All Substrings of a Given String
Let's define a function
countUniqueChars(s)
that returns the number of unique characters ons
.
- For example, calling
countUniqueChars(s)
ifs = "LEETCODE"
then"L"
,"T"
,"C"
,"O"
,"D"
are the unique characters since they appear only once ins
, thereforecountUniqueChars(s) = 5
.Given a string
s
, return the sum ofcountUniqueChars(t)
wheret
is a substring ofs
.Notice that some substrings can be repeated so in this case you have to count the repeated ones too.
class Solution {
public:
int uniqueLetterString(string s) {
int ans = 0;
int pos[26][2];
memset(pos, -1, sizeof(pos));
for(int i = 0; i < s.size(); i++){
int c = s[i] - 'A';
ans += (i - pos[c][1]) * (pos[c][1] - pos[c][0]);
pos[c][0] = pos[c][1];
pos[c][1] = i;
}
for(int i = 0; i < 26; i++){
ans += (s.size() - pos[i][1]) * (pos[i][1] - pos[i][0]);
}
return ans;
}
};
We iterate from 0 to n, where i is the length of the entire string, and in each iteartion with find the total of number of substring where s[i] is unique and ends before i. We can find the number by keeping track of the last two occurences of the character s[i], along with this formula:
This formula is based on a simple combination rule.
Consider "xxAxAxxxAx", where x can be any character except A.
Now we assume our pointer points to the last A, which means we have to find all the substrings that contain a unique A and ends up before the last A. We can divide the problem into number of ways of starting before the second A and the number of ways that end after the second A. (We use brackets here to denote the possible combinations.)
Before: ...(xA, ...x(A
After: A)xxx..., Ax)xx..., Axx)x..., Axxx)...
Thus, the total number of valid substrings would have a total of 2 x 4 = 8.
We are also doing an extra for loop at the end since maybe not all characters appear more than three times and ends up at the string's end. Therefore, we are iterating through all 26 uppercse characters to find the final answer.
Note that we initialize all values to -1 to somehow reduce extra logic.
LeetCode #2262. Total Appeal of A String
The appeal of a string is the number of distinct characters found in the string.
- For example, the appeal of
"abbca"
is3
because it has3
distinct characters:'a'
,'b'
, and'c'
.Given a string
s
, return the total appeal of all of its substrings.A substring is a contiguous sequence of characters within a string.
class Solution {
public:
long long appealSum(string s) {
vector<int> last(26, -1);
long long res = 0;
for(int i = 0; i < s.length(); i++){
res += (i - last[s[i] - 'a']) * (s.length() - i);
last[s[i] - 'a'] = i;
}
return res;
}
};
This solution also uses a similar approach as the one above.
We first iterate through each charcter in the string and find out the total number of substrings that it is the first to appear as that type of lowercase charater, i.e. the total appeal number that that character contributes. Again, we are using an array to the positions of all 26 lowercase's last apperances, and initializing them to -1, so as to make use of the same formula:
Another solution would be like this.
class Solution {
public:
long long appealSum(string s) {
vector<int> last(26, 0);
long long res = 0;
for(int i = 0; i < s.length(); i++){
last[s[i] - 'a'] = i+1;
for(int j : last){
res += j;
}
}
return res;
}
};
The only difference here is that we are finding all 26 lowercase charcters' contribution to the appeal number at each iteration. We are expanding the substring set at each iteration by adding in the next character inline and then calculate the appeal of the new subset.
Why is Lee God is good? When can I be half as good as him? TT