[炼手Rust]数组等值分割

116 阅读2分钟

Hi,大家好,这里是炼手Rust专栏,我是xiaoK,今天来看个小问题:数组等值分割。

wellaprobloghalfandhalfhaircolorimage1.jpg

提问

小峰将得到一个整数数组。小峰的工作是获取该数组并找到索引 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> { }

分析

简单的做法是,遍历一次,然后每次就计算左边与右边的和,判断是否相等即可。
但是更深入一下,这个遍历过程是可以优化的。因为求和过程每次都要计算左边与右边的和,这个效率是很低的,如果我们一开始就知道数组的和,那么在从左向右遍历期间,左边的和加上一个数,而右边的和相当于减去一个数,每次比较左右两边即可,这样就相当于只遍历了两次数组。

  1. 获取数组的和sum
  2. 初始化变量l_sum为 0,表示左边的数组之和,变量r_sumsum,表示右边的数组之和。
  3. 开始遍历数组,i为数组下标。
  4. r_sum -= arr\[i\]为当前右边数组之和,判断l_sum == r_sum是否相等。
  5. 如果满足 4,返回当前下标。
  6. 如果 4 不满足,l_sum += arr[i]。重复3,4,5,6过程。
  7. 结束证明没有找到这样的下标,返回 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

  1. array.iter().sum(),获取数组的和。