恋上数据结构与算法三高频题笔记2

本文介绍了一种实现LRU缓存的方法,利用哈希表结合双向链表实现高效的时间复杂度为O(1)的操作,并展示了如何按螺旋顺序遍历矩阵。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1._146_LRU缓存

标签:哈希表、链表、双向链表

思路:时间复杂度要求为O(1),用哈希表解决。哈希表的value存储双向链表节点。在双向链表中,建立一个虚拟头节点,一个虚拟尾节点。对操作过的节点,每次都将节点添加到头节点的后面,双向链表的最后一个节点存储的就是最近未使用的。

代码:

public class _146_LRU缓存 {
    private Node first;
    private Node last;
    Map<Integer,Node> map;
    private int capacity;
    public _146_LRU缓存(int capacity) {
        map = new HashMap<>(capacity);
        this.capacity = capacity;
        first = new Node();
        last = new Node();
        first.next = last;
        last.prev = first;

    }

    public int get(int key) {
        Node node = map.get(key);
        if(node == null) return -1;

        removeNode(node);
        addAfterFirst(node);

        return node.value;

    }

    public void put(int key, int value) {
        Node node = map.get(key);
        if(node != null){
            node.value = value;
            removeNode(node);
            addAfterFirst(node);
        }else{// 新添加一个key-value
            if(map.size() == capacity){
                //淘汰最近最少使用的node,删除最后一个(注意也要从map中删除)
                map.remove(last.prev.key);
                removeNode(last.prev);
            }
            map.put(key,node = new Node(key,value));
            addAfterFirst(node);

        }

    }

    private void removeNode(Node node) {
        node.next.prev = node.prev;
        node.prev.next = node.next;
    }

    private void addAfterFirst(Node node) {
        node.next = first.next;
        first.next.prev = node;
        first.next = node;
        node.prev  = first;
    }

    private static class Node{
        public int key;
        public int value;
        public Node prev;
        public Node next;

        public Node(int key, int value) {
            this.key = key;
            this.value = value;
        }

        public Node() {
        }
    }

}

2._54_螺旋矩阵

标签:数组、矩阵

思路:将矩阵看成若干层,先输出最外层的元素,其次输出次外层的元素,直到输出最内层的元  素。

 代码:

    public List<Integer> spiralOrder(int[][] matrix) {
        List<Integer> list = new ArrayList<>();
        int top = 0;
        int bottom = matrix.length - 1;
        int left = 0;
        int right = matrix[0].length - 1;
        while(top <= bottom && left <= right){
//            从left top->right top
            for(int i = left;i <= right;i++){
                list.add(matrix[top][i]);
            }
            top++;

//            从right top->right bottom
            for(int i = top;i <= bottom;i++){
                list.add(matrix[i][right]);

            }
            right--;
            if(top > bottom || left > right){
                break;
            }
//            从right bottom ->left bottom
            for(int i = right;i >= left;i--){
                list.add(matrix[bottom][i]);
            }
            bottom--;

//            从left bottom到left top
            for(int i = bottom;i >= top;i--){
                list.add(matrix[i][left]);

            }
            left++;
        }
        return list;

    }

注意如果不在while循环中进行判断,在奇数行和偶数列会出问题。

3._7_整数反转

标签:数学

思路:

          ①取出整数的每一位

          123 -> 321 = 3 * 100 + 2*10 +1

          如果将最后的结果存储为int类型,当溢出时,会计算错误。应该借助更大类型来判断溢出情况。

代码:

    public int reverse(int x) {
        long res = 0;

        while (x != 0) {
            res = res * 10 + x % 10;
            if(res > Integer.MAX_VALUE){
                return 0;
            }
            if(res < Integer.MIN_VALUE){
                return 0;
            }

            x /= 10;

        }
        return (int)res;

    }

        ②公式法

        判断计算出来的结果是否能正确的通过倒推法计算,如果数值相等,则计算正确;如果不相等,表示有溢出。

    public int reverse(int x){
        int res = 0;
        while(x != 0){
            int prevRes = res;
            res = prevRes * 10 + x % 10;
            if((res - x % 10) / 10 != prevRes) return 0;
            x /= 10;
        }
        return res;
    }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值