力扣周赛 503

Q1.限制有序数组中的元素出现次数

🔗 https://leetcode.cn/contest/weekly-contest-503/problems/limit-occurrences-in-sorted-array/description/

题目

  • 给定升序整数数组 nums 和整数 k
  • 返回去重后每个元素最多保留 k 个的数组(保持原顺序)

思路

  • 模拟

代码

cpp 复制代码
class Solution {
public:
    vector<int> limitOccurrences(vector<int>& nums, int k) {
        vector<int> ans;
        int cnt = 1;
        ans.push_back(nums[0]);
        for (int i = 1; i < nums.size(); i++) {
            if (nums[i] == nums[i-1]) 
                cnt++;
            else
                cnt = 1;
            if (cnt <= k) {
                ans.push_back(nums[i]);
            }
        }
        return ans;
    }
};

Q2. 密码强度

🔗 https://leetcode.cn/contest/weekly-contest-503/problems/password-strength/description/

题目

  • 给定字符串 password
  • 按出现过的不同字符计分并求和:小写字母 1分,大写字母 2分,数字 3分,特殊字符 5分
  • 返回总分

思路

  • 模拟

代码

cpp 复制代码
class Solution {
public:
    int passwordStrength(string password) {
        int ans = 0;
        set<char> s;
        for (char ch : password) {
            if (s.count(ch)) continue;
            s.insert(ch);
            if (ch >= '0' && ch <= '9') ans += 3;
            if (ch >= 'a' && ch <= 'z') ans += 1;
            if (ch >= 'A' && ch <= 'Z') ans += 2;
            if (ch == '!' || ch == '@' || ch == '#' || ch == '$') ans += 5;
        }
        return ans;
        
    }
};

Q3. 排序排列的最少操作数

🔗 https://leetcode.cn/contest/weekly-contest-503/problems/minimum-operations-to-sort-a-permutation/description/

题目

  • 给定 [0..n-1] 的一个排列 nums
  • 每次只能"反转整个数组"或"左旋一位"
  • 返回将其排成升序的最少操作次数,无法排序则返回 -1

思路

  • 最终都升序,需要当前的梯度变化仅一次
  • 即若当前都升序,仅存在一处降序;反之,若当前都降序,仅存在一处升序;都在首位相交的地方;
  • 找到升序开始的位置 idx,也就是 0 的位置,调整的方案:
    • 左旋 idx 次
    • 先反转,再左旋 len - idx 次,再反转
  • 找到降序开始的位置 idx,调整的方案:
    • 左旋 idx 次,反转
    • 反转,左旋 len - idx 次

代码

cpp 复制代码
class Solution {
public:
    int minOperations(vector<int>& nums) {
        int len = nums.size();
        if (len == 1) return 0;
        vector<int> n(nums);
        for (auto num : nums) {
            n.push_back(num);
        }
        int asc = 1, dsc = 1;
        int max_asc = -1, max_dsc = -1;
        for (int i = 1; i < n.size(); i++) {
            if (n[i] > n[i-1]) {
                asc++;
                dsc = 1;
            } else {
                asc = 1;
                dsc++;
            }
            if (max_asc == -1 && asc == len) max_asc = i;
            if (max_dsc == -1 && dsc == len) max_dsc = i;
        }

        if (max_asc == -1 && max_dsc == -1) return -1;
        int ans = n.size();
        if (max_dsc != -1) {
            int idx = max_dsc - len + 1;
            ans = min(ans, idx + 1); // 左旋 idx + 反转
            ans = min(ans, 1 + len - idx); // 反转 + 左旋
        }
        if (max_asc != -1) {
            int idx = max_asc - len + 1;
            ans = min(ans, idx); // 左旋
            ans = min(ans, 2 + len - idx); // 反转 + 左旋 + 反转
        }
        return ans;
        
    }
};

Q4. 递增后的数对数量

🔗 https://leetcode.cn/contest/weekly-contest-503/problems/number-of-pairs-after-increment/

