# 2499. Minimum Total Cost to Make Arrays Unequal
###### tags: `Leetcode` `Hard` `Greedy`
Link: https://leetcode.com/problems/minimum-total-cost-to-make-arrays-unequal/description/
## 思路
思路参考[这里](https://github.com/wisdompeak/LeetCode/tree/master/Greedy/2499.minimum-total-cost-to-make-arrays-unequal)
首先我们考虑答案至少是多少?如果所有的same pairs能够在“内部调整”后满足要求,即交换只涉及same pairs所在的位置,那么答案就是这些same pairs的下标之和。显然,这个答案是最小的,记做ret。
那么什么情况下我们能够保证所有的same pairs在“内部调整”后就能满足要求呢?只要其中的majority element不超过same pairs的总数的一半即可。举个例子(2,2),(2,2),(2,2),(1,1),(3,3),(4,4),我们只要把2和非2元素交换,就可以满足同一个pair里的两个元素不同。但是如果有过半数的majority element,例如(2,2),(2,2),(2,2),(2,2),(1,1),(3,3),那么我们就无法找到足够多的非2元素来拆散(2,2). 还有一个问题是如果出现(2,2),(3,3),(5,5)的情况,势必有一个element要被交换两次,为什么我们还是可以用ret当答案,因为只要让index0的数字被交换两次就可以了
对于上述的第一种情况,输出ret即可。对于第二种情况,我们就需要借助于其他pair的帮助。在这个例子中,“内部调整”后我们还有两对(2,2)没有被拆散,这就需要我们找其他distinc pairs来与之交换。显然,我们会按下标从小到大去尝试。例如我们考察(a,b)的时候,思考它是否能帮助拆散(2,2),需要满足的条件有三个:
a!=b,否则这是一个same pair,已经在“内部调整”时用过了。
a!=2且b!=2,否则交换之后仍然会有一个(2,2)。
满足上述两个条件,那么我们就再做一次(a,b)与(2,2)的交换即可。以此类推不断寻找下一个合适的distinct pair,直至将多余的(2,2)消耗掉。
## Code
```java=
class Solution {
public long minimumTotalCost(int[] nums1, int[] nums2) {
long ans = 0;
int n = nums1.length;
Map<Integer, Integer> map = new HashMap<>();
int maxFreq = 0, maxFreqNum = -1, badPos = 0;
for(int i=0; i<n; i++){
if(nums1[i]==nums2[i]){
map.put(nums1[i], map.getOrDefault(nums1[i], 0)+1);
if(map.get(nums1[i])>maxFreq){
maxFreq = map.get(nums1[i]);
maxFreqNum = nums1[i];
}
badPos++;
ans += i;
}
}
for(int i=0; i<n; i++){
if(maxFreq>badPos/2 && nums1[i]!=nums2[i] && nums1[i]!=maxFreqNum && nums2[i]!=maxFreqNum){
badPos++;
ans += i;
}
}
if(maxFreq>badPos/2) return -1;
return ans;
}
}
```