【教3妹学编程-算法题】将数组分成最小总代价的子数组 II

news2024/10/4 10:22:25

瑟瑟发抖

2哥 : 叮铃铃,3妹,过年干嘛呢,是不是逛吃逛吃,有没有长胖呢。
3妹:切,我妈张罗着要给我相亲呢。
2哥 : 相亲?哈哈哈哈
3妹:别笑了,我妈说跟我年龄相等的人都已经孩子上小学了,跟她年龄相等的人孙子最少都会打酱油了。
2哥 :哈哈哈哈,让我先笑一会儿
3妹:话说2哥过年在家里也刷题吗?
2哥:当然了,雷打不动。
3妹:好吧,还得是2哥🐂,我有几天懈怠了。
2哥:好吧,说到刷题啊,今天有一道“最小”的题目, 让我们先做一下吧~

吃瓜

题目:

给你一个下标从 0 开始长度为 n 的整数数组 nums 和两个 正 整数 k 和 dist 。

一个数组的 代价 是数组中的 第一个 元素。比方说,[1,2,3] 的代价为 1 ,[3,4,1] 的代价为 3 。

你需要将 nums 分割成 k 个 连续且互不相交 的子数组,满足 第二 个子数组与第 k 个子数组中第一个元素的下标距离 不超过 dist 。换句话说,如果你将 nums 分割成子数组 nums[0…(i1 - 1)], nums[i1…(i2 - 1)], …, nums[ik-1…(n - 1)] ,那么它需要满足 ik-1 - i1 <= dist 。

请你返回这些子数组的 最小 总代价。

示例 1:

输入:nums = [1,3,2,6,4,2], k = 3, dist = 3
输出:5
解释:将数组分割成 3 个子数组的最优方案是:[1,3] ,[2,6,4] 和 [2] 。这是一个合法分割,因为 ik-1 - i1 等于 5 - 2 = 3 ,等于 dist 。总代价为 nums[0] + nums[2] + nums[5] ,也就是 1 + 2 + 2 = 5 。
5 是分割成 3 个子数组的最小总代价。
示例 2:

输入:nums = [10,1,2,2,2,1], k = 4, dist = 3
输出:15
解释:将数组分割成 4 个子数组的最优方案是:[10] ,[1] ,[2] 和 [2,2,1] 。这是一个合法分割,因为 ik-1 - i1 等于 3 - 1 = 2 ,小于 dist 。总代价为 nums[0] + nums[1] + nums[2] + nums[3] ,也就是 10 + 1 + 2 + 2 = 15 。
分割 [10] ,[1] ,[2,2,2] 和 [1] 不是一个合法分割,因为 ik-1 和 i1 的差为 5 - 1 = 4 ,大于 dist 。
15 是分割成 4 个子数组的最小总代价。
示例 3:

输入:nums = [10,8,18,9], k = 3, dist = 1
输出:36
解释:将数组分割成 4 个子数组的最优方案是:[10] ,[8] 和 [18,9] 。这是一个合法分割,因为 ik-1 - i1 等于 2 - 1 = 1 ,等于 dist 。总代价为 nums[0] + nums[1] + nums[2] ,也就是 10 + 8 + 18 = 36 。
分割 [10] ,[8,18] 和 [9] 不是一个合法分割,因为 ik-1 和 i1 的差为 3 - 1 = 2 ,大于 dist 。
36 是分割成 3 个子数组的最小总代价。

提示:

3 <= n <= 10^5
1 <= nums[i] <= 10^9
3 <= k <= n
k - 2 <= dist <= n - 2

思路:

思考

维护两个有序集合前K-1小的数,
第一段的第一个数是确定的,即 nums[0]。

如果知道了第二段的第一个数的位置(记作 p),第三段的第一个数的位置,……,第 k 段的第一个数的位置(记作 q),那么这个划分方案也就确定了。

考虑到 q−p≤dist,本题相当于在一个大小固定为 dist+1的滑动窗口内,求前 k−1 小的元素和。

java代码:

public class Solution {
    public long minimumCost(int[] nums, int k, int dist) {
        k--;
        sumL = nums[0];
        for (int i = 1; i < dist + 2; i++) {
            sumL += nums[i];
            L.merge(nums[i], 1, Integer::sum);
        }
        sizeL = dist + 1;
        while (sizeL > k) {
            l2r();
        }

        long ans = sumL;
        for (int i = dist + 2; i < nums.length; i++) {
            // 移除 out
            int out = nums[i - dist - 1];
            if (L.containsKey(out)) {
                sumL -= out;
                sizeL--;
                removeOne(L, out);
            } else {
                removeOne(R, out);
            }

            // 添加 in
            int in = nums[i];
            if (in < L.lastKey()) {
                sumL += in;
                sizeL++;
                L.merge(in, 1, Integer::sum);
            } else {
                R.merge(in, 1, Integer::sum);
            }

            // 维护大小
            if (sizeL == k - 1) {
                r2l();
            } else if (sizeL == k + 1) {
                l2r();
            }

            ans = Math.min(ans, sumL);
        }
        return ans;
    }

