从零单排力扣周赛_周赛273

本文详细介绍了LeetCode周赛273的四道题目,包括A题反转两次的数字的判断,B题执行所有后缀指令的模拟解法,C题相同元素间隔之和的前缀和策略,以及D题还原原数组的枚举与匹配方法。每道题目均提供了解题思路和代码实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

本文同步发表于 个人博客

前言

感觉 l e e t c o d e leetcode leetcode 周赛不花时间,做一做还能保持一下手感,最重要的是能让人在周末早起。于是以后可能就会多打打 l e e t c o d e leetcode leetcode 了。

周赛273

AK时间: 21min

最终排名:

A 5963.反转两次的数字

给出数字 n n n R ( n ) R(n) R(n) 表示 n n n 翻转后去掉前导零的结果,要求判断 R ( R ( n ) ) R(R(n)) R(R(n)) 是否等于 n n n

0 ≤ n ≤ 1 0 6 0\le n\le 10^6 0n106

做法

判断 n n n 是否有后导 0 0 0,即 n n n 是否是 10 10 10 的倍数即可,特判 n = 0 n=0 n=0 的情况。

代码
class Solution {
public:
    bool isSameAfterReversals(int num) {
        return (num == 0 || num % 10 != 0);
    }
};

B 5964. 执行所有后缀指令

模拟题

做法

模拟即可

代码
class Solution {
public:
    vector<int> executeInstructions(int n, vector<int>& startPos, string s) {
        int m = s.size();
        vector<int> ans(m);
        for(int i = 0; i < m; i++){
            int ok = 0;
            int x = startPos[0], y = startPos[1];
            for(int j = i; j < m; j++){
                if(s[j] == 'L') y--;
                if(s[j] == 'R') y++;
                if(s[j] == 'U') x--;
                if(s[j] == 'D') x++;
                if(x < 0 || x >= n || y < 0 || y >= n) break;
                ok++;
            }
            ans[i] = ok;
        }
        return ans;
    }
};

C 5965.相同元素的间隔之和

给出 n n n 个数,对于每个 k ∈ [ 0 , n ) k\in[0,n) k[0,n),求出 ∑ i = 0 n − 1 ∣ i − k ∣ × [ a i = = a k ] \sum\limits_{i=0}^{n-1}|i-k|\times[a_i==a_k] i=0n1ik×[ai==ak]

1 ≤ n ≤ 1 0 5 , 1 ≤ a i ≤ 1 0 5 1\le n\le 10^5, 1\le a_i\le 10^5 1n105,1ai105

做法

很套路的题,把 a i a_i ai 相同的放到一个数组里,然后求一下前缀和,把绝对值拆开计算即可。
复杂度为 O ( n ) O(n) O(n) 或者 O ( n l o g n ) O(nlogn) O(nlogn)

代码
typedef long long ll;
class Solution {
public:
    vector<long long> getDistances(vector<int>& arr) {
        map<int, vector<int>> mp;
        int n = arr.size();
        vector<ll> ans(n);
        for(int i = 0; i < n; i++) mp[arr[i]].push_back(i);
        for(auto& e: mp){
            auto& v = e.second;
            int n = v.size();
            vector<ll> s(n);
            for(int i = 0; i < n; i++){
                if(i > 0) s[i] = s[i - 1];
                s[i] += v[i];
            }
            auto cal = [&](int l, int r){
                if(l > r) return 0ll;
                ll a = s[r], b = (l > 0? s[l - 1]: 0);
                return a - b;
            };
            for(int i = 0; i < n; i++){
                ll t1 = i + 1, t2 = n - i;
                ll s1 = t1 * v[i] - cal(0, i), s2 = cal(i, n - 1) - t2 * v[i];
                ans[v[i]] = s1 + s2;
            }
        }
        return ans;
    }
};

D 5966. 还原原数组

给出 2 n 2n 2n 个数,问能否划分成 n n n ( b i , c i ) (b_i,c_i) (bi,ci),满足 c i > b i , c i − b i c_i>b_i,c_i-b_i ci>bi,cibi 都相等,并且 c i ≡ b i ( m o d    2 ) c_i\equiv b_i(\mod 2) cibi(mod2),返回 b i + c i 2 \frac{b_i+c_i}{2} 2bi+ci。保证有解。

1 ≤ n ≤ 1000 1\le n\le 1000 1n1000

做法

九折还 h a r d hard hard

枚举 c i − b i c_i-b_i cibi 的值,然后从小到大枚举 b i b_i bi,用一个 s e t set set 或者 m u l t i s e t multiset multiset 或者 m a p map map 来快速判断有没有匹配的 c i c_i ci
总的复杂度是 O ( n l o g n ) O(nlogn) O(nlogn)

代码
class Solution {
public:
    vector<int> recoverArray(vector<int>& nums) {
        sort(nums.begin(), nums.end());
        int n = nums.size();
        for(int i = 1; i < n; i++){
            vector<int> vis(n);
            int k = nums[i] - nums[0];
            if(k == 0 || k % 2) continue;
            set<pair<int, int>> s;
            for(int j = 0; j < n; j++) s.insert({nums[j], j});
            vector<int> a;
            vis[0] = vis[i] = 1;
            a.push_back((nums[i] + nums[0]) / 2);
            s.erase({nums[0], 0}), s.erase({nums[i], i});
            int ok = 1;
            for(int j = 1; j < n; j++){
                if(vis[j]) continue;
                int v = nums[j] + k;
                auto it = s.lower_bound({v, 0});
                if(it == s.end() || it->first != v){
                    ok = 0;
                    break;
                }
                a.push_back((nums[j] + v) / 2);
                vis[j] = vis[it->second] = 1;
                s.erase({nums[j], j}), s.erase({it->first, it->second});
            }
            if(ok){
                return a;
                break;
            }
        }
        return {};
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值