0
点赞
收藏
分享

微信扫一扫

LeetCode291周赛题解,附‘字符串总引力‘详解

七公子706 2022-05-02 阅读 57

LeetCode291周赛题解 '字符串总引力’详解直接跳到最后

LeetCode291周赛题解

class Solution {
public:
    string removeDigit(string s, char d) {
        int n = s.size();
        string ans ="0";
        for(int i = 0; i < n; i++)
        {
            string t = "";
            if(s[i] == d)
            {
                t += s.substr(0, i - 0);
                t += s.substr(i + 1, n - i);
            }
            ans = max(ans, t);
        }
        return ans;
    }
};
class Solution {
public:
    int minimumCardPickup(vector<int>& c) {
        unordered_map<int,int> mp;
        int n = c.size();
        int ans = INT_MAX;
        bool f = false;
        for(int i = 0; i < n; i++)
        {
            if(mp.find(c[i]) == mp.end())
            {
                mp[c[i]] = i;
            }
            else
            {
                ans = min(ans, i - mp[c[i]] + 1);
                mp[c[i]] = i;
                f = true;
            }
        }
        if(!f)
            return -1;
        return ans;
    }
};
class Solution {
public:
    int countDistinct(vector<int>& nums, int k, int p) {
        int n = nums.size();
        set<string> s;
    
        for(int i = 0; i < n; i++)
        {
            string str = "";
            int t = 0;
            for(int j = i; j < n; j++)
            {
                str += to_string(nums[j]);
                str += ',';
                
                if(nums[j] % p == 0)
                    t++;
                if(t > k)
                    break;
                s.insert(str);
            }
            
        }
        
        return s.size();
    }
};

第四题:字符串总引力 -详解

提示 1-1
将所有子串按照其末尾字符的下标分组。

提示 1-2
考虑两组相邻的子串:以 s [ i − 1 ] s[i−1] s[i1]结尾的子串、以 s [ i ] s[i] s[i]结尾的子串。

提示 1-3
s [ i ] s[i] s[i] 结尾的子串,可以看成是以 s [ i − 1 ] s[i−1] s[i1] 结尾的子串,在末尾添加上 s[i]组成。

上面这一串提示是思考子串统计类问题的通用技巧之一。

提示 2-1
从左往右遍历 s s s,考虑将 s [ i ] s[i] s[i] 添加到以 s [ i − 1 ] s[i−1] s[i1] 结尾的子串的末尾。添加后,这些子串的引力值会增加多少?

提示 2-2
分类讨论:

  • 如果 s [ i ] s[i] s[i] 之前没有遇到过,那么这些子串的引力值都会增加 1 1 1,这些子串的引力值之和会增加 i i i,再加上 1 1 1,即 s [ i ] s[i] s[i] 单独组成的子串的引力值;

  • 如果 s [ i ] s[i] s[i] 之前遇到过,设其上次出现的下标为 j j j,那么向子串 s [ 0.. i − 1 ] , s [ 1.. i − 1 ] , s [ 2.. i − 1 ] , ⋯ , s [ j . . i − 1 ] s[0..i−1], s[1..i−1], s[2..i−1],⋯,s[j..i−1] s[0..i1],s[1..i1],s[2..i1],,s[j..i1]的末尾添加 s [ i ] s[i] s[i] 后,这些子串的引力值是不会变化的,因为 s [ i ] s[i] s[i] 已经在 s [ j ] s[j] s[j] 处出现过了;而子 s [ j + 1.. i − 1 ] , s [ j + 2.. i − 1 ] , ⋯ , s [ i − 1.. i − 1 ] s[j+1..i−1], s[j+2..i−1],⋯,s[i−1..i−1] s[j+1..i1],s[j+2..i1],,s[i1..i1] 由于不包含字符 s [ i ] s[i] s[i],这些子串的引力值都会增加 1 1 1,因此有 i − j − 1 i−j−1 ij1 个子串的引力值会增加 1 1 1,这些子串的引力值之和会增加 i − j − 1 i−j−1 ij1,再加上 1 1 1,即 s [ i ] s[i] s[i] 单独组成的子串的引力值。

模拟上述过程,遍历 s s s 的过程中用一个变量 s u m G sumG sumG 维护以 s [ i ] s[i] s[i] 结尾的子串的引力值之和,同时用一个数组 p o s pos pos 记录每个字符最近一次出现的下标。

累加遍历中的 s u m G sumG sumG 即为答案。

这里附上我的理解图(讨论样例一,包含特殊情况,abbca):

请添加图片描述

至此,所有的情况均分析完,最后的结果,我们可以一直累加当前斜对角层的引力数,当前斜对角层的引力数又等于上一层的加上当前层字符贡献的。代码如下:

class Solution {
public:
    long long appealSum(string &s) {
        long ans = 0L, sum_g = 0L;
        vector<int> pos(26, -1);// -1初始化,刚好处理了,字符没出现过 i + 1
        for (int i = 0; i < s.length(); ++i) {
            char c = s[i] - 'a';
            sum_g += i - pos[c]; //上一斜对角层 + 这一层字符贡献
            ans += sum_g; //总的 累加 这一斜对角层
            pos[c] = i;//维护字符位置
        }
        return ans;
    }
};


觉得文章有用,点个赞,点个收藏,支持一下

举报

相关推荐

0 条评论