Map:存储键值对 (key-value pairs),并且每个键都是唯一的
Map的特性:
- 键值对存储:每个元素是一个键值对(key-value),通过键来访问值。
- 键的唯一性:键必须是唯一的,不能重复。
- 值可以重复:值可以是相同的,但不同的键需要指向不同的存储位置。
- 允许 null:一些实现允许 null 键和 null 值(如 HashMap),但有些实现(如 Hashtable)不允许。
常用方法:
- put(K key, V value):将指定键值对放入 Map 中,若键已存在则替换旧值。
- get(Object key):返回指定键对应的值,若键不存在则返回 null。
- containsKey(Object key):检查是否包含指定的键。
- containsValue(Object value):检查是否包含指定的值。
- remove(Object key):删除指定键的键值对,返回该键对应的值。
- size():返回 Map 中键值对的数量。
- isEmpty():判断 Map 是否为空。
- keySet():返回包含所有键的 Set 视图。
- values():返回包含所有值的 Collection 视图。
- entrySet():返回包含所有键值对的 Set 视图,便于遍历。
- 在算法题中时常会用到
getOrDefault()方法:从映射中获取指定键的值,如果该键不存在,则返回一个默认值。
常见实现类:
- HashMap
- LinkedHashMap(HashMap的子类)
- TreeMap(基于红黑树实现)
算法题目
1.找出整型数组中占比超过一半的数
题目:给定一个长度为n的整型数组,已知其中一个数字的出现次数超过数组长度的一半,找出这个元素。
题解:
- 使用一个
Map来记录数组中每个数字出现的次数。 - 遍历数组,对于每个数字,将其出现次数记录在
Map中,键为数字,值为该数字的出现次数。 - 在遍历过程中,检查当前数字的出现次数是否大于
n/2:- 如果大于
n/2,则该数字即为答案,直接返回。 - 如果遍历结束仍未找到超过一半的数字(理论上这种情况不会发生,因为题目保证存在一个占比超过一半的数字)。
- 如果大于
public static int solution(int[] array) {
// Edit your code here
HashMap<Integer, Integer> hp = new HashMap<>();
int len = array.length;
for (int i = 0; i < len; i++) {
if (hp.containsKey(array[i])) {
int num = hp.get(array[i]) + 1;
hp.put(array[i], num);
if (num > len / 2) {
return array[i];
}
} else {
hp.put(array[i], 1);
}
}
return 0;
}
2.分组飞行棋棋子
题目:小M和小F在玩飞行棋。游戏结束后,他们需要将桌上的飞行棋棋子分组整理好。现在有 N 个棋子,每个棋子上有一个数字序号。小M的目标是将这些棋子分成 M 组,每组恰好5个,并且组内棋子的序号相同。小M希望知道是否可以按照这种方式对棋子进行分组。
题解:
- 遍历棋子的序号数组,将每个序号的出现次数记录在
Map中,键为序号,值为该序号的棋子数量。 - 遍历
Map,检查每个序号的棋子数量: 如果数量不是 5 的倍数,无法满足每组恰好 5 个相同序号的要求,直接返回false。 - 如果所有序号的棋子数量都是 5 的倍数,且总组数等于
M,则返回true,否则返回false。
public static String solution(int[] nums) {
// Please write your code here
if (nums.length % 5 != 0) {
return "False";
}
HashMap<Integer, Integer> map = new HashMap<>();
for (int i = 0; i < nums.length; i++) {
if (map.containsKey(nums[i])) {
map.put(nums[i], map.get(nums[i]) + 1);
} else {
map.put(nums[i], 1);
}
}
for (Integer value : map.values()) {
if (value % 5 != 0) {
return "False";
}
}
return "True";
}
3.寻找独特数字卡片
题目:在一个班级中,每位同学都拿到了一张卡片,上面有一个整数。有趣的是,除了一个数字之外,所有的数字都恰好出现了两次。现在需要你帮助班长小C快速找到那个拿了独特数字卡片的同学手上的数字是什么。
题解:遍历卡片的数字数组,将Map中不存在的key将其put,遍历到Map中已有的将其remove,输出Map中最后剩下的key即是结果。只需要遍历一遍即可。
public static int solution(int[] cards) {
// Edit your code here
HashMap<Integer, Integer> hashMap = new HashMap<>();
for (int i = 0; i < cards.length; i++) {
if (hashMap.containsKey(cards[i])) {
hashMap.remove(cards[i]);
} else {
hashMap.put(cards[i], 1);
}
}
Set<Integer> keys = hashMap.keySet();
int res = 0;
for (Integer key : keys) {
res = key;
}
return res;
}