【贪心】【分类讨论】2499. 让数组不相等的最小总代价

作者推荐

视频算法专题

本文涉及知识点

贪心 分类讨论

LeetCode2499. 让数组不相等的最小总代价

给你两个下标从 0 开始的整数数组 nums1 和 nums2 ,两者长度都为 n 。
每次操作中,你可以选择交换 nums1 中任意两个下标处的值。操作的 开销 为两个下标的 和 。
你的目标是对于所有的 0 <= i <= n - 1 ,都满足 nums1[i] != nums2[i] ,你可以进行 任意次 操作,请你返回达到这个目标的 最小 总代价。
请你返回让 nums1 和 nums2 满足上述条件的 最小总代价 ,如果无法达成目标,返回 -1 。
示例 1:
输入:nums1 = [1,2,3,4,5], nums2 = [1,2,3,4,5]
输出:10
解释:
实现目标的其中一种方法为:

  • 交换下标为 0 和 3 的两个值,代价为 0 + 3 = 3 。现在 nums1 = [4,2,3,1,5] 。
  • 交换下标为 1 和 2 的两个值,代价为 1 + 2 = 3 。现在 nums1 = [4,3,2,1,5] 。
  • 交换下标为 0 和 4 的两个值,代价为 0 + 4 = 4 。现在 nums1 = [5,3,2,1,4] 。
    最后,对于每个下标 i ,都有 nums1[i] != nums2[i] 。总代价为 10 。
    还有别的交换值的方法,但是无法得到代价和小于 10 的方案。
    示例 2:
    输入:nums1 = [2,2,2,1,3], nums2 = [1,2,2,3,3]
    输出:10
    解释:
    实现目标的一种方法为:
  • 交换下标为 2 和 3 的两个值,代价为 2 + 3 = 5 。现在 nums1 = [2,2,1,2,3] 。
  • 交换下标为 1 和 4 的两个值,代价为 1 + 4 = 5 。现在 nums1 = [2,3,1,2,2] 。
    总代价为 10 ,是所有方案中的最小代价。
    示例 3:
    输入:nums1 = [1,2,2], nums2 = [1,2,2]
    输出:-1
    解释:
    不管怎么操作,都无法满足题目要求。
    所以返回 -1 。
    提示:
    n == nums1.length == nums2.length
    1 <= n <= 105
    1 <= nums1[i], nums2[i] <= n

分类讨论

能否不相等

cnt[x]记录x在nums1和nums2中出现的总次数。cnt[x]取最大值对应的x是x1(众数)。
如果cnt[x1] > n,则一定无法不相等。nums1[i]和nums2[i]只能有一个是x,而i的取值范围是[0,n)共n种可能,顶多存放n个x。
如果cnt[x1]==n ,nums1[i]或nums2[i]中的一个等于x,另外一个不为x。故:一定能不相等。
下面来证明:cnt[x1] < n,一定能不相等。证明一
x1是众数,说明其它数<=cnt[x1] 2个x1 < 2*n,所以至少3个数。任选另外两个数各删除一个。众数不变(x1没减少,其它数减少少或不变),n–,经过优先次数n一定会等于x1。

何种顺序交换

cnt[x] 记录nums1[i]==nums2[i]==x 的数量。
令x = x1时cnt[x]取最大值。令sum = ∑ x ≠ x 1 ( c n t [ x ] ) \sum_{x\neq x1}(cnt[x]) x=x1(cnt[x])
一,cnt[x1] <= sum
如果总数量是偶数:按证明一的方法两两交换。
如果总是是奇数:说明至少3个数,总有一个数不等于nums1[0]和nums2[0],用这个数和下标0换。
二,cnt[x1] <= sum
sum个x按上述方式处理。n1 = cnt[x1]- sum个x 和符合以下条件的最小下标换。
1,没交换过,交换过的nums1[i]或nums2[i]至少一个是x1。
2,nums1[i]和nums2[i]不等于x。

代码

核心代码

