Hi,大家好,这里是炼手Rust专栏,我是xiaoK,今天来看个小问题:数组等值分割。
提问
小峰将得到一个整数数组。小峰的工作是获取该数组并找到索引 N,其中 N 左侧的整数之和等于 N 右侧的整数之和。
如果没有找到,则返回 None。
例:
input:[1,100,50,-51,1,1]
output:1
因为 100 这个数的左边之和为 1,右边之和也为 1。
input:[20,10,-80,10,10,15,35]
output:None
没有这样的分割,可以让数组的左边等于右边。
模板:
fn find_even_index(arr: &[i32]) -> Option<usize> { }
分析
简单的做法是,遍历一次,然后每次就计算左边与右边的和,判断是否相等即可。
但是更深入一下,这个遍历过程是可以优化的。因为求和过程每次都要计算左边与右边的和,这个效率是很低的,如果我们一开始就知道数组的和,那么在从左向右遍历期间,左边的和加上一个数,而右边的和相当于减去一个数,每次比较左右两边即可,这样就相当于只遍历了两次数组。
- 获取数组的和
sum。 - 初始化变量
l_sum为 0,表示左边的数组之和,变量r_sum为sum,表示右边的数组之和。 - 开始遍历数组,
i为数组下标。 r_sum -= arr\[i\]为当前右边数组之和,判断l_sum == r_sum是否相等。- 如果满足 4,返回当前下标。
- 如果 4 不满足,
l_sum += arr[i]。重复3,4,5,6过程。 - 结束证明没有找到这样的下标,返回
None。
解决方案
fn find_even_index(arr: &[i32]) -> Option<usize> {
let sum = arr.iter().sum();
let mut l_sum = 0;
let mut r_sum = sum;
for i in 0..arr.len() {
r_sum -= arr[i];
if l_sum == r_sum {
return Some(i);
}
l_sum += arr[i];
}
None
}
Trick
array.iter().sum(),获取数组的和。