题目:2561. 重排水果
思路:哈希表+贪心,时间复杂度0(nlogn)。
哈希表来记录两个数组中元素的差异情况,如果相差的值不是偶数,那无法相等,返回-1即可。
差值都为偶数,那可以开始交换,用数组a、b来记录两个篮子需要交换的水果。理论上是选这两个篮子组合里最小的一半即可,但没有限制水果的交换次数,此时可能会存在最小的一个水果呢,用于做中间商,交换两个数组中的元素,也就是进行两次。细节看注释。
C++版本:
class Solution {
public:
long long minCost(vector<int>& basket1, vector<int>& basket2) {
// 哈希表来记录两个数组中元素的差异情况
unordered_map<int,int> mp;
int n=basket1.size();
for(int i=0;i<n;i++){
mp[basket1[i]]++;
mp[basket2[i]]--;
}
// 数组a、b来记录两个篮子需要交换的水果
vector<int> a,b;
// 数组a、b里最小的一个水果
int mn=INT_MAX;
for(auto x:mp){
// 相差的值不是偶数,那无法相等
if(x.second%2!=0) return -1;
mn=min(mn,x.first);
if(x.second>0){
for(int i=0;i<x.second/2;i++){
a.push_back(x.first);
}
}else{
for(int i=0;i<-1*x.second/2;i++){
b.push_back(x.first);
}
}
}
//升序
sort(a.begin(),a.end());
//降序
sort(b.begin(),b.end(),greater());
long long ans=0;
for(int i=0;i<a.size();i++){
// 可能会存在最小的一个水果,用于做中间商,交换两个数组中的元素,也就是进行两次
ans+=min({a[i],b[i],mn*2});
}
return ans;
}
};
JAVA版本:
class Solution {
public long minCost(int[] basket1, int[] basket2) {
Map<Integer,Integer> mp=new HashMap<>();
int n=basket1.length;
for(int i=0;i<n;i++){
mp.merge(basket1[i],1,Integer::sum);
mp.merge(basket2[i],-1,Integer::sum);
}
int mn=Integer.MAX_VALUE;
List<Integer> a=new ArrayList<>();
List<Integer> b=new ArrayList<>();
for(Map.Entry<Integer,Integer> e :mp.entrySet()){
int x=e.getKey(),y=e.getValue();
if(y%2!=0) return -1;
mn=Math.min(mn,x);
if(y>0){
for(int i=0;i<y/2;i++){
a.add(x);
}
}else{
for(int i=0;i<-1*y/2;i++){
b.add(x);
}
}
}
Collections.sort(a);
b.sort(Collections.reverseOrder());
long ans=0;
for(int i=0;i<a.size();i++){
ans+=Math.min(mn*2,Math.min(a.get(i),b.get(i)));
}
return ans;
}
}
GO版本:
func minCost(basket1 []int, basket2 []int) int64 {
mp:=map[int]int{}
for i:=range basket1 {
mp[basket1[i]]++
mp[basket2[i]]--
}
a,b:=[]int{},[]int{}
mn:=math.MaxInt
for x,y:=range mp {
if y%2!=0 {
return -1
}
mn=min(mn,x)
if y>0 {
for i:=0;i<y/2;i++ {
a=append(a,x)
}
}else{
for i:=0;i< -1 * y/2;i++ {
b=append(b,x)
}
}
}
var ans int64 = 0
slices.Sort(a)
slices.SortFunc(b,func(i,j int) int {return j-i })
for i:=range a {
ans+=int64(min(a[i],b[i],mn*2))
}
return ans
}