class Solution {
public:long long minimumTotalCost(vector<int>& nums1, vector<int>& nums2) {{unordered_map<int, int> mNumCount;for (const auto& n : nums1){mNumCount[n]++;}for (const auto& n : nums2){mNumCount[n]++;}for (const auto& [tmp, cnt] : mNumCount){if (cnt > nums1.size()){return -1;}}}unordered_map<int, int> mNumCount;long long ans = 0;for (int i = 0; i < nums1.size(); i++){if (nums1[i] == nums2[i]){mNumCount[nums1[i]]++;ans += i;}}int x1 = -1, ctn1 = 0,total=0;for (const auto& [num, cnt] : mNumCount){if (cnt > ctn1){x1 = num;ctn1 = cnt;}total += cnt;}int iNeedChange = ctn1 - (total - ctn1);if (iNeedChange <= 0){return ans;}for (int j = 0; j < nums1.size(); j++){if ((nums1[j] == nums2[j]) || (nums1[j] == x1) || (nums2[j] == x1)){continue;}ans += j;if (--iNeedChange <= 0){return ans;}}return -1;}int m_c;
};

优化

前面的判断可以省略.

class Solution {
public:long long minimumTotalCost(vector<int>& nums1, vector<int>& nums2) {		unordered_map<int, int> mNumCount;long long ans = 0;for (int i = 0; i < nums1.size(); i++){if (nums1[i] == nums2[i]){mNumCount[nums1[i]]++;ans += i;}}int x1 = -1, ctn1 = 0,total=0;for (const auto& [num, cnt] : mNumCount){if (cnt > ctn1){x1 = num;ctn1 = cnt;}total += cnt;}int iNeedChange = ctn1 - (total - ctn1);if (iNeedChange <= 0){return ans;}for (int j = 0; j < nums1.size(); j++){if ((nums1[j] == nums2[j]) || (nums1[j] == x1) || (nums2[j] == x1)){continue;}ans += j;if (--iNeedChange <= 0){return ans;}}return -1;}int m_c;
};

测试用例

template<class T,class T2>
void Assert(const T& t1, const T2& t2)
{
assert(t1 == t2);
}

template
void Assert(const vector& v1, const vector& v2)
{
if (v1.size() != v2.size())
{
assert(false);
return;
}
for (int i = 0; i < v1.size(); i++)
{
Assert(v1[i], v2[i]);
}

}

int main()
{
vector nums1, nums2;
{
Solution sln;
nums1 = { 1, 2, 3, 4, 5 }, nums2 = { 1, 2, 3, 4, 5 };
auto res = sln.minimumTotalCost(nums1, nums2);
Assert(10, res);
}
{
Solution sln;
nums1 = { 2,2,2,1,3 }, nums2 = { 1,2,2,3,3 };
auto res = sln.minimumTotalCost(nums1, nums2);
Assert(10, res);
}
{
Solution sln;
nums1 = { 1,2,2 }, nums2 = { 2,2,1 };
auto res = sln.minimumTotalCost(nums1, nums2);
Assert(-1, res);
}
}

扩展阅读

视频课程

有效学习:明确的目标 及时的反馈 拉伸区(难度合适),可以先学简单的课程,请移步CSDN学院,听白银讲师(也就是鄙人)的讲解。
https://edu.csdn.net/course/detail/38771

如何你想快速形成战斗了,为老板分忧,请学习C#入职培训、C++入职培训等课程
https://edu.csdn.net/lecturer/6176

相关

下载

想高屋建瓴的学习算法,请下载《喜缺全书算法册》doc版
https://download.csdn.net/download/he_zhidan/88348653

我想对大家说的话
闻缺陷则喜是一个美好的愿望,早发现问题,早修改问题,给老板节约钱。
子墨子言之:事无终始,无务多业。也就是我们常说的专业的人做专业的事。
如果程序是一条龙,那算法就是他的是睛

测试环境

操作系统:win7 开发环境: VS2019 C++17
或者 操作系统:win10 开发环境: VS2022 C++17
如无特殊说明,本算法用**C++**实现。

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

只需一周,拿下自动化测试(全)

&#x1f345; 视频学习&#xff1a;文末有免费的配套视频可观看 &#x1f345; 点击文末小卡片 &#xff0c;免费获取软件测试全套资料&#xff0c;资料在手&#xff0c;涨薪更快 一、自动化测试 在软件测试中&#xff0c;自动化测试指的是使用独立于待测软件的其他软件来自动…

