周赛补题

leetcode 单 :  

第一题icon-default.png?t=M666https://leetcode.cn/problems/number-of-arithmetic-triplets/数据范围不大,可以直接枚举

class Solution {
public:
    int arithmeticTriplets(vector<int>& nums, int diff) {
        int count = 0;
        
        for(int i = 0; i < nums.size(); i ++){
            for(int j = 0; j < nums.size(); j ++){
                for(int k = 0; k < nums.size(); k ++){
                    if(nums[i] + diff == nums[j] && nums[j] + diff == nums[k])  count ++;
                }
            }
        }
        
        return count;
    }
};

当然我们可以用哈希表来优化,unordered_map 来存储出现的数,在利用 count 来检阅其中是否存在 nums[i] - diff 与 nums[i] + diff 即可

class Solution {
public:
    int arithmeticTriplets(vector<int>& nums, int diff) {
        int n = nums.size();
        unordered_set<int> st;

        for (int x : nums) st.insert(x);
        
        int ans = 0;
        for (int i = 0; i < n; i++) if (st.count(nums[i] - diff) > 0 && st.count(nums[i] + diff) > 0) ans++;

        return ans;
    }
};

第二题icon-default.png?t=M666https://leetcode.cn/problems/reachable-nodes-with-restrictions/bfs() 来解决,用 unordered_map 来模拟邻接链表,同时利用 set 的 count 函数查找

class Solution {
public:
    int reachableNodes(int n, vector<vector<int>>& edges, vector<int>& rest) {
        unordered_map<int, vector<int>> ans;
        unordered_set<int> kp(rest.begin(), rest.end());

        for(int i = 0; i < edges.size(); i ++){
            ans[edges[i][0]].push_back(edges[i][1]);
            ans[edges[i][1]].push_back(edges[i][0]);
        }

        queue<int> res;
        res.push(0);
        
        int count = 1;
        while(!res.empty()){
            int t = res.front();
            res.pop();

            for(auto c : ans[t]){
                if(kp.count(c))  continue;

                count ++;
                res.push(c);
            }

            kp.insert(t);
        }

        return count;
    }
};

第三题icon-default.png?t=M666https://leetcode.cn/problems/check-if-there-is-a-valid-partition-for-the-array/递推,设dp[j]表示 nums[j+1] 即从 0 到 j 的连续子数组能否进行划分。由于每次可以切出 2 个或 3 个,因此dp[j]只能由 dp[j-2] 或 dp[j-3] 转移而来。

class Solution {
public:
    bool validPartition(vector<int>& nums) {
        int n = nums.size();
        vector<bool> ans(n + 1);
        ans[0] = true;

        for(int i = 1; i <= n; i ++){
            if(i >= 2){
                if(nums[i - 2] == nums[i - 1])  ans[i] = ans[i] || ans[i - 2];
            }

            if(i >= 3){
                if(nums[i - 3] == nums[i - 2] && nums[i - 2] == nums[i - 1]){
                    ans[i] = ans[i] || ans[i - 3];
                }

                if(nums[i - 3] + 1 == nums[i - 2] && nums[i - 2] + 1 == nums[i - 1]){
                    ans[i] = ans[i] || ans[i - 3];
                }
            }
        }

        return ans[n];
    }
};


第四题icon-default.png?t=M666https://leetcode.cn/problems/longest-ideal-subsequence/

设 f(c) 表示从头开始遍历过程中,以字符 c 结尾的最长理想字符串的长度。
初始时,f(c)=0。
转移时,对于当前位置 c:=s(i),找到下标 [c−k,c+k] 内的 f 的最大值 m,转移 f(c)=m+1。
最终答案为 max(f(c))

class Solution {
public:
    int longestIdealString(string s, int k) {
        int n = s.size();
        vector<int> ans(26);

        for(int i = 0; i < n; i ++){
            int t = s[i] - 'a';

            int zhon = 0;
            for(int j = max(0, t - k); j <= min(25, t + k); j ++){
                zhon = max(zhon, ans[j]);
            }

            ans[t] = zhon + 1;
        }

        int res = 0;
        for(int i = 0; i < 26; i ++)  res = max(res, ans[i]);

        return res;
    }
};

