RainX_69

Minimize squared sum in K ops, Binary search

Dec 26th, 2022
95
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 4.48 KB | Source Code | 0 0
  1. /*
  2. You are given two positive 0-indexed integer arrays nums1 and nums2, both of length n.
  3.  
  4. The sum of squared difference of arrays nums1 and nums2 is defined as the sum of (nums1[i] - nums2[i])2 for each 0 <= i < n.
  5.  
  6. You are also given two positive integers k1 and k2. You can modify any of the elements of nums1 by +1 or -1 at most k1 times. Similarly, you can modify any of the elements of nums2 by +1 or -1 at most k2 times.
  7.  
  8. Return the minimum sum of squared difference after modifying array nums1 at most k1 times and modifying array nums2 at most k2 times.
  9.  
  10. Note: You are allowed to modify the array elements to become negative integers.
  11.  
  12.  
  13.  
  14. Example 1:
  15.  
  16. Input: nums1 = [1,2,3,4], nums2 = [2,10,20,19], k1 = 0, k2 = 0
  17. Output: 579
  18. Explanation: The elements in nums1 and nums2 cannot be modified because k1 = 0 and k2 = 0.
  19. The sum of square difference will be: (1 - 2)2 + (2 - 10)2 + (3 - 20)2 + (4 - 19)2 = 579.
  20. Example 2:
  21.  
  22. Input: nums1 = [1,4,10,12], nums2 = [5,8,6,9], k1 = 1, k2 = 1
  23. Output: 43
  24. Explanation: One way to obtain the minimum sum of square difference is:
  25. - Increase nums1[0] once.
  26. - Increase nums2[2] once.
  27. The minimum of the sum of square difference will be:
  28. (2 - 5)2 + (4 - 8)2 + (10 - 7)2 + (12 - 9)2 = 43.
  29. Note that, there are other ways to obtain the minimum of the sum of square difference, but there is no way to obtain a sum smaller than 43.
  30.  
  31.  
  32. Constraints:
  33.  
  34. n == nums1.length == nums2.length
  35. 1 <= n <= 105
  36. 0 <= nums1[i], nums2[i] <= 10^5
  37. 0 <= k1, k2 <= 10^9
  38.  
  39. https://leetcode.com/problems/minimum-sum-of-squared-difference/
  40. */
  41.  
  42. class Solution {
  43. public:
  44.     bool isOK(vector<long long> &diff, int K, long long guessedLevel){
  45.         long long requiredOps=0;
  46.         for(auto level: diff){
  47.             if(level<=guessedLevel){ // already less or equal to guessedLevel
  48.                 continue;
  49.             }
  50.             requiredOps+=(level-guessedLevel);
  51.         }
  52.         return requiredOps<=K;  // you can bring every diff to level guessedLevel in less or equal to k1+k2 operations
  53.     }
  54.    
  55.     long long minSumSquareDiff(vector<int>& nums1, vector<int>& nums2, int k1, int k2) {
  56.         int n=nums1.size();
  57.         vector<long long> diff(n);
  58.         for(int i=0;i<n;i++){
  59.             diff[i]=abs(nums1[i]-nums2[i]);
  60.         }
  61.        
  62.         // Finding the level using binary search which is possible in k1+k2 ops and lead to minimum level
  63.         long long low=0;
  64.         long long high=INT_MAX;
  65.         int totalOps=k1+k2;
  66.         int minLevel=-1;
  67.         while(low<=high){
  68.             int mid=(low+high)/2;
  69.             if(isOK(diff,totalOps,mid)==true){  // operations required to reach mid level is less than totalOps
  70.                 minLevel=mid;
  71.                 high=mid-1;
  72.             }
  73.             else{
  74.                 low=mid+1;
  75.             }
  76.         }
  77.        
  78.         // bring every diff to that level, and use operations for it
  79.         for(int i=0;i<n;i++){
  80.             if(diff[i]<=minLevel){  // already less than minLevel
  81.                 continue;
  82.             }
  83.             totalOps-=(diff[i]-minLevel);
  84.             diff[i]=minLevel;
  85.         }
  86.        
  87.        
  88.         /*
  89.            Note that it always better to reduce two largest differences by 1,
  90.            then one of them by 2: (n - 2) * (n - 2) + n * n > (n - 1) * (n - 1) + (n - 1) * (n - 1).
  91.         */
  92.         if(totalOps>0){
  93.             sort(diff.begin(),diff.end(),greater<int>());
  94.             for(int i=0;i<n && totalOps>0;i++){
  95.                 if(diff[i]>0){
  96.                     diff[i]--;
  97.                     totalOps--;
  98.                 }
  99.             }
  100.         }
  101.        
  102.         long long res=0;
  103.         for(auto level: diff){
  104.             res+=pow(level,2);
  105.         }
  106.         return res;
  107.        
  108.     }
  109. };
  110.  
  111. /*
  112. THOUGHT PROCESS-
  113.  
  114. K1 K2 are not separate, you can consider them the same as K=K1+K2. Now, you want to know, if there exist any level which every difference vector diff[i] be less or equal to. This should be done using binary search, using binary search you find a level called minLevel, such that every diff[i] can be bought equal to or less than this minLevel in the given amount of operations.
  115.  
  116. Now, after you get such minLevel, its time you bring every element to that level using operations, if your diff[i] is already at that level or below it, leave it. You might have some operations left. Use them to bring big diff[i] elements one by one. This is done by sorting as you can see in the code
  117.  
  118. Then you just find the res and return
  119. */
Advertisement
Add Comment
Please, Sign In to add comment