贪心
数组
题目描述
给你一个整数数组 nums
,和两个整数 limit
与 goal
。数组 nums
有一条重要属性:abs(nums[i]) <= limit
。
返回使数组元素总和等于 goal
所需要向数组中添加的 最少元素数量 ,添加元素 不应改变 数组中 abs(nums[i]) <= limit
这一属性。
注意,如果 x >= 0
,那么 abs(x)
等于 x
;否则,等于 -x
。
示例 1:
输入: nums = [1,-1,1], limit = 3, goal = -4
输出: 2
解释: 可以将 -2 和 -3 添加到数组中,数组的元素总和变为 1 - 1 + 1 - 2 - 3 = -4 。
示例 2:
输入: nums = [1,-10,9,1], limit = 100, goal = 0
输出: 1
提示:
1 <= nums.length <= 105
1 <= limit <= 106
-limit <= nums[i] <= limit
-109 <= goal <= 109
解法
方法一:贪心
我们先计算数组元素总和 $s$,然后计算 $s$ 与 $goal$ 的差值 $d$。
那么需要添加的元素数量为 $d$ 的绝对值除以 $limit$ 向上取整,即 $\lceil \frac{|d|}{limit} \rceil$。
注意,本题中数组元素的数据范围为 $[-10^6, 10^6]$,元素个数最大为 $10^5$,总和 $s$ 以及差值 $d$ 可能会超过 $32$ 位整数的表示范围,因此需要使用 $64$ 位整数。
时间复杂度 $O(n)$,空间复杂度 $O(1)$。其中 $n$ 为数组 $nums$ 的长度。
Python3 Java C++ Go TypeScript Rust C
class Solution :
def minElements ( self , nums : List [ int ], limit : int , goal : int ) -> int :
d = abs ( sum ( nums ) - goal )
return ( d + limit - 1 ) // limit
class Solution {
public int minElements ( int [] nums , int limit , int goal ) {
// long s = Arrays.stream(nums).asLongStream().sum();
long s = 0 ;
for ( int v : nums ) {
s += v ;
}
long d = Math . abs ( s - goal );
return ( int ) (( d + limit - 1 ) / limit );
}
}
class Solution {
public :
int minElements ( vector < int >& nums , int limit , int goal ) {
long long s = accumulate ( nums . begin (), nums . end (), 0l l );
long long d = abs ( s - goal );
return ( d + limit - 1 ) / limit ;
}
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 func minElements ( nums [] int , limit int , goal int ) int {
s := 0
for _ , v := range nums {
s += v
}
d := abs ( s - goal )
return ( d + limit - 1 ) / limit
}
func abs ( x int ) int {
if x < 0 {
return - x
}
return x
}
function minElements ( nums : number [], limit : number , goal : number ) : number {
const sum = nums . reduce (( r , v ) => r + v , 0 );
const diff = Math . abs ( goal - sum );
return Math . floor (( diff + limit - 1 ) / limit );
}
1
2
3
4
5
6
7
8
9
10
11
12 impl Solution {
pub fn min_elements ( nums : Vec < i32 > , limit : i32 , goal : i32 ) -> i32 {
let limit = limit as i64 ;
let goal = goal as i64 ;
let mut sum = 0 ;
for & num in nums . iter () {
sum += num as i64 ;
}
let diff = ( goal - sum ). abs ();
(( diff + limit - 1 ) / limit ) as i32
}
}
int minElements ( int * nums , int numsSize , int limit , int goal ) {
long long sum = 0 ;
for ( int i = 0 ; i < numsSize ; i ++ ) {
sum += nums [ i ];
}
long long diff = labs ( goal - sum );
return ( diff + limit - 1 ) / limit ;
}
GitHub