第一次打leetcode周赛复盘——第286场周赛

首先反思一下,只ac了一道题,好菜
看了前几名大佬的回答之后发现,算法的idea是一方面,目前我主要问题在于:1个月速成cpp,对基本函数太不熟悉了。
下面对这4道题逐一记录下学到的东西:

文章目录

  • 1. 5268.找出两数组的不同
  • 2. 5236.美化数组的最少删除数
  • 3. 5253. 找到指定长度的回文数
  • 4. 5269. 从栈中取出 K 个硬币的最大面值和


1. 5268.找出两数组的不同

链接见:5268.找出两数组的不同
第一次打leetcode周赛复盘——第286场周赛_第1张图片
这道题是俺唯一ac的题

大佬解法如下:

class Solution {
public:
    vector<vector<int>> findDifference(vector<int>& nums1, vector<int>& nums2) {
        std::set<int> s1(nums1.begin(), nums1.end());
        std::set<int> s2(nums2.begin(), nums2.end());
        std::vector<int> a, b;
        
        for (auto x : s1) {
            if (!s2.count(x)) {
                a.push_back(x);
            }
        }
        for (auto x : s2) {
            if (!s1.count(x)) {
                b.push_back(x);
            }
        }
        
        return {a, b};
    }
};

写的时候想到了把vector换成一个无重复元素的容器,但是不知道还能这么一行就塞进去,,

std::set<int> s1(nums1.begin(), nums1.end());

还有就是判断set里是否有某个元素的时候,只想起来了用std::find,忘记了还可以count()


2. 5236.美化数组的最少删除数

链接见:5236.美化数组的最少删除数
第一次打leetcode周赛复盘——第286场周赛_第2张图片
榜1大佬题解,加了点自己理解的注释:

class Solution {
public:
    int minDeletion(vector<int>& nums) {
        int ans = 0;
        int cur = 0; //cur记录数组中满足:对所有 i%2==0 的下标i ,nums[i] != nums[i+1] 成立的元素个数
        int last = -1;
        for (auto x : nums) {
            if (x == last && cur % 2 == 1) {
                ans++;
            } else {
                cur++;
                last = x;
            }
        }
        //如果处理完偶数下标的重复值后数组个数还是奇数,则还需要再删一个
        if (cur % 2 == 1) {
            ans++;
        }
        return ans;
    }
};

遇到这种找重复元素的题,可以拿一个变量记录下需要进行比对的值,例如这里的int last,遍历的时候进行更新即可
cur记录满足下标的重复条件的元素个数,如果它还是奇数,则需要再删一个,也就是ans++


3. 5253. 找到指定长度的回文数

链接见:5253. 找到指定长度的回文数
第一次打leetcode周赛复盘——第286场周赛_第3张图片
主要想法步骤:

  1. k为回文数的前一半位数,例:10101里对应着前三位——101
//intLength = 5 时 k = 3, 例:10101里对应着前三位——101
int k = (intLength + 1) / 2;
  1. 10^(k-1)后找到queries里对应下标回文数的前k位
//回文数的前半部分,例:10101里对应着前三位——101
long long res = p + x - 1;
  1. 找到可以reverse的部分,并逐一加到res上(每次加的时候res*10,即对应后面加了一位)
//找到可以reverse的那部分,即10101里的前两位10
auto s = std::to_string(res);
s.resize(intLength - k);
//"10"->"01"
std::reverse(s.begin(), s.end());
//总位数为res的位数+可以reverse部分的位数
for (auto c : s) {
	res = 10 * res + c - '0';
  }

依旧是大佬题解,加了注释:

class Solution {
public:
    vector<long long> kthPalindrome(vector<int>& queries, int intLength) {
        std::vector<long long> ans;
        for (auto x : queries) {
            //intLength = 5 时 k = 3, 例:10101里对应着前三位——101
            int k = (intLength + 1) / 2;
            int p = 1;
            //回文数左半边长度为k, p = 10^(k-1)
            for (int i = 0; i < k - 1; i++) {
                p *= 10;
            }
            //由于是回文数,只有intLength长度的回文数最多只有9*p个,超过这个下标的需要返回-1
            if (x > 9 * p) {
                ans.push_back(-1);
            } else {
                //回文数的前半部分,例:10101里对应着前三位——101
                long long res = p + x - 1;
                //找到可以reverse的那部分,即10101里的前两位10
                auto s = std::to_string(res);
                s.resize(intLength - k);
                //"10"->"01"
                std::reverse(s.begin(), s.end());
                //总位数为res的位数+可以reverse部分的位数
                for (auto c : s) {
                    res = 10 * res + c - '0';
                }
                ans.push_back(res);
            }
        }
        return ans;
    }
};


4. 5269. 从栈中取出 K 个硬币的最大面值和

链接见:5269. 从栈中取出 K 个硬币的最大面值和
第一次打leetcode周赛复盘——第286场周赛_第4张图片
lay了,一会再看

你可能感兴趣的:(leetcode周赛记录,leetcode,c++)