    private long sumL;
    private int sizeL;
    private final TreeMap<Integer, Integer> L = new TreeMap<>();
    private final TreeMap<Integer, Integer> R = new TreeMap<>();

    private void l2r() {
        int x = L.lastKey();
        removeOne(L, x);
        sumL -= x;
        sizeL--;
        R.merge(x, 1, Integer::sum);
    }

    private void r2l() {
        int x = R.firstKey();
        removeOne(R, x);
        sumL += x;
        sizeL++;
        L.merge(x, 1, Integer::sum);
    }

    private void removeOne(Map<Integer, Integer> m, int x) {
        int cnt = m.get(x);
        if (cnt > 1) {
            m.put(x, cnt - 1);
        } else {
            m.remove(x);
        }
    }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1457327.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

为什么2023年是AI视频的突破年,以及对2024年的预期#a16z

2023年所暴露的AI生成视频的各种问题&#xff0c;大部分被OpenAI发布的Sora解决了吗&#xff1f;以下为a16z发布的总结&#xff0c;在关键之处&#xff0c;我做了OpenAI Sora的对照备注。 推荐阅读&#xff0c;了解视频生成技术进展。 Why 2023 Was AI Video’s Breakout Year,…

开发消息多发工具需要用到的源代码

在数字化时代&#xff0c;消息传递是许多应用程序的核心功能之一&#xff0c;从社交媒体到企业通信&#xff0c;从个人聊天到群发消息&#xff0c;消息传递无处不在&#xff0c;为了满足这种需求&#xff0c;开发者经常需要创建或定制消息多发工具。 这些工具通常需要处理多个…

MySQL数据库基础(十):DQL数据查询语言

文章目录 DQL数据查询语言 一、数据集准备 二、select查询 三、简单查询 四、条件查询 1、比较查询 2、范围查询 3、逻辑查询 4、模糊查询 5、非空查询 五、排序查询 六、聚合查询 七、分组查询与having子句 1、分组查询介绍 2、group by的使用 3、group by 聚…

【深入理解设计模式】单例设计模式

单例设计模式 概念&#xff1a; 单例模式&#xff08;Singleton Pattern&#xff09;是 Java 中最简单的设计模式之一。 单例设计模式是一种创建型设计模式&#xff0c;其主要目的是确保类在应用程序中的一个实例只有一个。这意味着无论在应用程序的哪个位置请求该类的实例&a…

网站常见的反爬手段及反反爬思路

摘要:介绍常见的反爬手段和反反爬思路&#xff0c;内容详细具体&#xff0c;明晰解释每一步&#xff0c;非常适合小白和初学者学习&#xff01;&#xff01;&#xff01; 目录 一、明确几个概念 二、常见的反爬手段及反反爬思路 1、检测user-agent 2、ip 访问频率的限制 …

Web服务器基础

Web服务器基础 【一】前端概述 【1】HTML HTML&#xff08;超文本标记语言&#xff09;是用于创建网页结构的标记语言。它定义了网页的骨架&#xff0c;包括标题、段落、列表、链接等元素&#xff0c;但没有样式。可以将HTML视为网页的结构和内容的描述。 【2】CSS css&…

NAS系统折腾记 | TinyMediaManager刮削电影海报

搭建好了NAS系统和Emby Media Server&#xff0c;接下来就是怎样对下载好的电影/电视剧集等内容进行刮削来展示电影海报墙获得更好的效果了。实际上&#xff0c;Emby Server本身就内置了强大的元数据抓取功能&#xff0c;能够自动从互联网上抓取电影、电视剧的元数据和海报等信…

mysql在服务器中的主从复制Linux下

mysql在服务器中的主从复制Linux下 为什么要进行主从复制主从复制的原理主从复制执行流程操作步骤主库创建从库创建 测试 为什么要进行主从复制 在业务中通常会有情况&#xff0c;在sql执行时&#xff0c;将表锁住&#xff0c;导致不能进行查询&#xff0c;这样就会影响业务的…

【教程】MySQL数据库学习笔记(一)——认识与环境搭建(持续更新)

写在前面&#xff1a; 如果文章对你有帮助&#xff0c;记得点赞关注加收藏一波&#xff0c;利于以后需要的时候复习&#xff0c;多谢支持&#xff01; 【MySQL数据库学习】系列文章 第一章 《认识与环境搭建》 第二章 《数据类型》 文章目录 【MySQL数据库学习】系列文章一、认…

C++ 位运算常用操作 二进制中1的个数

给定一个长度为 n 的数列&#xff0c;请你求出数列中每个数的二进制表示中 1 的个数。 输入格式 第一行包含整数 n 。 第二行包含 n 个整数&#xff0c;表示整个数列。 输出格式 共一行&#xff0c;包含 n 个整数&#xff0c;其中的第 i 个数表示数列中的第 i 个数的二进制表…

深度解析 Transformer 模型:原理、应用与实践指南【收藏版】

深度解析 Transformer 模型&#xff1a;原理、应用与实践指南 1. Transformer 模型的背景与引言2. Transformer 模型的原理解析2.1 自注意力机制&#xff08;Self-Attention&#xff09;自注意力机制原理 2.2 多头注意力机制&#xff08;Multi-Head Attention&#xff09;多头注…

vue的生命周期图解

vue的生命周期图解 添加链接描述 vue的生命周期函数及过程的简述&#xff1a; vue的生命周期函数&#xff0c;其实就是vm的生命周期&#xff1b; 创建&#xff1a;beforeCreate、created 挂载&#xff1a;beforeMount、mounted 更新&#xff1a;beforeUpdate、updated [ˌʌpˈ…

(AtCoder Beginner Contest 341)(A - D)

比赛地址 : Tasks - Toyota Programming Contest 2024#2&#xff08;AtCoder Beginner Contest 341&#xff09; A . Print 341 模拟就好了 &#xff0c; 先放一个 1 , 然后放 n 个 01 ; #include<bits/stdc.h> #define IOS ios::sync_with_stdio(0);cin.tie(0);cout…

初始HTTP协议

一、http协议 1、http相关概念 互联网&#xff1a;是网络的网络&#xff0c;是所有类型网络的母集因特网&#xff1a;世界上最大的互联网网络。即因特网概念从属于互联网概念。习惯上&#xff0c;大家把连接在因特网上的计算机都成为主机。万维网&#xff1a;WWW&#xff08;…

vue3项目配置按需自动引入自定义组件unplugin-vue-components

我们通常在项目中&#xff0c;需要手动引入自定义的各种组件&#xff0c;如果涉及的页面功能比较多的话&#xff0c;光是import的长度都能赶上春联了。 如果&#xff0c;能有一个插件帮我们实现自动引入&#xff0c;是不是要谢天谢地了呢&#xff1f; 接下来就进入我们的主角u…

Vue2尚品汇前台项目笔记——(1)项目初始化

Vue2尚品汇前台项目笔记 一、项目初始化 使用[脚手架创建项目&#xff0c;具体参考之前的脚手架配置笔记&#xff0c;我起名叫vue_shop_test 1.脚手架目录分析 node_modules文件夹&#xff1a;项目依赖文件夹 public文件夹&#xff1a;一般放置一些静态资源&#xff08;图…

蓝桥杯:C++二叉树

二叉树 几乎每次蓝桥杯软件类大赛都会考核二叉树&#xff0c;它或者作为数据结构题出现&#xff0c;或者应用在其他算法中。大部分高级数据结构是基于二叉树的&#xff0c;例如常用的高级数据结构线段树就是基于二叉树的。二叉树应用广泛和它的形态有关。 二叉树的定义&#x…

Junit测试套件(Test Suite)

0. 什么是测试套件 对多个测试类的统一执行 只有一个测试类 点击一下执行就好有 5个测试类 分别打开 挨个点执行有100个测试类 &#xff1f;&#xff1f;分别点开执行 为100个测试类创建一个测试套件&#xff0c;然后再执行一次测试套件 √ 一个测试套件“囊括“三个测试类…

【Funny Game】 人生重开模拟器

目录 【Funny Game】 人生重开模拟器&#xff01; 人生重开模拟器&#xff01; 文章所属专区 Funny Game 人生重开模拟器&#xff01; 人生重开模拟器&#xff0c;让你体验从零开始的奇妙人生。在这个充满惊喜和挑战的游戏中&#xff0c;你可以自由选择性别、出生地、家庭背景…

Bpmn-js 属性控制

我们可以通过bpmn-js来访问对应的BPMN图例的属性信息。对应的流程图中的每个图例元素&#xff08;如开始、结束、中间/边界事件等都通过businessObject属性存储对基础BPMN元素的引用。业务对象是从BPMN 2.0 XML导入并在导出过程中序列化的实际元素。使用业务对象来读取和写入BP…