题目

  • 给定数组 nums1nums2 和查询 queries
  • 支持两种操作:
    • 区间加(将 nums2[x..y] 每个元素加 val);
    • 计数(统计满足 nums1[j] + nums2[k] == tot 的下标对 (j,k) 数量)
  • 返回每次计数查询的结果数组

思路

  • 暴力必定 TLE,nums1 的长度不超过 5,核心就是精简对 num2 上的操作,采用分块法
  • 每个块上的 add_val,就记做一个整体,块两边的,逐个更新;
  • 块大小的最优解为 sqrt(num2.size()),作为一种平衡
  • 注意:map 直接 count 不存在的元素,会插入元素,对性能有影响

代码

cpp 复制代码
class Solution {
public:
    vector<int> numberOfPairs(vector<int>& nums1, vector<int>& nums2, vector<vector<int>>& queries) {
        struct Block {
            unordered_map<long long, int> freq;
            long long lazy_val;
            
        };

        // init block with map & lazy_val
        int n = nums2.size();
        int size = sqrt(n);
        int B = (n + size - 1) / size;
         vector<long long> arr(n); 

        vector<Block> block(B);
        for (int i = 0;i < n; i++) {
            arr[i] = nums2[i]; 
            block[i / size].freq[nums2[i]]++;
            block[i / size].lazy_val = 0;
        }

        // process queryies
        vector<int> ans;
        auto add = [&](int x, int y, int val) {
            int l = x / size;
            int r = y / size;
            if (l == r) {
                for (int i = x; i <= y; i++) {
                    if (--block[l].freq[arr[i]] == 0) block[l].freq.erase(arr[i]);
                    arr[i] += val;
                    block[l].freq[arr[i]]++;
                }
                return;
            }

            for (int i = x; i < (l + 1) * size; i++) {                    
                    if (--block[l].freq[arr[i]] == 0) block[l].freq.erase(arr[i]); 
                    arr[i] += val;
                    block[l].freq[arr[i]]++;
                
            }

            for (int i = l + 1; i < r; i++) {
                block[i].lazy_val += val;
            }

            for (int i = r * size; i <= y; i++) {
                    if (--block[r].freq[arr[i]] == 0) block[r].freq.erase(arr[i]); 
                    arr[i] += val;
                    block[r].freq[arr[i]]++;
                
            }
            
        };

        auto count = [&](int tot) {
            int cnt = 0;
            for (int i = 0; i < B; i++) {
                for (int j = 0; j < nums1.size(); j++) {
                    long long target = tot - nums1[j] - block[i].lazy_val;
                    auto it = block[i].freq.find(target);
                    if (it != block[i].freq.end()) {
                        cnt += it->second;
                    }   
                }
            }
            ans.push_back(cnt);
        };

        for (auto query : queries) {
            if (query[0] == 1) {
                add(query[1], query[2], query[3]);
            } else {
                count(query[1]);
            }
        }

        return ans;
    }
};
相关推荐
Nontee13 小时前
三大范式是什么?
java·前端·数据库
sheeta199813 小时前
LeetCode 每日一题笔记 日期:2026.05.21 题目:3043. 最长公共前缀的长度
笔记·算法·leetcode
Chase_______13 小时前
【Java】String 常量池、== 与 equals 详解:从引用比较到 intern() 一次讲清
java·开发语言
专注VB编程开发20年13 小时前
B4A要编绎成Release发布APP/waiting for ide debugger to connect
java·b4a
吃好睡好便好13 小时前
创建随机矩阵
开发语言·人工智能·线性代数·算法·matlab·矩阵
我欲扶摇九万里13 小时前
Mac版idea快捷键失效的原因及解决方法
java·macos·intellij-idea
拙野13 小时前
【保姆级教程】Claude Code无缝集成DeepSeek V4 Pro
java·人工智能·deepseek·claudecode·ai coding
sheeta199813 小时前
LeetCode 每日一题笔记 日期:2026.05.23 题目:1752. 检查数组是否经排序和轮转得到
笔记·算法·leetcode
likerhood13 小时前
设计模式 · 代理模式(Proxy Pattern)java
java·设计模式·代理模式