0
点赞
收藏
分享

微信扫一扫

73双周赛的反思

那小那小 2022-03-11 阅读 26

总览

T1 过于急躁、题没看懂直接切,结果付出了 wa 两次的惨痛代价,以后没看懂题之前要耐心;T2 暴力梭哈,考的是自定义排序;T3 反向建边后常规 dfs ;T4 又是没信心写😭。

一、

看懂题目就写出来了,哈希表 + 模拟

class Solution {
public:
    int mostFrequent(vector<int>& nums, int key) {
        int n = nums.size();
        unordered_map<int, int> m;
        for(int i = 0; i < n - 1; ++ i)
            if(nums[i] == key) //nums[i] == key 且 nums[i + 1] == target
                m[nums[i + 1]] ++;
        int maxn = 0;
        for(auto [x,y] : m)
            maxn = max(maxn, y);
        for(auto [x , y] : m)
            if(y == maxn)
                return x;
        return 0;
        
    }
};

二、

自定义排序

先贴一份比赛时候手忙脚乱写的:

#define x first
#define y second
class Solution {
public:
    vector<int> sortJumbled(vector<int>& mapping, vector<int>& nums) {
        vector<vector<int>> a;
        int idx = 0;
        for(int num : nums)
        {
            string s = to_string(num);
            string tmp;
            for(auto i : s)
                tmp += to_string(mapping[i - '0']);
            a.push_back({stoi(tmp), num, idx ++});
        }
        sort(a.begin(), a.end(), [](vector<int> &p1, vector<int> &p2)
             {
                 if(p1[0] != p2[0])
                    return p1[0] < p2[0];
                 return p1[2] < p2[2];
             });
        vector<int> ans;
        for(auto &i : a)
            ans.push_back(i[1]);
        return ans;
    }
};

将 nums 里的数字按照规则转换没有写好,转字符后再转数字有些繁琐、这里不用to_string实现一下。wa 了一次,原因是没有处理 0。还好比赛的时候直接上字符串。不过速度快了三倍。

for(int num : nums)
{
    int tmp = 0, nn = num, p = 1;
    if(num == 0) //特判0
    {
        a.push_back({mapping[0], num, idx ++});
        continue;
    }
    while(nn)
    {
        int t = nn % 10;
        tmp += p * mapping[t];
        p *= 10;
        nn /= 10;
    }
    a.push_back({tmp, num, idx ++});
}

三、

一开始正向建边 dfs wa 了一次又 TLE 了一次,再试的拓扑排序,我写的依然 TLE 了一次;然后灵感爆发,反向建边常规 dfs 一遍 AC

class Solution {
public:
    //反向建图 对每个点dfs
    vector<bool> b;
    vector<vector<int>> a; //建图
    vector<vector<int>> ans; //父节点 所有能到达它的父节点去重
    vector<vector<int>> getAncestors(int n, vector<vector<int>>& edges) {
        a.resize(n); ans.resize(n); b.resize(n); 
        for(auto &i : edges)
            a[i[1]].push_back(i[0]); //反向建边

        for(int i = 0; i < n; ++ i) //对每个点dfs一次
        {
            b = vector<bool>(n);
            dfs(i, i);
        }
        
        for(auto &i : ans) //去重
        {
            sort(i.begin(), i.end());
            i.erase(unique(i.begin(), i.end()), i.end());
        }
        return ans;
    }
    
    void dfs(int u, int x) //u是父节点  x是dfs过程中的节点
    {
        for(auto &i : a[x])
        {
            ans[u].push_back(i);
            if(!b[i]) 
            {
                dfs(u, i);
                b[i] = true;
            }
        }
    }
};

四、

直接放上 评论区佬的证明

再临摹一下佬的代码

class Solution {
public:
    int minMovesToMakePalindrome(string s) {
        int res = 0, n = s.size();
        for(int i = 0, j = n - 1; i < j; ++ i) //固定左指针
        {
            for(int k = j; k != i; -- k)
            {
                if(s[k] == s[i]) //偶数
                {
                    for(; k < j; ++ k) 
                    {
                        swap(s[k], s[k + 1]);
                        res ++;
                    }
                    j --; //右边界缩小
                    goto OK;
                }
            }
            res += n / 2 - i;
            OK :;
        }
        return res;
    }
};
举报

相关推荐

0 条评论