ServletConfig和ServletContext

ServletConfig接口 在Servlet运行期间&#xff0c;需要一些配置信息&#xff0c;这些信息都可以在WebServlet注解的属性中配置。当Tomcat初始化一个Servlet时&#xff0c;会将该Servlet的配置信息封装到一个ServletConfig对象中&#xff0c;通过调用init(ServletConfig config…

[Vue warn]: Invalid vnode type when creating vnode: false

如题&#xff0c;意思是创建vnode时&#xff0c;vnode类型无效:false。 根据右边的索引点进去&#xff0c;发现定位的是组件loading。搜索loading发现声明了变量loading&#xff0c;更改后问题消失。

CVE-2022-33891 Apache Spark shell 命令注入漏洞分析

漏洞简介 Apache Spark 是专为大规模数据处理而设计的快速通用的计算引擎。Spark是UC Berkeley AMP lab (加州大学伯克利分校的AMP实验室)所开源的类Hadoop MapReduce的通用并行框架 Spark&#xff0c;拥有Hadoop MapReduce所具有的优点&#xff1b;但不同于MapReduce的…

awk指定输入分隔符,输出分隔符

awk -v FS -v OFS, {print $1,$2} a.txt FS &#xff0c;指定输入分割符为 OFS,&#xff0c;指定输出分割符为, 效果

【C++】隐藏的this指针

文章目录 1.this指针的引出2.this指针的特性 1.this指针的引出 我们通过日期类来学习this指针&#xff0c;首先我们先定义一个日期类。 class Date { public:void Display(){cout << _year << "-" << _month << "-" << _d…

ubuntu2004自动更新内核导致nvidia驱动无法正常启动的问题

症状 开机后&#xff0c;nvidia-smi无法正常显示显卡状态&#xff0c;另外无法连接多个显示屏 解决 参考这个文章&#xff1a; ls /usr/src可以看到已安装的nvidia驱动版本是nvidia-535.54.03 然后运行下面的指令&#xff1a; sudo apt-get install dkmssudo dkms instal…

网络——套接字编程TCP

目录 服务端 创建套接字&#xff08;socket&#xff09; 服务端绑定&#xff08;bind&#xff09; 服务端监听&#xff08;listen&#xff09; 服务器接收&#xff08;accept&#xff09; 服务端处理&#xff08;read & write&#xff09; 客户端 创建套接字&#…

配置DNS后,SSH登录变慢

问题描述 最近使用ssh时出现登录非常缓慢的状态&#xff0c;登录一般需要花费20秒以上才能正常登陆&#xff0c; Connecting to *****:22... Connection established. To escape to local shell, press CtrlAlt].等待十秒钟后&#xff0c;提示登录成功 Last login: Mon Jun …

目标检测的指标评估

目标检测模型的评价指标主要用于衡量模型的性能&#xff0c;特别是它在定位和识别目标方面的准确性。以下是一些常见的评价指标&#xff1a; 1. 精确度 (Precision): 表示检测到的目标中&#xff0c;正确检测到的目标所占的比例。精确度高意味着模型产生的误报&#xff08;错误…

【C++】基础:STL容器库

&#x1f60f;★,:.☆(&#xffe3;▽&#xffe3;)/$:.★ &#x1f60f; 这篇文章主要介绍STL容器库。 学其所用&#xff0c;用其所学。——梁启超 欢迎来到我的博客&#xff0c;一起学习&#xff0c;共同进步。 喜欢的朋友可以关注一下&#xff0c;下次更新不迷路&#x1f95…

官宣子品牌艾荷,坚定数字化赋能,鸿雁2024新春发布会助推40多年央企品牌焕新升级

3月25日&#xff0c;一场以“春江水暖雁先飞”为主题的2024鸿雁电器智能物联战略及新品发布会在杭州盛大召开。鸿雁电器总裁王米成、副总裁吴明、副总裁夏晓衍、市场部总经理梁彩雷、五金水暖渠道部总经理刘亮、灯饰与智能家居渠道部总经理王育炳等公司领导出席&#xff0c;以及…