找出与数组相加的整数 Ⅱ。用go语言,给定两个整数数组 nums1 和 nums2,你需要从 nums1 中移除两个元素,然后将 nums1 中的其余元素与一个整数 x 相加。
如果 x 是负数,则相当于减少元素的值。执行这些操作后,要使得 nums1 和 nums2 相等。
两个数组相等的定义为它们包含相同的整数,并且这些整数的出现频率也相同。
请返回能够使这两个数组相等的最小整数 x。
输入:nums1 = [4,20,16,12,8], nums2 = [14,18,10]。
输出:-2。
解释:
移除 nums1 中下标为 [0,4] 的两个元素,并且每个元素与 -2 相加后,nums1 变为 [18,14,10] ,与 nums2 相等。
大体步骤如下:
1.首先,给 nums1 和 nums2 数组进行排序,以便后续比较。
2.再循环 nums1 数组的倒数三个元素(0-based index),从倒数第三个元素开始向前:
2.a. 设定 left 和 right 两个指针,分别指向 nums1 和 nums2 数组的起始位置。
2.b. 在一个循环中,比较 nums1[left] - nums2[right] 是否等于 nums1[i] - nums2[0],如果相等则继续移动 right 指针,直到不相等为止。
2.c. 在移动过程中,不断更新 left 和 right 指针的位置,直到其中一个数组被遍历完全(即 right 指针达到 nums2 数组的末尾)。
2.d. 如果 right 指针达到 nums2 数组末尾,则返回 nums2[0] - nums1[i]。
3.如果没有找到合适的解,最终返回 0。
总的时间复杂度为 O(nlog(n)),其中 n 为 nums1 和 nums2 数组的总长度,主要是排序的时间复杂度。
额外空间复杂度为 O(1),只使用了少量指针和变量,没有使用额外的数据结构。
Go完整代码如下:
package main
import (
"fmt"
"sort"
)
func minimumAddedInteger(nums1 []int, nums2 []int) int {
sort.Ints(nums1)
sort.Ints(nums2)
for i := 2; i >= 0; i-- {
left, right := i+1, 1
for left < len(nums1) && right < len(nums2) {
if nums1[left]-nums2[right] == nums1[i]-nums2[0] {
right++
}
left++
}
if right == len(nums2) {
return nums2[0] - nums1[i]
}
}
return 0
}
func main() {
nums1 := []int{4, 20, 16, 12, 8}
nums2 := []int{14, 18, 10}
fmt.Println(minimumAddedInteger(nums1, nums2))
}
Rust完整代码如下:
use std::cmp::Ordering;
fn minimum_added_integer(nums1: &mut Vec<i32>, nums2: &Vec<i32>) -> i32 {
let mut nums1_sorted = nums1.clone();
let mut nums2_sorted = nums2.clone();
nums1_sorted.sort();
nums2_sorted.sort();
for i in (0..=2).rev() {
let mut left = i + 1;
let mut right = 1;
while left < nums1_sorted.len() && right < nums2_sorted.len() {
if nums1_sorted[left] - nums2_sorted[right] == nums1_sorted[i] - nums2_sorted[0] {
right += 1;
}
left += 1;
}
if right == nums2_sorted.len() {
return nums2_sorted[0] - nums1_sorted[i];
}
}
0
}
fn main() {
let mut nums1 = vec![4, 20, 16, 12, 8];
let nums2 = vec![14, 18, 10];
println!("{}", minimum_added_integer(&mut nums1, &nums2));
}