C++算法:让数组不相等的最小总代价

简介: C++算法:让数组不相等的最小总代价

题目

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

术语

如果nums1[i] 和nums2[i]相等,是内部;否则是外部。显然,内部的数需要全部交换。

假定不同的数的数量是偶数

分析那些情况可以只内部交换,不和外包交换。下面只列出nums1和nums2中不同的元素。

nums1

nums2

交换过程

能否能内部交换

[1,2]

[1,2]

[2,1]

[1,2,2,2]

[1,2,2,2]

[2,1,2,2]

不能

[1,2,3,4]

[1,2,3,4]

[2,1,3,4][2,1,4,3]

[1,1,2,3]

[1,1,2,3]

[2,1,1,3][2,3,1,1]

[1,1,2,2]

[1,1,2,2]

[2,1,1,2][2,2,1,1]

猜想:除众数外,其它数都可以匹配上

如果众数大于总数的一半,则非众数全部和众数匹配,非众数全部匹配,部分众数无法匹配,假定其为iNeedSwapOut则其值为:众数-非众数。

如果众数小于等于总数的一半(意味着至少2种数)。假定最多的数数量为n1,次多的为n2,如果有三种数,第三多的为n3。

最多的数和次多的数匹配,也就是n1和n2的各减少1。用N1代表新的n1,N2代码新的n2.结果有三种:

转换前

转换后

情况一

[1,2]

[]

情况二

[1,2,3,4]

[3,4]

[1,1,2,2,3,3]

[3,3,1,2]

[1,1,1,2,2,2,3,3,3,4]

[3,3,3,1,1,2,2,4]

情况三

[1,1,2,3]

[1,3]

  • N1和N2都为0,匹配结束。由于和是偶数,每次匹配和减少2,最终一定为成为0。
  • N1为n1-1,由于2*n1 <= sum ,所以 2*(n1-1) <= sum-2。 匹配后,仍然符合:众数小于等于总数的一半。
  • N1为n3,前提条件 n1和n2和n3相等,且都大于0。其和至少为n3*3-2。假的2*n3 > n3*3-2,则0 >n3-2,即n < 2。

n1为1时,此时有偶数个数量为1的种类,任意匹配都符合题意。

结论

如果众数小于等于总数的一半,则所有的数都可以内部匹配。如果众数大于总数的一半,则部分众数需要在外部匹配。

如果不同数的数量是奇数

由于是奇数,众数的数量不会等于总数的一半。

如果众数小于总数的一半

用C++的整数表示就是:modeCount <=iNotSameCount/2 ,推论:至少有3个数。n1,n2,n3各取一个数,余下的数,符合偶数且众数小于等于总数的一半。这三个数,至少有一个数,和当前的nums1[0]、nums2[i]不同,假定为x,另外两个数分别为y1,y2。分三步:一,先交换除x,y1,y2外的数。二,再交换y1,y2。三,交换nums1[i]和x。由于x和y1 y2 原始nums1[i]和nums2[i]都不同,所以完成第二步后nums1[0]和nums2[0]一定和x不同。

如果众数大于总数的一半

多出的部分外部匹配。其它内部匹配。

结论

如果众数小于等于总数的一半(整除2),则全部内交换。否则需要外部交换,需要的交换次数可以用统一的公式。

int iNeedSwapOut = max(0,modeCount - (iNotSameCount - modeCount));

代码结构

代码分三部分。

  • 计算内部的数量,需要交换的数的数量。内部交换的总代价。
  • 计算需要交换的数的众数(数量最多的数)。
  • 计算外部交换的总代价。


  • 代码
class Solution {
public:
long long minimumTotalCost(vector<int>& nums1, vector<int>& nums2) {
m_c = nums1.size();
int iNotSameCount = 0;
long long llRet = 0;
std::unordered_map<int, int> mNotSameNum;
for (int i = 0; i < m_c; i++)
{
if (nums1[i] != nums2[i])
{
continue;
}
llRet += i;
mNotSameNum[nums1[i]]++;
iNotSameCount++;
}
if (mNotSameNum.empty())
{
return 0;
}
//如果众数不超过一半(意味着至少2个数),如果是偶数,内部就可以交换。
//如果是奇数,至少有一个和nums2[0]不同。
//求众数和众数出现的数量
int mode = -1;
int modeCount = 0;
for (const auto& [v, n] : mNotSameNum)
{
if (n > modeCount)
{
mode = v;
modeCount = n;
}
}
//除众数外,其它数都可以内部交换,非众数都可以和众数交换
int iNeedSwapOut = max(0,modeCount - (iNotSameCount - modeCount));
for (int i = 0; (i < m_c)&& iNeedSwapOut; i++)
{//必须从小到循环,这样才能代价最小
if (nums1[i] == nums2[i])
{//已经是内部
continue;
}
if ((mode == nums1[i]) || (mode == nums2[i]))
{//不能和众数交换,或者i或交换的元素相等
continue;
}
iNeedSwapOut--;
llRet += i;
}
return iNeedSwapOut ? -1 : llRet ;
}
int m_c;
};

说明

源码和少量测试用例下载:

https://download.csdn.net/download/he_zhidan/88368465


其它

视频课程

如果你觉得复杂,想从简单的算法开始,可以学习我的视频课程。

https://edu.csdn.net/course/detail/38771

我的其它课程

https://edu.csdn.net/lecturer/6176

测试环境

