• 不使用map和set实现LRU——那用List?


    遇到一道面试题,不使用map和set实现LRU,要求get的时间复杂度为O(logn),put的时间复杂度不超过O(n)。想到了用ArrayList来实现,保存有序的key。然而牵涉add节点,在保证有序的情况下通过插入排序在ArrayList中插入一个新节点,时间复杂度不能保证O(n),粗略写了一个代码,供大家提出一些建议。

    class LRUCache {
        class ListNode {
            int key;
            int val;
            ListNode next;
            ListNode pre;
            public ListNode(int key, int val) {
                this.key = key;
                this.val = val;
                next = null;
                pre = null;
            }
        }
    
        private int capacity;
        private List<ListNode> list;
        private int getId;
        private ListNode tail;
        private ListNode head;
    
        public LRUCache(int k) {
            capacity = k;
            list = new ArrayList<>();
            head = new ListNode(-1, -1);
            tail = new ListNode(-1, -1);
            head.next = tail;
            tail.pre = head;
        }
     // 二分查找
        public int search(int key) {
            int left = 0, right = list.size() - 1;
            while (left <= right) {
                int mid = left + (right - left) / 2;
                ListNode node = list.get(mid);
                if (node.key > key) {
                    right = mid - 1;
                } else if (node.key < key) {
                    left = mid + 1;
                } else {
                    return mid;
                }
            }
            return -1;
        }
    // get
        public int get(int key) {
            getId = search(key);
            if (getId == -1) {
                return getId;
            }
            ListNode node = list.get(getId);
            node.pre.next = node.next;
            node.next.pre = node.pre;
            addToTail(node);
            return node.val;
        }
    // put
        public void put(int key, int val) {
            if (get(key) != -1) {
                list.get(getId).val = val;
                return;
            }
            ListNode node = new ListNode(key, val);
            addToTail(node);
            int i = 0;
            for (; i < list.size(); ++i) {
                if (list.get(i).key > key) {
                    list.add(i, node); // 这里牵涉到get和add两个操作,不能保证put的时间复杂度为O(n)
                    break;
                }
            }
            if (i == list.size()) list.add(node);
            if (list.size() > capacity) {
                getId = search(head.next.key);
                list.remove(getId);
                head.next = head.next.next;
                head.next.pre = head;
            }
        }
    
        public void addToTail(ListNode node) {
            node.pre = tail.pre;
            node.next = tail;
            node.pre.next = node;
            tail.pre = node;
        }
    }
    

      

  • 相关阅读:
    TPYBoard—MicroPython开发板免费试用!你最想抱走哪款?
    MicroPython最全资料集锦丨TPYBoard全系列教程之文档+例程源码
    MicroPython-GPRS教程之TPYBoardv702GPRS功能测试
    MicroPython-GPS教程之TPYBoardv702控制5110显示当前经纬度
    MicroPython之TPYBoard v102开发板控制OLED显示中文
    TPYBoard开发板ADC数模转换一: 初识ADC使用
    Set集合
    Collection接口和List集合
    在方法中抛出异常,使用throw关键字抛出异常
    捕捉异常和异常的使用原则
  • 原文地址:https://www.cnblogs.com/peony-jing/p/13681135.html
Copyright © 2020-2023  润新知