【周赛83】828. 统计子串中的唯一字符

67 阅读2分钟

周赛链接

830. 较大分组的位置 O(n)O(1)\lgroup O(n)、O(1)\rgroup

链接

830. 较大分组的位置

方法一:一次遍历

class Solution:
    def largeGroupPositions(self, s: str) -> List[List[int]]:
        n = len(s)
        res = []
        cnt = 1  # 统计相同的个数
        for i in range(n):
            if i == n - 1 or s[i] != s[i + 1]:
                if cnt >= 3:
                    res.append([i - cnt + 1, i])
                cnt = 1
            else:
                cnt += 1            
                
        return res 
class Solution {
public:
    vector<vector<int>> largeGroupPositions(string s) {
        int n = s.size();
        vector<vector<int>> res;
        int cnt = 1;
        for (int i = 0; i < n; ++i){
            if (i == n - 1 || s[i] != s[i + 1]){
                if (cnt >= 3){
                    res.push_back({i - cnt + 1, i});
                }
                cnt = 1;
            }else{
                cnt += 1;
            }
        }
        return res;
    }
};

831. 隐藏个人信息 O(n)\lgroup O(n)\rgroup

链接

831. 隐藏个人信息

方法一:模拟

class Solution:
    def maskPII(self, s: str) -> str:
        idx = s.find('@')
        if idx >= 0:
            return (s[0] + '*' * 5 + s[idx - 1:]).lower()
        
        s = "".join(c for c in s if c.isdigit())
        return ["", "+*-", "+**-", "+***-"][len(s) - 10] + "***-***-" + s[-4:]

image.png

class Solution {
public:
    vector<string> country = {"", "+*-", "+**-", "+***-"};
    
    string maskPII(string s) {
        string res;
        int idx = s.find('@');
        if (idx >= 0){// 邮箱: 首尾字符 + 邮箱后缀
            transform(s.begin(), s.end(), s.begin(), ::tolower);
            return s.substr(0, 1) + "*****" + s.substr(idx - 1);
        }
        
        s = regex_replace(s, regex("[^0-9]"), ""); // 正则 
        return country[s.size() - 10] + "***-***-"  + s.substr(s.size() - 4);
    }
};
class Solution:
    def maskPII(self, s: str) -> str:
        res = ""
        cnt = 0
        cnt2 = 0
        lis = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9']
        if s[0].isalpha():
            idx = s.index('@')
            return s[0].lower() + '*' * 5 + s[idx-1].lower() + s[idx :].lower()
        
        else:
            for i in range(len(s)-1, -1, -1):
                if s[i] in lis:
                    cnt += 1
                    if cnt < 4:
                        res += s[i]
                    if cnt == 4:
                        res += s[i] + '-***-***'
                    if cnt > 10:
                        cnt2 += 1
            if cnt2 == 0:
                return res[::-1]
            elif cnt2 == 1:
                return "+*-" + res[::-1]
            elif cnt2 == 2:
                return "+**-" + res[::-1]
            elif cnt2 == 3:
                return "+***-" + res[::-1]

829. 连续整数求和 O(n)O(1)\lgroup O(\sqrt{n})、O(1)\rgroup

链接

829. 连续整数求和

方法一:数学

image.png

class Solution:
    def consecutiveNumbersSum(self, n: int) -> int:
        res = 0
        for k in range(1, math.ceil(math.sqrt(2* n))):  # 项数  k   首项为 a  则 (2 * a + k - 1) * k = 2 * n
            b, c = divmod(2 * n, k)
            if c == 0 and (b - (k - 1)) % 2 == 0:  # b = (2 * 首项 + k - 1) 
                res += 1
                    
        return res 

image.png

class Solution {
public:
    int consecutiveNumbersSum(int n) {
        int res = 0;
        for (int k = 1; k * k < 2 * n; ++k){//  项数  k  第一项 为a 则有
            int c = 2 * n % k;
            if (c == 0 && (2 * n / k - k + 1) % 2 == 0){// (2* a +  k - 1)* k = 2 * n
                res += 1;                
            }
            
        }
        return res;
    }
};

828. 统计子串中的唯一字符 O(n)\lgroup O(n)\rgroup

链接

828. 统计子串中的唯一字符

方法一:哈希表统计出现位置,再根据规律分别计算每个字符的贡献

image.png

class Solution:
    def uniqueLetterString(self, s: str) -> int:
        dic = collections.defaultdict(list)
        for i, c in enumerate(s):
            dic[c].append(i)
            
        res = 0
        for arr in dic.values():
            arr = [-1] + arr + [len(s)]  # 三数 遍历 技巧  注意 这里 是 s 的边界
            for i in range(1, len(arr) - 1):
                res += (arr[i] - arr[i - 1]) * (arr[i + 1] - arr[i])
        return res 

image.png

class Solution {
public:
    int uniqueLetterString(string s) {
        unordered_map<char, vector<int>> dic;
        int n = s.size();
        for (int i = 0; i < n; ++i){
            dic[s[i]].emplace_back(i);
            
        }
        int res = 0;
        for (auto [_, arr] : dic){
            arr.insert(arr.begin(), -1);
            arr.emplace_back(n);
            for (int i = 1; i < arr.size() - 1; ++i){
                res += (arr[i] - arr[i- 1]) * (arr[i + 1] - arr[i]);
            }
        }
        return res;
    }
};