2022-06-01:给定一个数组arr,可能有正、有负、有0,无序。 只能挑选两个数字,想尽量让两个数字加起来的绝对值尽量小。 返回可能的最小的值。

答案2022-06-01:

排序,双指针。

代码用rust编写。代码如下:

fn main() {
    let mut arr: Vec<i32> = vec![-8, -5, -2, -1, 0, 1, 7, 9];
    let ans = min_sumabs3(&mut arr);
    println!("ans = {}", ans);
}

fn min_sumabs3(arr: &mut Vec<i32>) -> i32 {
    if arr.len() < 2 {
        return -1;
    }
    arr.sort();
    let n = arr.len() as i32;
    let mut split: i32 = -1;
    for i in 0..n {
        if arr[i as usize] >= 0 {
            split = i;
            break;
        }
    }
    if split == 0 {
        return arr[0] + arr[1];
    }
    if split == -1 {
        return -arr[(n - 2) as usize] - arr[(n - 1) as usize];
    }
    let mut ans = 2147483647;
    if split + 1 < n {
        ans = arr[split as usize] + arr[(split + 1) as usize];
    }
    if split - 2 >= 0 {
        ans = get_min(ans, -arr[(split - 1) as usize] - arr[(split - 2) as usize]);
    }
    let mut r = n - 1;
    for l in 0..split {
        ans = get_min(ans, abs(arr[l as usize] + arr[r as usize]));
        while r - 1 >= split
            && abs(arr[l as usize] + arr[r as usize])
                >= abs(arr[l as usize] + arr[(r - 1) as usize])
        {
            r -= 1;
            ans = get_min(ans, abs(arr[l as usize] + arr[r as usize]));
        }
    }
    return ans;
}

fn get_min<T: Clone + Copy + std::cmp::PartialOrd>(a: T, b: T) -> T {
    if a < b {
        a
    } else {
        b
    }
}

fn abs(a: i32) -> i32 {
    if a < 0 {
        -a
    } else {
        a
    }
}

执行结果如下:

在这里插入图片描述


左神java代码