还原原数组
难度:
标签:
题目描述
代码结果
运行时间: 100 ms, 内存: 16.5 MB
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;
import java.util.stream.Collectors;
/**
* Using Java Streams to process the array and find the original array `arr`.
* The logic is the same but uses more functional programming style.
*/
public class Solution {
public int[] recoverArray(int[] nums) {
Arrays.sort(nums);
int n = nums.length / 2;
for (int i = 1; i < nums.length; i++) {
int k = (nums[i] - nums[0]) / 2;
if (k > 0 && (nums[i] - nums[0]) % 2 == 0) {
Set<Integer> lowerSet = new HashSet<>();
Set<Integer> higherSet = Arrays.stream(nums).boxed().collect(Collectors.toSet());
for (int num : nums) {
if (!lowerSet.contains(num - k)) {
lowerSet.add(num);
} else {
higherSet.remove(num);
}
}
if (lowerSet.size() == n && higherSet.size() == n) {
int[] result = lowerSet.stream().mapToInt(num -> num + k).toArray();
return result;
}
}
}
return new int[0];
}
}
解释
方法:
首先,对输入数组 nums 进行排序。然后遍历数组,尝试找到可能的差值 d = 2k,其中 k 是原数组 arr 和 lower 或 higher 数组之间的差值。这个差值 d 必须是偶数,因为 k 需要是整数。对于每一个可能的 d,尝试将 nums 分为两组,一组表示 lower,一组表示 higher。使用一个集合 vis 来记录已经被使用的 higher 的索引,确保每个元素只被使用一次。通过遍历检查是否可以完全匹配 lower 和 higher 数组。如果成功匹配,说明已经找到了原数组 arr。此算法尝试所有可能的 d,直到找到一个有效的结果。
时间复杂度:
O(n^2)
空间复杂度:
O(n)
代码细节讲解
🦆
在尝试找到可能的差值 d 时,你是如何确定 d 必须是偶数的?
▷🦆
为什么在遍历数组时跳过重复元素,即 nums[i] == nums[i - 1] 的情况?
▷🦆
在双指针策略中,为什么选择 nums[i] - nums[0] 作为起始的差值 d?这种选择对于找到正确的 k 有什么特别的意义吗?
▷🦆
算法在检测到 nums[hi] - nums[lo] > d 时选择中断循环,这样的处理是否可能导致漏掉正确的 k 值?
▷