从相邻元素对还原数组
难度:
标签:
题目描述
代码结果
运行时间: 161 ms, 内存: 55.3 MB
/*
* 思路:
* 1. 使用一个哈希映射来记录每个数的相邻元素。
* 2. 找到只有一个相邻元素的数,它必定是数组的起点或终点。
* 3. 使用Java Stream来构建原始数组。
*/
import java.util.*;
import java.util.stream.Collectors;
public class Solution {
public int[] restoreArray(int[][] adjacentPairs) {
// 创建一个哈希映射来记录每个数的相邻元素
Map<Integer, List<Integer>> map = Arrays.stream(adjacentPairs)
.flatMap(pair -> Arrays.stream(new int[][] { { pair[0], pair[1] }, { pair[1], pair[0] } }))
.collect(Collectors.groupingBy(pair -> pair[0], Collectors.mapping(pair -> pair[1], Collectors.toList())));
// 找到只有一个相邻元素的数,作为数组的起点
int start = map.keySet().stream().filter(key -> map.get(key).size() == 1).findFirst().get();
// 构建原始数组
int n = adjacentPairs.length + 1;
int[] result = new int[n];
Set<Integer> visited = new HashSet<>();
result[0] = start;
visited.add(start);
for (int i = 1; i < n; i++) {
int current = result[i - 1];
int next = map.get(current).stream().filter(neighbor -> !visited.contains(neighbor)).findFirst().get();
result[i] = next;
visited.add(next);
}
return result;
}
}
解释
方法:
这个题解首先利用一个哈希表(使用defaultdict(list))来存储每个数及其相邻的数。键是数组中的数,值是与这个键相邻的数的列表。通过遍历adjacentPairs,将每对相邻的数相互添加到对方的列表中。接着,找到那个只有一个相邻数的数,这个数必定是原数组的端点(起点或终点)。从这个端点开始,逐步构建原数组,直到到达另一个端点。为了确保不重复访问,我们维护一个历史变量来记录上一个访问的元素,以此来决定下一个应该访问的元素。
时间复杂度:
O(n)
空间复杂度:
O(n)
代码细节讲解
🦆
在哈希表构建过程中,为什么要将每对相邻数相互添加到对方的列表中,而不是只添加一次?
▷🦆
如何保证在寻找原数组端点时,只选择了那些只有一个邻居的元素,而不会错误地选择有两个邻居的元素?
▷🦆
题解中提到,从端点开始构建原数组,但实际操作中如何确保不在遍历过程中回访已经访问过的节点?
▷🦆
在while循环条件中,`if len(num_cnt[start]) == 1` 是如何确保已经到达数组的另一个端点?
▷