日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

LeetCode 1300. 转变数组后最接近目标值的数组和(二分查找)

發(fā)布時間:2024/7/5 编程问答 25 豆豆
生活随笔 收集整理的這篇文章主要介紹了 LeetCode 1300. 转变数组后最接近目标值的数组和(二分查找) 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

1. 題目

給你一個整數(shù)數(shù)組 arr 和一個目標(biāo)值 target ,請你返回一個整數(shù) value ,
使得將數(shù)組中所有大于 value 的值變成 value 后,數(shù)組的和 最接近 target (最接近表示兩者之差的絕對值最小)。

如果有多種使得和最接近 target 的方案,請你返回這些整數(shù)中的最小值

請注意,答案不一定是 arr 中的數(shù)字。

示例 1: 輸入:arr = [4,9,3], target = 10 輸出:3 解釋:當(dāng)選擇 value 為 3 時,數(shù)組會變成 [3, 3, 3],和為 9 , 這是最接近 target 的方案。示例 2: 輸入:arr = [2,3,5], target = 10 輸出:5示例 3: 輸入:arr = [60864,25176,27249,21296,20204], target = 56803 輸出:11361提示: 1 <= arr.length <= 10^4 1 <= arr[i], target <= 10^5

來源:力扣(LeetCode)
鏈接:https://leetcode-cn.com/problems/sum-of-mutated-array-closest-to-target
著作權(quán)歸領(lǐng)扣網(wǎng)絡(luò)所有。商業(yè)轉(zhuǎn)載請聯(lián)系官方授權(quán),非商業(yè)轉(zhuǎn)載請注明出處。

2. 解題

  • 先將數(shù)組排序,求出前綴和
  • 要找的這個數(shù)ans上下限 [0, arr_max]
  • 如果這個數(shù)ans比0還小,數(shù)組所有的數(shù)將變成ans,target > 0,不會更接近
  • 如果這個數(shù)ans比數(shù)組最大的還大,數(shù)組所有的數(shù)不變,跟target的差,也不變,但題目要求最小的ans,所以ans的范圍是 [0, arr_max]
  • 現(xiàn)在需要證明,數(shù)組的和與target的單調(diào)性:
    假設(shè)選取的數(shù)為 v2, a[i-1] <= v2 < a[i]
    此時,a[0]+a[1]+...+a[i?1]+v2+...+v2(n?i個)?target?式1a[0]+a[1]+...+a[i-1]+ v2+...+v2 (n-i個)-target-式1a[0]+a[1]+...+a[i?1]+v2+...+v2(n?i)?target?1
    再次選擇數(shù) v1,a[i-1] <= v1 < v2
    此時,a[0]+a[1]+...+a[i?1]+v1+...+v1(n?i個)?target?式2a[0]+a[1]+...+a[i-1]+ v1+...+v1 (n-i個)-target - 式2a[0]+a[1]+...+a[i?1]+v1+...+v1(n?i)?target?2
    上下做差:式1-式2 = (v2?v1)?(n?i)>=0(v2-v1)*(n-i) >= 0(v2?v1)?(n?i)>=0
    選擇數(shù) v1,v1 < a[i-1] < v2
    此時,a[0]+a[1]+...+a[i?2]+v1+...+v1(n?i+1個)?target?式3a[0]+a[1]+...+a[i-2]+ v1+...+v1 (n-i+1個)-target - 式3a[0]+a[1]+...+a[i?2]+v1+...+v1(n?i+1)?target?3
    上下做差:式1-式3 = a[i?1]?v1+(v2?v1)?(n?i)>=0a[i-1]-v1+(v2-v1)*(n-i) >= 0a[i?1]?v1+(v2?v1)?(n?i)>=0
    所以上式是單調(diào)遞增的!可以進行二分查找
class Solution { public:int findBestValue(vector<int>& arr, int target) {int i, l, r, mid, idx, diff, mindiff = INT_MAX, n = arr.size(), ans=INT_MAX;sort(arr.begin(),arr.end());vector<int> presum(arr);for(i = 1; i < n; ++i)presum[i] += presum[i-1];//前綴和l = 0, r = arr[n-1];//范圍while(l <= r){mid = l+((r-l)>>1);idx = binsearch(arr, mid);//二分查找mid這個值在數(shù)組中的位置diff = (idx>0? presum[idx-1] : 0) +(n-idx)*mid-target;//函數(shù)式的值,函數(shù)單調(diào)遞增if(abs(diff) < mindiff){mindiff = abs(diff);ans = mid;//有更小的}else if((abs(diff) == mindiff))ans = min(ans,mid);//相等的情況下取更小的if(diff < 0)//小了,要讓他增大,在0左右尋找l = mid+1;else if(diff > 0)r = mid-1;elsereturn ans;}return ans;}int binsearch(vector<int>& arr, int val){ //找第一個大于val的數(shù)的下標(biāo)int l = 0, r = arr.size()-1, mid;while(l <= r){mid = l+((r-l)>>1);if(arr[mid] > val){if(mid==0 || arr[mid-1] <= val)return mid;elser = mid-1;}elsel = mid+1;}return arr.size();//沒找到,全部小于val} };

總結(jié)

以上是生活随笔為你收集整理的LeetCode 1300. 转变数组后最接近目标值的数组和(二分查找)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。