leetcode 1300m 转变数组后最接近目标值的数组和

Published on:
Tags: leetcode

题目描述#

给你一个整数数组 arr 和一个目标值 target ,请你返回一个整数 value ,使得将数组中所有大于 value 的值变成 value 后,数组的和最接近  target (最接近表示两者之差的绝对值最小)。

如果有多种使得和最接近 target 的方案,请你返回这些整数中的最小值。

请注意,答案不一定是 arr 中的数字。

示例1:

1
2
3
输入:arr = [4,9,3], target = 10
输出:3
解释:当选择 value 为 3 时,数组会变成 [3, 3, 3],和为 9 ,这是最接近 target 的方案。

算法#

  1. 排序数组
  2. 遍历数组,找到 $i$ ,使得 $i$ 满足 $sum_{i-1} + arr[i] \times (arrSize - i) > target$ $(sum_i$表示从$0$至$i$的累加和$)$ 。
    找到 $i$ 之后,表示结果 $value < arr[i]$,即从 $i$ 开始以后的元素都使用 $value$ 代替,于是 $value$ 约等于 $(target-sum_{i-1}) \div (arrSize - i)$,说约等于因为这里可能结果不是整数,所以需要根据题意找到最优解(最接近,最小)。
  3. 当 $i==arrSize$ 时,表示数组元素之和小于 $target$ ,返回数组的最大元素即可。

C代码#

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
#include <stdio.h>
#include <stdlib.h>

void bubble(int* arr, int arrSize);
int findBestValue(int* arr, int arrSize, int target);

int main()
{
int arr[] = {4,9,3};
int n = 3,target = 10;
int value = findBestValue(&arr[0],n,target);
printf("value=%d",value);
return 0;
}
// 排序
void bubble(int* arr, int arrSize)
{
for(int i=0;i<arrSize-1;i++)
{
int flag = 1;
for(int j=arrSize-1;j>i;j--)
{
if(arr[j] < arr[j-1])
{
int temp = arr[j];
arr[j] = arr[j-1];
arr[j-1] = temp;
flag = 0;
}
}
if(flag == 1) break;
}
}

int findBestValue(int* arr, int arrSize, int target)
{
bubble(&arr[0],arrSize);
int i,sum=0;

for(i=0;i<arrSize;i++)
{
if(sum + arr[i]*(arrSize-i) > target) break;
sum += arr[i];
}

if(i == arrSize) return arr[arrSize-1];

int value = (target-sum)/(arrSize-i);
double value_1 = (double)(target-sum)/(arrSize-i);
if(value_1 - value > 0.5)
return value+1;
else
return value;
}

时间复杂度#

算法的时间复杂度为排序算法时间复杂度 $O(n^2)$