算法高频题目

LRUCache实现

思路:使用linkedHashMap。按照插入顺序的有序链表。 get 操作。cache不包含,返回-1。包含。我们需要当前key重新put。 /将 key 变为最近使用
put。如果包含。修改当前key值。然后将key变成最近使用。不包含。如果cacheSize大于当前最大size。我们需要溢出最近没有使用的。那就是链表的最后一个元素。链表的头部。

class LRUCache {
    int cap;
    LinkedHashMap<Integer, Integer> cache = new LinkedHashMap<>();
    public LRUCache(int capacity) { 
        this.cap = capacity;
    }
    
    public int get(int key) {
        if (!cache.containsKey(key)) {
            return -1;
        }
        // 将 key 变为最近使用
        makeRecently(key);
        return cache.get(key);
    }
    
    public void put(int key, int val) {
        if (cache.containsKey(key)) {
            // 修改 key 的值
            cache.put(key, val);
            // 将 key 变为最近使用
            makeRecently(key);
            return;
        }
        
        if (cache.size() >= this.cap) {
            // 链表头部就是最久未使用的 key
            int oldestKey = cache.keySet().iterator().next();
            cache.remove(oldestKey);
        }
        // 将新的 key 添加链表尾部
        cache.put(key, val);
    }
    
    private void makeRecently(int key) {
        int val = cache.get(key);
        // 删除 key,重新插入到队尾
        cache.remove(key);
        cache.put(key, val);
    }
}


public class LRUCache {
    //双链表  从左往右使用减少
    class DLinkedNode{
        int key, val;
        DLinkedNode pre;
        DLinkedNode next;
        public DLinkedNode(){}
        public DLinkedNode(int _key, int _val) {
            this.key = _key;
            this.val = _val;
        }
    }

    DLinkedNode tail, head;  //双链表头指针和尾部指针
    HashMap<Integer, DLinkedNode> cache = new HashMap<>();
    int size;    //当前元素数量
    int capacity;  //容量

    //1.初始化
    public LRUCache(int _capacity) {
        this.capacity = _capacity;
        this.size = 0;
        tail = new DLinkedNode();
        head = new DLinkedNode();
        head.next = tail;
        tail.pre = head;
    }
    
    public int get(int key) {
        DLinkedNode node = cache.get(key);

        if(node == null){
            //不存在key
            return -1;
        }else {
            //使用了该数,更新缓存
            deleteNode(node);
            addToHead(node);
        }
        return node.val;
    }
    
    public void put(int key, int value) {
        DLinkedNode node = cache.get(key);

        //如果存在,修改并更新缓存;
        if(node != null){
            node.val = value;
            deleteNode(node);
            addToHead(node);
        }else {
            //不存在
            //1.判断容量  达到最大容量,删除最近未使用节点(别忘了cache也要删)
            if(size == capacity){
                DLinkedNode removeNode = tail.pre;
                deleteNode(removeNode);
                cache.remove(removeNode.key);
                size--;
            }
            DLinkedNode newNode = new DLinkedNode(key, value);
            size++;
            addToHead(newNode);
            cache.put(key, newNode);
        }
    }

    //删除双链表中的节点
    public void deleteNode(DLinkedNode node){
        node.pre.next = node.next;
        node.next.pre = node.pre;
    }

    //加入到链表头部
    public void addToHead(DLinkedNode node){
        node.pre = head;
        node.next = head.next;
        head.next.pre = node;
        head.next = node;
    }  
}

/**
 * Your LRUCache object will be instantiated and called as such:
 * LRUCache obj = new LRUCache(capacity);
 * int param_1 = obj.get(key);
 * obj.put(key,value);
 */

技巧题目

169. 多数元素

给定一个大小为 n 的数组 nums ,返回其中的多数元素。多数元素是指在数组中出现次数 大于 ⌊ n/2 ⌋ 的元素。

你可以假设数组是非空的,并且给定的数组总是存在多数元素。

示例 1:

输入:nums = [3,2,3]
输出:3

示例 2:

输入:nums = [2,2,1,1,1,2,2]
输出:2

提示:

  • n == nums.length
  • 1 <= n <= 5 * 104
  • -109 <= nums[i] <= 109

**进阶:**尝试设计时间复杂度为 O(n)、空间复杂度为 O(1) 的算法解决此问题。

思路:正负抵消。相同的数量,count 加一。不同count–。如果coun==0;把当前的cardnum赋值为当前num。count重新初始化为1。z这样去做。最后那个cardNum一定是出现最多的。

class Solution {
    public int majorityElement(int[] nums) {
            int cardNum = nums[0];
            int count = 1;
            for(int  i=1;i<nums.length;i++){
                if(cardNum==nums[i]){
                    count++;
                }else{
                    count --;
                    if(count==0){
                        cardNum=  nums[i];
                        count=1;
                    }
                }
            }
           return cardNum;
    }
}

  • 7
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值