Finding All Substrings (LeetCode #828 & #2262)

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 on s.

  • For example, calling countUniqueChars(s) if s = "LEETCODE" then "L""T""C""O""D" are the unique characters since they appear only once in s, therefore countUniqueChars(s) = 5.

Given a string s, return the sum of countUniqueChars(t) where t is a substring of s.

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:

num = (i - lastOccurence) \times (lastOccurence - secondLastOccurence)

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 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" is 3 because it has 3 distinct characters: 'a''b', and 'c'.

Given a string s, return the total appeal of all of its substrings.

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:

 num = (i - lastOccurence) \times (stringLength - i)

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值