leetcode 双 :  

第一题icon-default.png?t=M666https://leetcode.cn/problems/merge-similar-items/用map存储合并数据,因其有序,直接拷贝至vector即可

class Solution {
public:
    vector<vector<int>> mergeSimilarItems(vector<vector<int>>& items1, vector<vector<int>>& items2) {
        map<int, int> ans;

        for(auto c : items1)  ans[c[0]] += c[1];
        for(auto c : items2)  ans[c[0]] += c[1];

        vector<vector<int>> res;
        for(auto it = ans.begin(); it != ans.end(); it ++){
            res.push_back({it -> first, it -> second});
        }

        return res;
    }
};

第二题icon-default.png?t=M666https://leetcode.cn/problems/count-number-of-bad-pairs/将题目中的公式变形,可以转为求 nums[i] - i != nums[j] - j 的数对数量。
使用哈希表存储,再通过总数对数量,减去哈希表中相同数字组成数对的数量。

class Solution {
public:
    long long countBadPairs(vector<int>& nums) {
        long long sum = 0, n = nums.size();
        map<int, int>mp;
        for(int i = 0; i < n; i++)  mp[i - nums[i]]++;

        for(map<int, int>::iterator it = mp.begin(); it != mp.end(); it++) {
            sum += (long long)it->second * (long long)(it->second - 1) / 2;
        }

        return n * (n - 1) / 2 - sum;
    }
};

第三题icon-default.png?t=M666https://leetcode.cn/problems/task-scheduler-ii/按顺序遍历任务数组,使用变量 day 记录天数,即完成当前任务后的下一天。天数从 0 开始。
使用哈希表记录上一次完成同种任务的 day。
遍历时,如果发现上一次完成同种任务时的间隔天数不足 space,则重置 day:=last(t)+space+1。

class Solution {
public:
    long long taskSchedulerII(vector<int>& tasks, int space) {
        unordered_map<int, long long> ans;

        long long res = 0;
        for(auto c : tasks){
            if(ans.find(c) != ans.end() && res <= space + ans[c]){
               res = space + ans[c] + 1;
            }

            ans[c] = res;
            res ++;
        }

        return res;
    }
};

第四题icon-default.png?t=M666https://leetcode.cn/problems/minimum-replacements-to-sort-the-array/假设b以及b后面的序列都已经处理好了 满足非递减,那么a需要被分解
a = a1+a2+…+ak;且a1<=a2<=…<=ak
那么我们需要a1最大 a1最大肯定是平均分 a1max = a/k
本题需要k尽量小 巧合的是 当k最小,a1max才最大
于是我们每次可以找到最小的k 从而计算出a1max
最小的k肯定是a/b上取整

class Solution {
public:
    long long minimumReplacement(vector<int>& nums) {
        long long res = 0;

        for(int i = nums.size() - 2, b = nums.back();i >= 0; i --){
            int a = nums[i];
            int k = (a + b - 1) / b;
            res += k - 1;
            b = a / k;
        }

        return res;
    }
};

acwing :  

第一题icon-default.png?t=M666https://www.acwing.com/problem/content/4506/枚举即可

#include <bits/stdc++.h>
using namespace std;

int main(){
    int a, b, n;
    cin >> a >> b >> n;
    
    int count = 0;
    for(int i = 0; i <= a; i ++){
        for(int j = 0; j <= b; j ++){
            if(i + j == n){
                count ++;
            }
        }
    }
    
    cout << count << endl;
    return 0;
}

第二题icon-default.png?t=M666https://www.acwing.com/problem/content/4507/用栈简单模拟即可

#include <bits/stdc++.h>
using namespace std;

int main(){
    string a;
    cin >> a;
    
    stack<char> ans;
    int count = 0;
    for(int i = 0; i < a.size(); i ++){
        if(!ans.empty() && a[i] == ans.top()){
            ans.pop();
            count ++;
        }
        else  ans.push(a[i]);
    }
    
    if(count & 1)  cout << "Yes" << endl;
    else  cout << "No" << endl;
    
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值