两数之和+LUR

牛客题

1.两数之和

使用hashmap解决

    public int[] twoSum(int[] nums, int target) {
        Map<Integer, Integer> m = new HashMap<>();
        for (int i = 0; i < nums.length; i++) {
            if (m.get(target - nums[i]) != null) {
                return new int[]{m.get(target - nums[i])+1, i+1};
            }
            m.put(nums[i], i);
        }
        return new int[]{0, 0};
    }

思想:从数组中挑出一个数,判断map中是否有其需要的数
如果有,则返回结果
如果没有,将这个数放入map中
继续挑下一个数

设计LRU(Least Recently Used)

设计LRU(最近最少使用)缓存结构,该结构在构造时确定大小,假设大小为 k ,并有如下两个功能

  1. set(key, value):将记录(key, value)插入该结构
  2. get(key):返回key对应的value值

思路:
1.想到队列(先进先出)
but 如果使用get()方法,无法快速的从队列中提出相应的数组
2.数组(带索引,可通过判断大小决定先后,其次,可以通过给定的k值,决定数组的大小)
集合也可带索引(arraylist底层还是数组)
但是之后需要进行列表类元素的位置转换->so,选择链表可能更加合适
linkedlist<hashMap<Integer,Integer>>
java中有一个特别适合的类LinkedHashMap<>()
key是按照顺序存放的

import java.util.*;

public class Solution {
    /**
     * lru design
     * @param operators int整型二维数组 the ops
     * @param k int整型 the k
     * @return int整型一维数组
     */
public class Solution {
    public int[] LRU (int[][] operators, int k) {
        HashMap<Integer,Integer> dic = new HashMap();
        List<integer> list = new ArrayList<integer>();
        List<integer> res = new ArrayList<integer>();
        for(int i=0;i<operators.length;i++)
        {
            int[] temp = operators[i];
            if(temp[0]==1) //更新操作;
            {
                if(list.size()>=k)
                {
                    list.remove(0);
                }
                dic.put(temp[1],temp[2]);
                if(list.contains(temp[1]))
                {
                    list.remove(list.indexOf(temp[1]));
                    list.add(temp[1]);
                }
                else
                {
                    list.add(temp[1]);
                }
            }
            else
            {
                if(list.contains(temp[1]))
                {
                    res.add(dic.get(temp[1]));
                    list.remove(list.indexOf(temp[1]));
                    list.add(temp[1]);
                }
                else
                {
                    res.add(-1);
                }
            }
        }
        return res.stream().mapToInt(Integer::intValue)
                .toArray();
    }
}

2.较为常见的hashmap+双向链表

import java.util.*;
class LRUCache {
    class Node {
        int k, v;
        Node l, r;
        Node(int _k, int _v) {
            k = _k;
            v = _v;
        }
    }
    int n;
    Node head, tail;
    Map<Integer, Node> map;
    public LRUCache(int capacity) {
        n = capacity;
        map = new HashMap<>();
        head = new Node(-1, -1);
        tail = new Node(-1, -1);
        head.r = tail;
        tail.l = head;
    }

    public int get(int key) {
        if (map.containsKey(key)) {
            Node node = map.get(key);
            refresh(node);
            return node.v;
        } 
        return -1;
    }

    public void put(int key, int value) {
        Node node = null;
        if (map.containsKey(key)) {
            node = map.get(key);
            node.v = value;
        } else {
            if (map.size() == n) {
                Node del = tail.l;
                map.remove(del.k);
                delete(del);
            }
            node = new Node(key, value);
            map.put(key, node);
        }
        refresh(node);
    }

    // refresh 操作分两步:
    // 1. 先将当前节点从双向链表中删除(如果该节点本身存在于双向链表中的话)
    // 2. 将当前节点添加到双向链表头部
    void refresh(Node node) {
        delete(node);
        node.r = head.r;
        node.l = head;
        head.r.l = node;
        head.r = node;
    }

    // delete 操作:将当前节点从双向链表中移除
    // 由于我们预先建立 head 和 tail 两位哨兵,因此如果 node.l 不为空,则代表了 node 本身存在于双向链表(不是新节点)
    void delete(Node node) {
        if (node.l != null) {
            Node left = node.l;
            left.r = node.r;
            node.r.l = left;
        }
    }
}

public class Solution {
    /**
     * lru design
     * @param operators int整型二维数组 the ops
     * @param k int整型 the k
     * @return int整型一维数组
     */
    public int[] LRU (int[][] operators, int k) {
        List<Integer> list = new ArrayList<>();
        LRUCache lru = new LRUCache(k);
        for (int[] op : operators) {
            int type = op[0];
            if (type == 1) {
                // set(k,v) 操作
                lru.put(op[1], op[2]);
            } else {
                // get(k) 操作
                list.add(lru.get(op[1]));
            }
        } 
        int n = list.size();
        int[] ans = new int[n];
        for (int i = 0; i < n; i++) ans[i] = list.get(i);
        return ans;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值