力扣122双周赛

第 122 场双周赛

文章目录

  • [第 122 场双周赛](#第 122 场双周赛)
    • [将数组分成最小总代价的子数组 I](#将数组分成最小总代价的子数组 I)
    • 判断一个数组是否可以变为有序
    • [最多 K 个重复元素的最长子数组](#最多 K 个重复元素的最长子数组)
    • [将数组分成最小总代价的子数组 II](#将数组分成最小总代价的子数组 II)

将数组分成最小总代价的子数组 I

暴力模拟

cpp 复制代码
class Solution {
public:
    int minimumCost(vector<int>& nums) {
        int ans = nums[0] , n = nums.size();
        int res = 1e9;
        for(int i = 1 ; i < n ; i ++){
            for(int j = i + 1 ; j < n ; j ++){
                res = min(res , nums[i] + nums[j]);
            }
        }
        return ans + res;
    }
};

判断一个数组是否可以变为有序

把1数目相同的分组排序在判断

cpp 复制代码
class Solution {
public:
    bool canSortArray(vector<int>& nums) {
        auto f = [&](int x) -> int{
            int sum = 0;
            for(int i = 0 ; i< 10 ; i ++){
                if(x >> i & 1)sum ++;
            }
            return sum;
        };
        int n = nums.size();
        vector<vector<int>>v;
        vector<int> s;
        for(int i = 0; i < n ; i ++){
            if(i != 0 && f(nums[i]) != f(nums[i - 1])){
                sort(s.begin() , s.end());
                v.push_back(s);
                s.clear();
            }
            s.push_back(nums[i]);
        }
        sort(s.begin() , s.end());
        v.push_back(s);
        
        int last = -1;
        for(int i = 0 ; i < v.size() ; i ++){
            auto x = v[i];
            // for(auto xx : x)cout << xx << " ";
            // cout << endl;
            int fir = x[0] , end = x[x.size() - 1];
            if(i == 0){
                last = end;
            }else{
                // cout << fir << "---" << end << "---" << last;
                // cout << endl;
                if(fir < last)return false;
                last = end;
            }
        }
        return true;
    }
};

最多 K 个重复元素的最长子数组

贪心,等于找最小的合并

cpp 复制代码
class Solution {
public:
    int gcd(int a, int b)
    {
        return b ? gcd(b, a % b) : a;
    }
    int minimumArrayLength(vector<int>& nums) {
        int c = 0;
        for(auto x: nums){
            c = gcd(c , x);
        }
        int cnt = count(nums.begin() , nums.end() , c);
        if(cnt != 0){
            if(cnt % 2)return cnt / 2 + 1;
            return cnt / 2;
        }
        return 1;
    }
};

将数组分成最小总代价的子数组 II

实质为求滑动窗口中的前 k 小值,模板

cpp 复制代码
// 两个 multiset 维护滑动窗口中的前 K 小值
struct Magic {
    int K;
    // st1 保存前 K 小值,st2 保存其它值
    multiset<long long> st1, st2;
    // sm 表示 st1 中所有数的和
    long long sm;

    Magic(int K): K(K), sm(0) {}

    // 调整 st1 和 st2 的大小,保证调整后 st1 保存前 K 小值
    void adjust() {
        while (st1.size() < K && st2.size() > 0) {
            long long t = *(st2.begin());
            st1.insert(t);
            sm += t;
            st2.erase(st2.begin());
        }
        while (st1.size() > K) {
            long long t = *prev(st1.end());
            st2.insert(t);
            st1.erase(prev(st1.end()));
            sm -= t;
        }
    }

    // 插入元素 x
    void add(long long x) {
        if (!st2.empty() && x >= *(st2.begin())) st2.insert(x);
        else st1.insert(x), sm += x;
        adjust();
    }

    // 删除元素 x
    void del(long long x) {
        auto it = st1.find(x);
        if (it != st1.end()) st1.erase(it), sm -= x;
        else st2.erase(st2.find(x));
        adjust();
    }
};

class Solution {
public:
    long long minimumCost(vector<int>& nums, int K, int dist) {
        int n = nums.size();

        // 滑动窗口初始化
        Magic magic(K - 2);
        for (int i = 1; i < K - 1; i++) magic.add(nums[i]);

        long long ans = magic.sm + nums[K - 1];
        // 枚举最后一个数组的开头
        for (int i = K; i < n; i++) {
            int t = i - dist - 1;
            if (t > 0) magic.del(nums[t]);
            magic.add(nums[i - 1]);
            ans = min(ans, magic.sm + nums[i]);
        }

        return ans + nums[0];
    }
};

--

相关推荐
感哥15 小时前
C++ 面向对象
c++
CoovallyAIHub17 小时前
中科大DSAI Lab团队多篇论文入选ICCV 2025,推动三维视觉与泛化感知技术突破
深度学习·算法·计算机视觉
沐怡旸17 小时前
【底层机制】std::shared_ptr解决的痛点?是什么?如何实现?如何正确用?
c++·面试
NAGNIP18 小时前
Serverless 架构下的大模型框架落地实践
算法·架构
moonlifesudo18 小时前
半开区间和开区间的两个二分模版
算法
moonlifesudo18 小时前
300:最长递增子序列
算法
CoovallyAIHub1 天前
港大&字节重磅发布DanceGRPO:突破视觉生成RLHF瓶颈,多项任务性能提升超180%!
深度学习·算法·计算机视觉
感哥1 天前
C++ STL 常用算法
c++
CoovallyAIHub1 天前
英伟达ViPE重磅发布!解决3D感知难题,SLAM+深度学习完美融合(附带数据集下载地址)
深度学习·算法·计算机视觉
saltymilk1 天前
C++ 模板参数推导问题小记(模板类的模板构造函数)
c++·模板元编程