Java算法题解析(9)——Map和Set专题

在Java算法专栏,博主会分 1. 解题思路 2. 代码实现及解析 3. 总结 三部分整理算法解析,作为我们笔试手撕算法的资本,博主会慢慢整理出更多的不同的算法篇章,敬请期待!进去狠狠刷题~~

预祝大家笔试、面试轻松过,拿下满意offer~

文章目录

一、随机链表的复制

Leetcode链接

题目简单说就是复刻一个和原随机链表结构、指向完全一样的新链表,新链表所有节点都是全新的,指针绝对不能指向原链表的任何节点。

核心要求就2点:

  1. 新节点的 val 、 next 指向、 random 指向,和原链表对应节点完全一致;

  2. 新链表的所有指针,只能指向新链表自己的节点,不能碰原链表。

解题思路

哈希表映射法:用map存<原节点,新节点>,一次遍历建节点,二次遍历补next/random。

代码实现及解析

java 复制代码
import java.util.HashMap;
import java.util.Map;

// Definition for a Node.
class Node {
    int val;
    Node next;
    Node random;

    public Node(int val) {
        this.val = val;
        this.next = null;
        this.random = null;
    }
}


class Solution {
    public Node copyRandomList(Node head) {
        Map<Node,Node> map=new HashMap<>();//map来存放"旧-新"节点对
        Node cur=head;
        //遍历原链表,对于每一个节点,构造出一个新的节点(val值复制),并将这样的新旧两个节点作为一个键值对存入map中
        while(cur!=null){
            Node node=new Node(cur.val);
            map.put(cur,node);
            cur=cur.next;
        }
        //再遍历一遍旧链表,这一遍有了map的作用,我们再遍历旧链表的同时就可以对新链表节点之间的一一对应关系搭建好
        cur=head;
        while(cur!=null){
            map.get(cur).next=map.get(cur.next);//根据旧链表遍历结果将新链表的节点链接
            map.get(cur).random=map.get(cur.random);//根据旧链表的random值,新链表也具有一样的对应关系,将其填入
            cur=cur.next;

        }

        return map.get(head);
    }
}

总结

  • 充分利用了map能储存key与val的对应关系的特点

二、前K个高频单词

Leetcode链接

给定一个单词列表 words 和一个整数 k ,返回前 k 个出现次数最多的单词。

返回的答案应该按单词出现频率由高到低排序。如果不同的单词有相同出现频率, 按字典顺序排序。

解题思路

  • 先利用Map统计好各单词出现的次数
  • 再使用经典的topK问题的解题法解题

代码实现

java 复制代码
import java.util.*;

//构造一个比较器,作为PriorityQueue的参数
class myComparator implements Comparator<Map.Entry<String,Integer>> {
    public int compare(Map.Entry<String,Integer> o1,Map.Entry<String,Integer> o2){
        if(o1.getValue().equals(o2.getValue())){//如果出现次数一样,则按照字典序排序
            return o2.getKey().compareTo(o1.getKey());
        }else{//谁的val(出现次数)小,谁就排在前面
            return o1.getValue().compareTo(o2.getValue());
        }
    }
}



class Solution {
    public List<String> topKFrequent(String[] words, int k) {
        //1.先将各单词出现的次数统计出来
        Map<String,Integer> map=new HashMap<>();
        for(String str:words){
            if(!map.containsKey(str)){
                map.put(str,1);
            }else{
                int val=map.get(str);
                map.put(str,val+1);
            }
        }

        //2.再来使用topK问题的解法

        //建立小根堆
        PriorityQueue<Map.Entry<String,Integer>> minHeap=new PriorityQueue<>(new myComparator());
        //遍历map
        for(Map.Entry<String,Integer> entry:map.entrySet()){
            if(minHeap.size()<k){//先用前k个map节点建个小根堆
                minHeap.offer(entry);
            }else{//后面的节点再依据数据值按不同逻辑处理
                Map.Entry<String,Integer> top=minHeap.peek();//堆顶元素
                if(entry.getValue().compareTo(top.getValue())>0){//若该节点的val值大于top的val值,则弹出top,插入该节点
                    minHeap.poll();
                    minHeap.offer(entry);
                }else if(entry.getValue().compareTo(top.getValue())==0){//若该节点的val值等于top的val值,则按照字典序排序
                    if(entry.getKey().compareTo(top.getKey())<0){
                        minHeap.poll();
                        minHeap.offer(entry);
                    }
                }
            }
        }
        //将minHeap中每个节点的key值,也就是单词一一取出(此时还是升序)
        List<String> list=new ArrayList<>();
        while(!minHeap.isEmpty()){
            String str=minHeap.poll().getKey();
            list.add(str);
        }
        //将list反转
        Collections.reverse(list);
        return list;

    }

}

觉得文章对你有帮助的话就点个赞,收藏起来这份免费的资料吧!也欢迎大家在评论区讨论技术、经验

相关推荐
草履虫建模18 小时前
力扣算法 1768. 交替合并字符串
java·开发语言·算法·leetcode·职场和发展·idea·基础
naruto_lnq20 小时前
分布式系统安全通信
开发语言·c++·算法
Jasmine_llq21 小时前
《P3157 [CQOI2011] 动态逆序对》
算法·cdq 分治·动态问题静态化+双向偏序统计·树状数组(高效统计元素大小关系·排序算法(预处理偏序和时间戳)·前缀和(合并单个贡献为总逆序对·动态问题静态化
qq_2975746721 小时前
【实战教程】SpringBoot 实现多文件批量下载并打包为 ZIP 压缩包
java·spring boot·后端
老毛肚21 小时前
MyBatis插件原理及Spring集成
java·spring·mybatis
学嵌入式的小杨同学21 小时前
【Linux 封神之路】信号编程全解析:从信号基础到 MP3 播放器实战(含核心 API 与避坑指南)
java·linux·c语言·开发语言·vscode·vim·ux
lang2015092821 小时前
JSR-340 :高性能Web开发新标准
java·前端·servlet
Re.不晚21 小时前
Java入门17——异常
java·开发语言
爱吃rabbit的mq21 小时前
第09章:随机森林:集成学习的威力
算法·随机森林·集成学习
缘空如是21 小时前
基础工具包之JSON 工厂类
java·json·json切换