问题描述
小S拥有一条由n颗珠子组成的手链,每颗珠子都有一个对应的颜色编号。她希望将手链上相同颜色的珠子进行去重,只保留每种颜色最后出现的那颗珠子,同时保持珠子原来的相对顺序。
例如,如果珠子的颜色编号是 [1, 2, 1, 3, 4, 2, 4, 4],去重后的珠子颜色应该是 [1, 3, 2, 4]。
问题理解
我们需要对一个由n颗珠子组成的手链进行去重操作,只保留每种颜色最后出现的那颗珠子,同时保持珠子原来的相对顺序。
数据结构选择
- HashMap:用于记录每种颜色的最后出现位置。
- ArrayList:用于存储去重后的结果。
算法步骤
-
第一次遍历:
- 遍历整个数组,记录每种颜色的最后出现位置。
- 使用HashMap来存储颜色和其最后出现的位置。
-
第二次遍历:
- 再次遍历整个数组,只保留每种颜色最后出现的那颗珠子。
- 如果当前位置是HashMap中记录的最后出现位置,则将该颜色加入到结果列表中。
-
转换结果:
- 将ArrayList转换为int数组,作为最终结果返回。
具体步骤
-
初始化HashMap:用于存储颜色和其最后出现的位置。
-
第一次遍历数组:
- 对于每个颜色,更新HashMap中该颜色的最后出现位置。
-
初始化ArrayList:用于存储去重后的结果。
-
第二次遍历数组:
- 对于每个颜色,检查当前位置是否是HashMap中记录的最后出现位置。
- 如果是,则将该颜色加入到结果列表中。
-
转换结果:
- 将ArrayList转换为int数组,返回结果。
亮点1:使用HashMap记录最后出现位置
- 高效查找:HashMap可以在常数时间内查找和更新元素,非常适合记录每种颜色的最后出现位置。
- 简化逻辑:通过记录最后出现位置,我们可以在第二次遍历时直接判断当前位置是否是该颜色的最后出现位置,从而简化去重逻辑。
亮点2:两次遍历数组
- 第一次遍历:记录每种颜色的最后出现位置。
- 第二次遍历:只保留每种颜色最后出现的那颗珠子。
- 保持顺序:通过两次遍历,我们可以在保持珠子相对顺序的同时完成去重操作。
总结
通过两次遍历数组,我们可以高效地完成去重操作,并保持珠子的相对顺序。HashMap的使用帮助我们快速查找每种颜色的最后出现位置,而ArrayList则用于存储最终的去重结果。
代码
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class Main {
public static int[] solution(int n, int[] a) {
// 使用HashMap来记录每种颜色的最后出现位置
Map<Integer, Integer> lastOccurrence = new HashMap<>();
// 遍历数组,记录每种颜色的最后出现位置
for (int i = 0; i < n; i++) {
lastOccurrence.put(a[i], i);
}
// 使用ArrayList来存储去重后的结果
List<Integer> resultList = new ArrayList<>();
// 再次遍历数组,只保留每种颜色最后出现的那颗珠子
for (int i = 0; i < n; i++) {
if (lastOccurrence.get(a[i]) == i) {
resultList.add(a[i]);
}
}
// 将ArrayList转换为int数组
int[] result = new int[resultList.size()];
for (int i = 0; i < resultList.size(); i++) {
result[i] = resultList.get(i);
}
return result;
}
public static void main(String[] args) {
System.out.println(Arrays.equals(solution(8, new int[]{1, 2, 1, 3, 4, 2, 4, 4}), new int[]{1, 3, 2, 4}));
System.out.println(Arrays.equals(solution(5, new int[]{5, 5, 5, 5, 5}), new int[]{5}));
System.out.println(Arrays.equals(solution(6, new int[]{6, 1, 2, 6, 1, 2}), new int[]{6, 1, 2}));
}
}