当前位置: 首页 > news >正文

滑动窗口算法-day11(不定长选做)

1.每种字符至少取 K 个

题目

解析

  • 要求取两边的元素,且三种元素数量不能小于 K;
  • 反向思维转化为:先计算每个元素个数到 cnt,构建窗口,依次消减 cnt,若新进队元素 x 使得 cnt[x] < K,则移动窗口;
  • 注意点:若本身就有元素总数小于 K,直接返回 -1;

代码

class Solution {
public:
    int takeCharacters(string s, int k) {
        // 时间复杂度:O(n)
        // 空间复杂度:O(1)

        int n = s.size();
        int ans = 0;

        unordered_map<char,int> cnt;
        for(char c : s) cnt[c] ++;

        // 如果任何字符的数量小于 k,直接返回 -1
        if (cnt['a'] < k || cnt['b'] < k || cnt['c'] < k) {
            return -1;
        }

        int l = 0;
        for(int r = 0;r < n;r ++) {
            cnt[s[r]] --;

            while(cnt[s[r]] < k){
                cnt[s[l]] ++;
                l ++;
            } 

            ans = max(ans,r - l + 1);
        }

        return n - ans;
    }
};

2.数组的最大美丽值

题目

解析

  • 由于答案记录最终数组中最多相等的数,所以与数组顺序无关,直接排序;
  • 将每个数字 x 想象成一个数值范围,例如 (x - k, x + k),(y - k, y + k);
  • 若要两个数字可以转换,则需要满足 x + k >= y - k,即 y - x <= 2 * k;
  • 遍历数组,若两头数字不满足条件转换,则令 L++;满足则更新答案;

代码

class Solution {
public:
    int maximumBeauty(vector<int>& nums, int k) {
        // 时间复杂度:O(nlogn)
        // 空间复杂度:O(1)

        int n = nums.size();
        int ans = 0;

        sort(nums.begin(),nums.end());// 排序不影响结果

        int l = 0;
        for(int r = 0;r < n;r ++){
            // 若右边界元素和左边界元素取值范围无交集,则移动窗口
            while(nums[r] - nums[l] > 2 * k){
                l ++;
            }

            ans = max(ans,r - l + 1);
        }

        return ans;
    }
};

3.最高频元素的频数

题目

解析

  • 题目要求最高频元素的频数,与数组顺序无关,直接排序;
  • 核心思想:计算窗口每个元素与右边界元素的距离和
  • 一开始我的思路是加上每两个元素之间的差值,使其小于 k,但其实不是这样算;
  • 计算公式为:(nums[r] - nums[r - 1]) * (r - l)
  • 当距离和超过 K 时,就要移动窗口,没超过就更新答案最大值;

公式推导:

画出来的面积就是窗口每个元素与右边界元素的距离和nums[r] - nums[r - 1] 是矩形高,r - l 是矩形宽;

代码

class Solution {
public:
    int maxFrequency(vector<int>& nums, int k) {
        // 时间复杂度:O(nlogn)
        // 空间复杂度:O(1)

        int n = nums.size();
        int ans = 1;
        long long sum = 0;

        sort(nums.begin(),nums.end());

        int l = 0;
        for(int r = 1;r < n;r ++){
            // 计算窗口内元素到窗口右边界元素距离总和
            sum += (long long)(nums[r] - nums[r - 1]) * (r - l);

            while(sum > k) {
                // 减去窗口左边界元素到右边界元素距离
                sum -= nums[r] - nums[l];
                l ++;
            }

            ans = max(ans,r - l + 1);
        }

        return ans;
    }
};

相关文章:

  • Ollama+ WebUI 部署deepseek-r1
  • qemu分析之 KVM_EXIT_MMIO
  • 【C++标准库类型】深入理解C++中的using声明:从基础到实践
  • 关于ModbusTCP/RTU协议对接Ethernet/IP(CIP)协议的方案
  • 大模型剪枝、量化、蒸馏的区别和联系
  • 自动化测试 | Python+PyCharm+Google Chrome+Selenium 环境安装记录
  • 【MySQL】MySQL服务器——mysqld
  • Java 大视界 -- 基于 Java 的大数据机器学习模型的迁移学习应用与实践(129)
  • Redis的缓存雪崩、缓存击穿、缓存穿透与缓存预热、缓存降级
  • 数据可信、隐私可控:CESS 如何打造波卡生态数据新基建?
  • Netty基础—4.NIO的使用简介一
  • laravel项目中使用FFMPeg 剪裁视频
  • 电子电气架构 --- 智能电动汽车概述
  • 【InterruptCallBack】- KRTS C++示例精讲(14)
  • java自带日志系统介绍(JUL)以及和Log4j 2、Logback、SLF4J不同日志工具的对比
  • 【解决方案】RAGFlow部分问题清单及解决方案备忘1
  • 专业视角:set 和 multiset的原理与应用解析
  • 星海智算:风月ComfyUI_SD3.5使用教程
  • 嵌入式开发工程师笔试面试指南-模电基础
  • uni-app vue2 记住密码功能
  • 怎么查网站是哪家制作公司做的/建站优化公司
  • 点图片跳到网站怎么做/百度一下百度下载
  • 动态网站开发与设计关键技术/东莞百度seo电话
  • wordpress 美拍插件/seo发包软件
  • 网站开发 毕业答辩ppt/聊城seo优化
  • 磁力天堂/新乡seo推广