• 【数据结构】Map和Set


    目录

    一、Map

    1.1 Map常用方法

    1.2 Map注意事项

    1.3 Map的遍历

    二、Set

    2.1 Set常用方法

    2.2 Set注意事项

    2.3 Set的遍历

    三、题目练习

    3.1 从给定的数据中,找出第一个重复的数据

    3.2 去除给定的数据中重复的数据

    3.3 统计重复的数据出现的次数

    3.4 只出现一次的数据

    3.5 复制带随机指针的链表

    3.6 宝石与石头

    3.7 坏键盘打字

    3.8 前K个高频单词


    一、Map

    1.1 Map常用方法

    Map是一个接口类,没有继承Collection。存储的是键值对,键一定是唯一的,不能重复。

    方法说明
    V get(Object key)返回key对应的value
    V getOrDefault(Object key, V defaultValue)返回key对应的value, key 不存在,返回默认值
    V put(K key, V value)设置key对应的value
    V remove(Object key)删除key对应的映射关系
    Set keySet()返回所有key的不重复集合
    Collection values()返回所有value的可重复集合
    Set> entrySet()返回所有的key-value映射关系
    boolean containsKey(Object key)判断是否包含key
    boolean containsValue(Object value)判断是否包含value

    1.2 Map注意事项

    • Map是一个接口,不能直接实例化对象,如果要实例化对象只能实例化其实现类TreeMap或者HashMap
    • Map中存放键值对的Key是唯一的, value是可以重复的
    • Map中的Key可以全部分离出来,存储到Set中来进行访问(因为Key不能重复)。
    • Map中的value可以全部分离出来,存储在Collection的任何-个子集合中(value可能有重复)。
    • Map中键值对的Key不能直接修改, value可以修改,如果要修改key,只能先将该key删除掉,然后再来进行重新插入
    • key可以为null。value也可以为null

    1.3 Map的遍历

    借助Set> entrySet()

    方法说明
    K getKey()返回entry中的key
    V getValue()返回entry中的value
    V setValue(V value)将键值对中的value替换为指定value
    1. Set> entrySet = hashmap.entrySet();
    2. for(Map.Entry entry : entrySet){
    3. int a = entry.getKey();
    4. System.out.println(entry);
    5. }

    二、Set

    2.1 Set常用方法

    方法说明
    boolean add(E e)添加元素,但重复元素不会被添加成功
    void clear()清空集合
    boolean contains(Object 0)判断o是否在集合中
    Iterator iterator()返回迭代器
    boolean remove(Object o) .删除集合中的0
    int size()返回set中元素的个数
    boolean isEmpty()检测set是否为空,空返回true, 否则返回false
    Object[] toArray() 将set中的元素转换为数组返回
    boolean containsAll(Collection c)集合c中的元素是否在set中全部存在,是返回true, 否则返回true
    boolean addAl(Collection将集合c中的元素添加到set中,可以达到去重的效果

    2.2 Set注意事项

    • Set是继承自Collection的一 个接口类
    • Set中只存储了key, 并组要求key一定要唯一
    • Set最大的功能就是对集合中的元素进行去重
    • Set中的Key不能修改,如果要修改,先将原来的删除掉,然后再重新插入
    • 插入的值可以为null

    2.3 Set的遍历

    1. public static void main(String[] args) {
    2. HashSet set = new HashSet<>();
    3. set.add(1);
    4. set.add(2);
    5. set.add(3);
    6. set.add(4);
    7. Iterator iterator = set.iterator();
    8. while (iterator.hasNext()){
    9. System.out.println(iterator.next());
    10. }
    11. }

    三、题目练习

    3.1 从给定的数据中,找出第一个重复的数据

    1. public int func(int[] nums){
    2. Set hashSet = new HashSet<>();
    3. for(int i=0;i
    4. if(hashSet.contains(nums[i])){
    5. return nums[i];
    6. }
    7. hashSet.add(nums[i]);
    8. }
    9. return -1;
    10. }

    3.2 去除给定的数据中重复的数据

    1. public void func2(int[] nums){
    2. Set hashSet = new HashSet<>();
    3. for(int i=0;i
    4. hashSet.add(nums[i]);
    5. }
    6. System.out.println(hashSet);
    7. }

    3.3 统计重复的数据出现的次数

    1. public void fun3(int[] nums){
    2. Map hashmap = new HashMap<>();
    3. for (int i = 0; i < nums.length; i++) {
    4. if(hashmap.containsKey(nums[i])){
    5. // 如果在hashmap中存在,就更新次数
    6. int count = hashmap.get(nums[i]);
    7. count = count+1;
    8. hashmap.put(nums[i],count);
    9. }else{
    10. // 不存在,就放入hashmap中,值是1
    11. hashmap.put(nums[i],1);
    12. }
    13. }
    14. Set> entrySet = hashmap.entrySet();
    15. // 遍历hashmap
    16. for(Map.Entry entry : entrySet){
    17. int a = entry.getKey();
    18. System.out.println(entry);
    19. }
    20. }

    3.4 只出现一次的数据

    力扣

    1. class Solution {
    2. public int singleNumber(int[] nums) {
    3. Set set = new HashSet<>();
    4. for(int i=0;i
    5. // 如果已经出现,就从set中移除该元素
    6. if(set.contains(nums[i])){
    7. set.remove(nums[i]);
    8. }else{
    9. set.add(nums[i]);
    10. }
    11. }
    12. // set剩下的元素就是只出现一次的元素
    13. Iterator it = set.iterator();
    14. while(it.hasNext()){
    15. return it.next();
    16. }
    17. return -1;
    18. }
    19. }

    3.5 复制带随机指针的链表

    力扣

    1. class Solution {
    2. public Node copyRandomList(Node head) {
    3. Map map = new HashMap<>();
    4. Node cur = head;
    5. while(cur != null){
    6. // 将新节点和旧节点的对应关系存储到map中
    7. Node node = new Node(cur.val);
    8. map.put(cur,node);
    9. cur = cur.next;
    10. }
    11. cur = head;
    12. while(cur != null){
    13. // 得到新节点
    14. // 从map中得到新节点和旧节点 根据旧节点的next和random属性修改新节点的属性
    15. Node node = map.get(cur);
    16. node.next = map.get(cur.next);
    17. node.random = map.get(cur.random);
    18. cur = cur.next;
    19. }
    20. return map.get(head);
    21. }
    22. }

    3.6 宝石与石头

    力扣

    1. class Solution {
    2. public int numJewelsInStones(String jewels, String stones) {
    3. Set set = new HashSet<>();
    4. for(int i =0;i
    5. char ch = jewels.charAt(i);
    6. // 对jewels中的字符进行去重
    7. if(!set.contains(ch)){
    8. set.add(ch);
    9. }
    10. }
    11. int sum = 0;
    12. for(int i =0;i
    13. char ch = stones.charAt(i);
    14. // stones中的字符如果在set中出现,sum++
    15. if(set.contains(ch)){
    16. sum++;
    17. }
    18. }
    19. return sum;
    20. }
    21. }

    3.7 坏键盘打字

    旧键盘 (20)__牛客网

    1. import java.util.*;
    2. public class Main{
    3. public static void func(String str1,String str2){
    4. // 先将字符串转成大写的字符数组
    5. char[] ch1 = str1.toUpperCase().toCharArray();
    6. char[] ch2 = str2.toUpperCase().toCharArray();
    7. // ch1是正常的输入
    8. // ch2是实际的输入
    9. Set set1 = new HashSet<>();
    10. for(char ch:ch2){
    11. // 统计ch2中出现的不重复的字符 ,这些字符都是好的按键
    12. if(!set1.contains(ch)){
    13. set1.add(ch);
    14. }
    15. }
    16. Set set2 = new HashSet<>();
    17. for(char ch:ch1){
    18. // 如果字符没有在好的按键集合里,就加到set2中,加之前要判断是否已经存在,如果存在,就不用再add了
    19. if(!set1.contains(ch)){
    20. if(!set2.contains(ch)){
    21. set2.add(ch);
    22. System.out.print(ch);
    23. }
    24. }
    25. }
    26. }
    27. public static void main(String[] args){
    28. Scanner scanner = new Scanner(System.in);
    29. String str1 = scanner.nextLine();
    30. String str2 = scanner.nextLine();
    31. func(str1,str2);
    32. }
    33. }

    3.8 前K个高频单词

    力扣

    • 先统计每个单词的出现次数
    • 建立一个小根堆,重写compare方法。存在两种情况,第一种是两个词的出现次数一样,比较单词的首字母的AscII码值。第二种情况是两个词的出现次数不一样
    • topK思想。
    1. class Solution {
    2. public List topKFrequent(String[] words, int k) {
    3. int c = k;
    4. HashMap hashmap = new HashMap<>();
    5. // 统计每个单词的出现次数
    6. for(String str:words){
    7. if(!hashmap.containsKey(str)){
    8. hashmap.put(str,1);
    9. }else{
    10. int count = hashmap.get(str);
    11. hashmap.put(str,count+1);
    12. }
    13. }
    14. // 建立一个小根堆,重写compare方法
    15. PriorityQueue> queue = new PriorityQueue<>(new Comparator>(){
    16. @Override
    17. public int compare(Map.Entry o1,Map.Entry o2){
    18. if(o1.getValue().equals(o2.getValue())){
    19. return o2.getKey().compareTo(o1.getKey());
    20. }
    21. return o1.getValue()-o2.getValue();
    22. }
    23. });
    24. // topK的思想
    25. for(Map.Entry entry : hashmap.entrySet()){
    26. if(k >0){
    27. queue.offer(entry);
    28. k--;
    29. }else{
    30. Map.Entry peek = queue.peek();
    31. int tmp = peek.getValue().compareTo(entry.getValue());
    32. if(tmp < 0){
    33. queue.poll();
    34. queue.offer(entry);
    35. }else if(tmp == 0){
    36. if(peek.getKey().compareTo(entry.getKey()) >0 ){
    37. queue.poll();
    38. queue.offer(entry);
    39. }
    40. }
    41. }
    42. }
    43. List result = new ArrayList<>();
    44. for(int i=0;i
    45. result.add(queue.poll().getKey());
    46. }
    47. Collections.reverse(result);
    48. return result;
    49. }
    50. }

  • 相关阅读:
    LeetCode-高频 SQL 50 题:连接 篇
    2022年最新山西机动车签字授权人模拟考试及答案
    【Java小知识点】类加载器的区别
    算法篇 滑动窗口 leetcode 长度最小的子数组
    常识——虚拟机安装centos7与联网
    区块链智能合约开发
    Spring之ioc
    物联网智慧大屏
    串口控制小车电机转动+蓝牙长按控制
    Go语言基础之包
  • 原文地址:https://blog.csdn.net/weixin_44258092/article/details/126453640