1300. Sum of Mutated Array Closest to Target(Leetcode每日一題-2020.06.14)

Problem

Given an integer array arr and a target value target, return the integer value such that when we change all the integers larger than value in the given array to be equal to value, the sum of the array gets as close as possible (in absolute difference) to target.

In case of a tie, return the minimum such integer.

Notice that the answer is not neccesarilly a number from arr.

Example1

Input: arr = [4,9,3], target = 10
Output: 3
Explanation: When using 3 arr converts to [3, 3, 3] which sums 9 and that’s the optimal answer.

Example2

Input: arr = [2,3,5], target = 10
Output: 5

Example3

Input: arr = [60864,25176,27249,21296,20204], target = 56803
Output: 11361

Solution

三分查找

class Solution {
public:


    int findBestValue(vector<int>& arr, int target) {

        int max_ele = *std::max_element(arr.begin(),arr.end());

        return ternarySearch(arr,0,max_ele,target);


    }

    int diffSum(vector<int>& arr,int val,int target)
    {
        int sum = 0;
        for(auto num:arr)
        {
            if(num > val)
                sum += val;
            else   
                sum += num;

        }

        return abs(target-sum);
    }

    int ternarySearch(vector<int>& arr,int l, int r,int target) {
        while (l < r)
        {
            
            int m1 = l + (r - l) / 3;
            int m2 = r - (r - l) / 3;

           
            int diffSum1 = diffSum(arr,m1,target);
            int diffSum2 = diffSum(arr,m2,target);
            
            if(l + 2 == r) //特判,如果只有三個數字了,找到最小的那一個
            {
                int diffSum3 =  diffSum(arr,l+1,target);
                if(diffSum1<=diffSum2 && diffSum1<=diffSum3)
                    return l;
                else if(diffSum3< diffSum1 && diffSum3 <= diffSum2)
                    return l+1;
                else if(diffSum2 < diffSum1 && diffSum2 < diffSum3)
                    return r;
            }
            if (diffSum(arr,m1,target) >= diffSum(arr,m2,target)) //說明最小值在靠近m2的那一側,即區間[m1,r]
            {
                l = m1;
            } 
            else //說明最小值在靠近m1的那一側,即區間[l,m2]
            {
                r = m2;
            }

        }
        return l;
    }
};

Ref

https://www.jianshu.com/p/60d8c3e576d7

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章