win7 VS2019 C++17 或Win10 VS2022 Ck++17

相关下载

算法精讲《闻缺陷则喜算法册》doc版

https://download.csdn.net/download/he_zhidan/88348653

相关文章
|
6月前
|
存储 监控 算法
基于 C++ 哈希表算法实现局域网监控电脑屏幕的数据加速机制研究
企业网络安全与办公管理需求日益复杂的学术语境下,局域网监控电脑屏幕作为保障信息安全、规范员工操作的重要手段,已然成为网络安全领域的关键研究对象。其作用类似网络空间中的 “电子眼”,实时捕获每台电脑屏幕上的操作动态。然而,面对海量监控数据,实现高效数据存储与快速检索,已成为提升监控系统性能的核心挑战。本文聚焦于 C++ 语言中的哈希表算法,深入探究其如何成为局域网监控电脑屏幕数据处理的 “加速引擎”,并通过详尽的代码示例,展现其强大功能与应用价值。
158 2
|
7月前
|
存储 算法 C++
Windows共享文件:探秘C++实现的B树索引算法奇境
在数字化时代,Windows共享文件的高效管理至关重要。B树算法以其自平衡多路搜索特性,在文件索引与存储优化中表现出色。本文探讨B树在Windows共享文件中的应用,通过C++实现具体代码,展示其构建文件索引、优化数据存储的能力,提升文件检索效率。B树通过减少磁盘I/O操作,确保查询高效,为企业和个人提供流畅的文件共享体验。
|
4月前
|
存储 监控 算法
基于跳表数据结构的企业局域网监控异常连接实时检测 C++ 算法研究
跳表(Skip List)是一种基于概率的数据结构,适用于企业局域网监控中海量连接记录的高效处理。其通过多层索引机制实现快速查找、插入和删除操作,时间复杂度为 $O(\log n)$,优于链表和平衡树。跳表在异常连接识别、黑名单管理和历史记录溯源等场景中表现出色,具备实现简单、支持范围查询等优势,是企业网络监控中动态数据管理的理想选择。
148 0
|
6月前
|
监控 算法 数据处理
基于 C++ 的 KD 树算法在监控局域网屏幕中的理论剖析与工程实践研究
本文探讨了KD树在局域网屏幕监控中的应用,通过C++实现其构建与查询功能,显著提升多维数据处理效率。KD树作为一种二叉空间划分结构,适用于屏幕图像特征匹配、异常画面检测及数据压缩传输优化等场景。相比传统方法,基于KD树的方案检索效率提升2-3个数量级,但高维数据退化和动态更新等问题仍需进一步研究。未来可通过融合其他数据结构、引入深度学习及开发增量式更新算法等方式优化性能。
181 17
|
5月前
|
存储 机器学习/深度学习 算法
基于 C++ 的局域网访问控制列表(ACL)实现及局域网限制上网软件算法研究
本文探讨局域网限制上网软件中访问控制列表(ACL)的应用,分析其通过规则匹配管理网络资源访问的核心机制。基于C++实现ACL算法原型,展示其灵活性与安全性。文中强调ACL在企业与教育场景下的重要作用,并提出性能优化及结合机器学习等未来研究方向。
151 4
|
5月前
|
机器学习/深度学习 存储 算法
基于 C++ 布隆过滤器算法的局域网上网行为控制:URL 访问过滤的高效实现研究
本文探讨了一种基于布隆过滤器的局域网上网行为控制方法,旨在解决传统黑白名单机制在处理海量URL数据时存储与查询效率低的问题。通过C++实现URL访问过滤功能,实验表明该方法可将内存占用降至传统方案的八分之一,查询速度提升约40%,假阳性率可控。研究为优化企业网络管理提供了新思路,并提出结合机器学习、改进哈希函数及分布式协同等未来优化方向。
160 0
|
7月前
|
存储 监控 算法
基于 C++ 哈希表算法的局域网如何监控电脑技术解析
当代数字化办公与生活环境中,局域网的广泛应用极大地提升了信息交互的效率与便捷性。然而,出于网络安全管理、资源合理分配以及合规性要求等多方面的考量,对局域网内计算机进行有效监控成为一项至关重要的任务。实现局域网内计算机监控,涉及多种数据结构与算法的运用。本文聚焦于 C++ 编程语言中的哈希表算法,深入探讨其在局域网计算机监控场景中的应用,并通过详尽的代码示例进行阐释。
161 4
|
8月前
|
存储 算法 安全
企业员工数据泄露防范策略:基于 C++ 语言的布隆过滤器算法剖析[如何防止员工泄密]
企业运营过程中,防范员工泄密是信息安全领域的核心议题。员工泄密可能致使企业核心数据、商业机密等关键资产的流失,进而给企业造成严重损失。为应对这一挑战,借助恰当的数据结构与算法成为强化信息防护的有效路径。本文专注于 C++ 语言中的布隆过滤器算法,深入探究其在防范员工泄密场景中的应用。
187 8
|
1月前
|
机器学习/深度学习 算法 机器人
【水下图像增强融合算法】基于融合的水下图像与视频增强研究(Matlab代码实现)
【水下图像增强融合算法】基于融合的水下图像与视频增强研究(Matlab代码实现)
196 0
|
1月前
|
数据采集 分布式计算 并行计算
mRMR算法实现特征选择-MATLAB
mRMR算法实现特征选择-MATLAB
144 2

热门文章

最新文章