148 lines
4.7 KiB
C++
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// Source : https://leetcode.com/problems/equal-sum-arrays-with-minimum-number-of-operations/
// Author : Hao Chen
// Date : 2021-03-24
/*****************************************************************************************************
*
* You are given two arrays of integers nums1 and nums2, possibly of different lengths. The values in
* the arrays are between 1 and 6, inclusive.
*
* In one operation, you can change any integer's value in any of the arrays to any value between 1
* and 6, inclusive.
*
* Return the minimum number of operations required to make the sum of values in nums1 equal to the
* sum of values in nums2. Return -1 if it is not possible to make the sum of the two arrays
* equal.
*
* Example 1:
*
* Input: nums1 = [1,2,3,4,5,6], nums2 = [1,1,2,2,2,2]
* Output: 3
* Explanation: You can make the sums of nums1 and nums2 equal with 3 operations. All indices are
* 0-indexed.
* - Change nums2[0] to 6. nums1 = [1,2,3,4,5,6], nums2 = [6,1,2,2,2,2].
* - Change nums1[5] to 1. nums1 = [1,2,3,4,5,1], nums2 = [6,1,2,2,2,2].
* - Change nums1[2] to 2. nums1 = [1,2,2,4,5,1], nums2 = [6,1,2,2,2,2].
*
* Example 2:
*
* Input: nums1 = [1,1,1,1,1,1,1], nums2 = [6]
* Output: -1
* Explanation: There is no way to decrease the sum of nums1 or to increase the sum of nums2 to make
* them equal.
*
* Example 3:
*
* Input: nums1 = [6,6], nums2 = [1]
* Output: 3
* Explanation: You can make the sums of nums1 and nums2 equal with 3 operations. All indices are
* 0-indexed.
* - Change nums1[0] to 2. nums1 = [2,6], nums2 = [1].
* - Change nums1[1] to 2. nums1 = [2,2], nums2 = [1].
* - Change nums2[0] to 4. nums1 = [2,2], nums2 = [4].
*
* Constraints:
*
* 1 <= nums1.length, nums2.length <= 10^5
* 1 <= nums1[i], nums2[i] <= 6
******************************************************************************************************/
class Solution {
private:
void print(vector<int>& n) {
cout <<"[";
for(int i=0; i< n.size() - 1; i++) {
cout << n[i] << ",";
}
cout << n[n.size()-1] << "]" <<endl;
}
private:
int minOpsBySort(int gaps, vector<int>& small, vector<int>& big) {
sort(small.begin(), small.end());
sort(big.begin(), big.end());
int op = 0;
int left = 0, right = big.size() -1;
while (gaps >0) {
int small_gaps = left < small.size() ? 6 - small[left] : 0;
int big_gaps = right >= 0 ? big[right] - 1 : 0;
if (small_gaps > big_gaps) {
gaps -= small_gaps;
left++;
}else{
gaps -= big_gaps;
right--;
}
op++;
}
return op;
}
int minOpsByCnt1(int gaps, vector<int>& small, vector<int>& big) {
int small_cnt[6] = {0} , big_cnt[6] = {0};
for (auto& n : small) small_cnt[n-1]++;
for (auto& n : big) big_cnt[n-1]++;
int op = 0;
int left = 0, right = 5;
while( gaps > 0 ) {
while (left < 6 && small_cnt[left] == 0 ) left++;
while ( right >=0 && big_cnt[right] == 0 ) right--;
int small_gaps = left < 6 ? 6 - (left + 1) : 0;
int big_gaps = right >= 0 ? right : 0;
if (small_gaps > big_gaps) {
gaps -= small_gaps;
small_cnt[left]--;
}else{
gaps -= big_gaps;
big_cnt[right]--;
}
op++;
}
return op;
}
int minOpsByCnt2(int gaps, vector<int>& small, vector<int>& big) {
int cnt[6] = {0};
for (auto& n : small) cnt[6-n]++;
for (auto& n : big) cnt[n-1]++;
int ops = 0;
for (int i=5 ; i >= 0 && gaps > 0; i--) {
if (cnt[i] == 0) continue;
if (cnt[i] * i > gaps) {
ops += (gaps / i + (gaps % i ? 1:0) ) ;
break;
}
gaps -= cnt[i] * i;
ops += cnt[i];
}
return ops;
}
public:
int minOperations(vector<int>& nums1, vector<int>& nums2) {
int len1 = nums1.size(), len2 = nums2.size();
if ( len1 > 6*len2 || len2 > 6*len1) return -1;
int sum1 = 0 , sum2 = 0;
for (auto& n : nums1) sum1 += n;
for (auto& n : nums2) sum2 += n;
if (sum1 > sum2) {
swap(sum1, sum2);
swap(nums1, nums2);
}
int gaps = sum2 - sum1;
if (gaps == 0) return 0;
return minOpsByCnt2(gaps, nums1, nums2); //104ms
return minOpsByCnt1(gaps, nums1, nums2); //108ms
return minOpsBySort(gaps, nums1, nums2); //140ms
}
};