LeetCode题解12 (146,97) LRU缓存<HashMap + 双向链表>,二叉树的中序遍历

LRU缓存(146)

在这里插入图片描述
从题上看存在Key和Value因此我们采用HashMap来进行存储,这里我们采用HashMap+双向链表来实现,我们需要实现里面的get,put方法。

我们需要先创建1个链表节点

//先定义一个节点类
class ListNode{
    //它是一个双向链表
    int key;
    int value;
    ListNode front;
    ListNode next;
    public ListNode(int key,int value){
        this.key = key;
        this.value = value;
    }
}

这里我们先实现put方法,根据题意:
1.首先我们应该判断当前的Map中是否存在一样的Key。
2.如果有了,我们就直接将原来的Value变成新的Value就行了,同时将这个节点放到首位。
3.如果没有,我们还要先判断HashMap的容量(capacity),如果超过了容量就删除最后一个节点,如果没有超过我们就把新的节点放到链表的末尾同时在HashMap添加。

public void put(int key, int value) {
        //先看该链表中有无当前的key,没有的话在添加之前要先确定容量
        if(!map.containsKey(key)){
            if(map.size() == capacity) {
            deletLastNode();
         }
            //先保存第一个节点即head的下一个节点
            ListNode temp = head.next;
            //先定义要新添加的节点
            ListNode newListNode = new ListNode(key,value);
            //head的下一个节点即为第一个节点,因为是双向链表因此需要2次连接
            head.next = newListNode;
            newListNode.front = head;
            //将temp连接到新的链表之后
            newListNode.next = temp;
            temp.front = newListNode;
            //再将新的节点加入map
            map.put(key,newListNode);
        }else{
            //如果map中有key的话,我们仅需要更改里面的value
              //先拿到对应key的节点
            ListNode list1 = map.get(key);
            list1.value = value;
            //因为我们做了1次修改,我们应该把修改的那个节点放在最前面
            putNodeFirst(list1);
        }
    }

同时这里面涉及到了将节点放到首位的方法: putNodeFirst()

实现:

这里如果不理解链表节点连接的建议画个双向链表来比对

//把当前的节点放到链表首位
    private void putNodeFirst(ListNode node){
        //这里建议画图好理解
        node.front.next = node.next;
        node.next.front = node.front;
        //记录第一个节点
        ListNode temp = head.next;
        head.next = node;
        node.front = head;
        node.next = temp;
        temp.front = node;
    }
}

删除最后一个节点的方法 : deletLastNode()

 //删除最后一个节点
    private void deletLastNode(){
        //先找到到最后一个节点即tail的上一个节点
        ListNode lastNode = tail.front;
        //然后我们将倒数第2个节点与tail连接那么倒数第二个节点就成了最后1个节点了
        lastNode.front.next = tail;
        tail.front = lastNode.front;
        //将最后lastNode从map中移除
        map.remove(lastNode.key);
    }

get方法的实现:
先判断map中是否存在对应的key值,没有的话返回-1,有的话返回对应的value,然后将对应的节点放到首位

 public int get(int key) {
        if(map.containsKey(key)){
            ListNode node1 = map.get(key);
            putNodeFirst(node1);
            return node1.value;
        }else{
            return -1;
        }
    }

完整代码解答:

//先定义一个节点类
class ListNode{
    //它是一个双向链表
    int key;
    int value;
    ListNode front;
    ListNode next;
    public ListNode(int key,int value){
        this.key = key;
        this.value = value;
    }
}
class LRUCache {
    int capacity;
    //Key是数字,值为链表
    Map<Integer,ListNode> map = new HashMap<>();
    //设置1个链表的头和尾
    ListNode head = new ListNode(0,0);
    ListNode tail = new ListNode(0,0);
    public LRUCache(int capacity) {
      this.capacity = capacity;
      //设置双向链表的连接 
        head.next = tail;
        tail.front = head;
    }
     // 思路:
     // 先判断map中是否存在对应的key值,没有的话返回-1,有的话返回对应的value,然后将对应的节点放到首位
    public int get(int key) {
        if(map.containsKey(key)){
            ListNode node1 = map.get(key);
            putNodeFirst(node1);
            return node1.value;
        }else{
            return -1;
        }
    }
    
    public void put(int key, int value) {
        //先看该链表中有无当前的key,没有的话在添加之前要先确定容量
        if(!map.containsKey(key)){
            if(map.size() == capacity) deletLastNode();
            //先保存第一个节点即head的下一个节点
            ListNode temp = head.next;
            //先定义要新添加的节点
            ListNode newListNode = new ListNode(key,value);
            //head的下一个节点即为第一个节点,因为是双向链表因此需要2次连接
            head.next = newListNode;
            newListNode.front = head;
            //将temp连接到新的链表之后
            newListNode.next = temp;
            temp.front = newListNode;
            //再将新的节点加入map
            map.put(key,newListNode);
        }else{
            //如果map中有key的话,我们仅需要更改里面的value
              //先拿到对应key的节点
            ListNode list1 = map.get(key);
            list1.value = value;
            //因为我们做了1次修改,我们应该把修改的那个节点放在最前面
            putNodeFirst(list1);
        }
    }
    //删除最后一个节点
    private void deletLastNode(){
        //先找到到最后一个节点即tail的上一个节点
        ListNode lastNode = tail.front;
        //然后我们将倒数第2个节点与tail连接那么倒数第二个节点就成了最后1个节点了
        lastNode.front.next = tail;
        tail.front = lastNode.front;
        //将最后lastNode从map中移除
        map.remove(lastNode.key);
    }
    //把当前的节点放到链表首位
    private void putNodeFirst(ListNode node){
        //这里建议画图好理解
        node.front.next = node.next;
        node.next.front = node.front;
        //记录第一个节点
        ListNode temp = head.next;
        head.next = node;
        node.front = head;
        node.next = temp;
        temp.front = node;
    }
}

二叉树的中序遍历(94)

在这里插入图片描述
这道题是简单题,同时也是树这个数据结构最基础的题,我们首先需要理解什么是中序遍历,(左,根,右),同时题上要求我们用一个数组来进行存储,因此我们需要定义一个数组。

扩展: 链接: (前序遍历 + 中序遍历 +后序遍历)

完整代码解答:

class Solution {
    ArrayList<Integer> list = new ArrayList<>();
    public List<Integer> inorderTraversal(TreeNode root) {
        if(root != null){
            //先左子节点
            inorderTraversal(root.left);
            //根节点
            list.add(root.val);
            inorderTraversal(root.right);
        }
        return list;
    }
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

爱敲键盘的程序源

你的激励是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值