博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
链表专题8 - leetcode148. Sort List/146. LRU Cache - Hard
阅读量:2217 次
发布时间:2019-05-07

本文共 3820 字,大约阅读时间需要 12 分钟。

题目描述

链表排序,要求时间复杂度O(nlogn),空间复杂度O(1)

例子

Example 1:

Input: 4->2->1->3

Output: 1->2->3->4

Example 2:

Input: -1->5->3->4->0

Output: -1->0->3->4->5

思想

联想几个时间复杂度O(nlogn)的排序:堆排序(麻烦),快排(要移位,还要交换),归并排序(找中点,可以用快慢指针找中点)

解法

# Definition for singly-linked list.# class ListNode(object):#     def __init__(self, x):#         self.val = x#         self.next = Noneclass Solution(object):    def sortList(self, head):        """        :type head: ListNode        :rtype: ListNode        """        if not head or not head.next:            return head        fast = slow = pre = head        while fast and fast.next:    # Mark: pre            pre = slow            slow = slow.next            fast = fast.next.next        pre.next = None                left = self.sortList(head)        right = self.sortList(slow)        return self.merge(left, right)            def merge(self, left, right):        dummy = ListNode(-1)        p = dummy        while left and right:            if left.val < right.val:                p.next = left                left = left.next            else:                p.next = right                right = right.next            p = p.next        if left:            p.next = left        else:            p.next = right        return dummy.next

题目描述

设计一种LRU的数据结构,支持下面两个操作:get和put。

get(key) - 如果key在缓存中,返回key对应的value(总是正数),否则返回-1
put(key, value) - 设置值;如果key不存在,插入值。当缓存达到容量时,它应该在插入新项前使最近最少使用的项无效。
最好O(1)的时间复杂度

如果一个数据长时间没有使用,且又有新的数据加入,那么应该将最长时间没有使用的数据去除

例子

LRUCache cache = new LRUCache( 2 /* capacity */ );

cache.put(1, 1);
cache.put(2, 2);
cache.get(1); // returns 1
cache.put(3, 3); // evicts key 2
cache.get(2); // returns -1 (not found)
cache.put(4, 4); // evicts key 1
cache.get(1); // returns -1 (not found)
cache.get(3); // returns 3
cache.get(4); // returns 4

思想

首先,涉及查询,考虑用字典来存储。
难点 - 如何找到哪个节点最久没被使用?
定义一个双向链表,尾部的节点最久没被使用。每次访问某节点时,删除该节点,并把该节点放在头部。

注意双向链表的head和tail没有数据。

解法

双向链表的插入和删除

class LRUCache(object):    class Node(object):        def __init__(self, key, value):            self.key = key            self.value = value            self.next, self.prev = None, None    def __init__(self, capacity):        """        :type capacity: int        """        self.capacity = capacity        self.size = 0        self.dic = {
} # self.dic[key] = Node(key, value) self.head, self.tail = self.Node(-1,-1) , self.Node(-1,-1) self.head.next, self.tail.prev = self.tail, self.head def removeNode(self, node): node.prev.next = node.next node.next.prev = node.prev node.prev, node.next = None, None def insertNode(self, node): node.prev = self.head node.next = self.head.next self.head.next.prev, self.head.next = node, node def get(self, key): """ :type key: int :rtype: int """ if key not in self.dic: return -1 else: node = self.dic[key] self.removeNode(node) self.insertNode(node) return node.value def put(self, key, value): """ :type key: int :type value: int :rtype: void """ if key in self.dic: node = self.dic[key] self.removeNode(node) self.insertNode(node) node.value = value else: # Remove the tailest node if self.size == self.capacity: remove = self.tail.prev self.removeNode(remove) del self.dic[remove.key] self.size -= 1 # Insert the headest node node = self.Node(key, value) self.insertNode(node) self.dic[key] = node self.size += 1 # Your LRUCache object will be instantiated and called as such:# obj = LRUCache(capacity)# param_1 = obj.get(key)# obj.put(key,value)

转载地址:http://vzkfb.baihongyu.com/

你可能感兴趣的文章
用ARIMA模型做需求预测
查看>>
推荐系统
查看>>
TensorFlow-11-策略网络
查看>>
浅谈 GBDT
查看>>
如何选择优化器 optimizer
查看>>
一文了解强化学习
查看>>
CART 分类与回归树
查看>>
seq2seq 的 keras 实现
查看>>
seq2seq 入门
查看>>
什么是 Dropout
查看>>
用 LSTM 做时间序列预测的一个小例子
查看>>
用 LSTM 来做一个分类小问题
查看>>
详解 LSTM
查看>>
按时间轴简述九大卷积神经网络
查看>>
详解循环神经网络(Recurrent Neural Network)
查看>>
为什么要用交叉验证
查看>>
用学习曲线 learning curve 来判别过拟合问题
查看>>
用验证曲线 validation curve 选择超参数
查看>>
用 Grid Search 对 SVM 进行调参
查看>>
用 Pipeline 将训练集参数重复应用到测试集
查看>>