前缀和 数组
题目描述 给你一个下标从 0 开始的长度为 n 的整数数组 nums。
定义两个数组 leftSum 和 rightSum,其中:
leftSum[i] 是数组 nums 中下标 i 左侧元素之和。如果不存在对应的元素,leftSum[i] = 0 。 rightSum[i] 是数组 nums 中下标 i 右侧元素之和。如果不存在对应的元素,rightSum[i] = 0 。 返回长度为 n 数组 answer,其中 answer[i] = |leftSum[i] - rightSum[i]|。
示例 1:
输入: nums = [10,4,8,3]
输出: [15,1,11,22]
解释: 数组 leftSum 为 [0,10,14,22] 且数组 rightSum 为 [15,11,3,0] 。
数组 answer 为 [|0 - 15|,|10 - 11|,|14 - 3|,|22 - 0|] = [15,1,11,22] 。
示例 2:
输入: nums = [1]
输出: [0]
解释: 数组 leftSum 为 [0] 且数组 rightSum 为 [0] 。
数组 answer 为 [|0 - 0|] = [0] 。
提示:
1 <= nums.length <= 1000 1 <= nums[i] <= 105 解法 方法一:前缀和 我们定义变量 \(l\) 表示数组 \(\textit{nums}\) 中下标 \(i\) 左侧元素之和,变量 \(r\) 表示数组 \(\textit{nums}\) 中下标 \(i\) 右侧元素之和。初始时 \(l = 0\) , \(r = \sum_{i = 0}^{n - 1} \textit{nums}[i]\) 。
遍历数组 \(\textit{nums}\) ,对于当前遍历到的数字 \(x\) ,我们更新 \(r = r - x\) ,此时 \(l\) 和 \(r\) 分别表示数组 \(\textit{nums}\) 中下标 \(i\) 左侧元素之和和右侧元素之和。我们将 \(l\) 和 \(r\) 的差的绝对值加入答案数组 \(\textit{ans}\) 中,然后更新 \(l = l + x\) 。
遍历结束,返回答案数组 \(\textit{ans}\) 即可。
时间复杂度 \(O(n)\) ,其中 \(n\) 是数组 \(\textit{nums}\) 的长度。空间复杂度 \(O(1)\) ,不考虑返回值的空间。
相似题目:
Python3 Java C++ Go TypeScript Rust C
class Solution :
def leftRightDifference ( self , nums : List [ int ]) -> List [ int ]:
l , r = 0 , sum ( nums )
ans = []
for x in nums :
r -= x
ans . append ( abs ( l - r ))
l += x
return ans
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 class Solution {
public int [] leftRightDifference ( int [] nums ) {
int l = 0 , r = 0 ;
for ( int x : nums ) {
r += x ;
}
int n = nums . length ;
int [] ans = new int [ n ] ;
for ( int i = 0 ; i < n ; ++ i ) {
r -= nums [ i ] ;
ans [ i ] = Math . abs ( l - r );
l += nums [ i ] ;
}
return ans ;
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 class Solution {
public :
vector < int > leftRightDifference ( vector < int >& nums ) {
int l = 0 , r = 0 ;
for ( int x : nums ) {
r += x ;
}
int n = nums . size ();
vector < int > ans ( n );
for ( int i = 0 ; i < n ; ++ i ) {
r -= nums [ i ];
ans [ i ] = abs ( l - r );
l += nums [ i ];
}
return ans ;
}
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 func leftRightDifference ( nums [] int ) [] int {
l , r := 0 , 0
for _ , x := range nums {
r += x
}
n := len ( nums )
ans := make ([] int , n )
for i , x := range nums {
r -= x
ans [ i ] = abs ( l - r )
l += x
}
return ans
}
func abs ( x int ) int {
if x < 0 {
return - x
}
return x
}
function leftRightDifference ( nums : number []) : number [] {
let [ l , r ] = [ 0 , nums . reduce (( a , b ) => a + b , 0 )];
const ans : number [] = [];
for ( const x of nums ) {
r -= x ;
ans . push ( Math . abs ( l - r ));
l += x ;
}
return ans ;
}
1
2
3
4
5
6
7
8
9
10
11
12
13 impl Solution {
pub fn left_right_difference ( nums : Vec < i32 > ) -> Vec < i32 > {
let mut l = 0 ;
let mut r : i32 = nums . iter (). sum ();
let mut ans = Vec :: with_capacity ( nums . len ());
for x in nums {
r -= x ;
ans . push (( l - r ). abs ());
l += x ;
}
ans
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 /**
* Note: The returned array must be malloced, assume caller calls free().
*/
int * leftRightDifference ( int * nums , int numsSize , int * returnSize ) {
* returnSize = numsSize ;
int * ans = ( int * ) malloc ( sizeof ( int ) * numsSize );
int l = 0 , r = 0 ;
for ( int i = 0 ; i < numsSize ; ++ i ) {
r += nums [ i ];
}
for ( int i = 0 ; i < numsSize ; ++ i ) {
r -= nums [ i ];
ans [ i ] = abs ( l - r );
l += nums [ i ];
}
return ans ;
}