难度中等
运用你所掌握的数据结构,设计和实现一个 LRU (最近最少使用) 缓存机制 。
实现 LRUCache
类:
LRUCache(int capacity)
以正整数作为容量capacity
初始化 LRU 缓存int get(int key)
如果关键字key
存在于缓存中,则返回关键字的值,否则返回-1
。void put(int key, int value)
如果关键字已经存在,则变更其数据值;如果关键字不存在,则插入该组「关键字-值」。当缓存容量达到上限时,它应该在写入新数据之前删除最久未使用的数据值,从而为新的数据值留出空间。
进阶:你是否可以在 O(1)
时间复杂度内完成这两种操作?
示例:
输入 ["LRUCache", "put", "put", "get", "put", "get", "put", "get", "get", "get"] [[2], [1, 1], [2, 2], [1], [3, 3], [2], [4, 4], [1], [3], [4]] 输出 [null, null, null, 1, null, -1, null, -1, 3, 4] 解释 LRUCache lRUCache = new LRUCache(2); lRUCache.put(1, 1); // 缓存是 {1=1} lRUCache.put(2, 2); // 缓存是 {1=1, 2=2} lRUCache.get(1); // 返回 1 lRUCache.put(3, 3); // 该操作会使得关键字 2 作废,缓存是 {1=1, 3=3} lRUCache.get(2); // 返回 -1 (未找到) lRUCache.put(4, 4); // 该操作会使得关键字 1 作废,缓存是 {4=4, 3=3} lRUCache.get(1); // 返回 -1 (未找到) lRUCache.get(3); // 返回 3 lRUCache.get(4); // 返回 4
提示:
1 <= capacity <= 3000
0 <= key <= 3000
0 <= value <= 104
- 最多调用
3 * 104
次get
和put
class listnode{
public:
listnode (){};
listnode(int k, int value){
this->key=k;
this->val=value;
};
int key;
int val;
listnode* pre;
listnode* next;
};
unordered_map<int,listnode*> h;
int cap;
int size;
listnode* head;
listnode* tail;
LRUCache(int capacity) {
this->cap = capacity;
this->size=0;
this->head= new listnode(1,0);
this->tail= new listnode(1,0);
head->next=tail;
tail->pre=head;
}
int get(int key) {
if(h.count(key)){
listnode* node=h[key];
int value=node->val;
moveToHead(node,value);
return value;
}
else
return -1;
}
void put(int key, int value) {
if(h.count(key)){
listnode* node = h[key];
moveToHead(node,value);
}
else{
listnode* node = new listnode(key,value);
addNodeToHead(node);
h[key]=node;
size++;
if(size>cap){
removeTail();
size--;
}
}
}
void moveToHead(listnode *node,int value){
listnode* move=new listnode(node->key,value);
addNodeToHead(move);
node->pre->next=node->next;
node->next->pre=node->pre;
//delete(node);
node=NULL;
h[move->key]=move;
}
void addNodeToHead(listnode *node){
node->pre=head;
node->next=head->next;
head->next->pre=node;
head->next=node;
}
void removeTail(){
listnode * pre=tail->pre;
int k=pre->key;
listnode *tmp=pre->pre;
tmp->next=tail;
tail->pre=tmp;
//delete(pre);
pre=NULL;
h.erase(k);
}
难度中等
给你链表的头结点 head
,请将其按 升序 排列并返回 排序后的链表 。
进阶:
- 你可以在
O(n log n)
时间复杂度和常数级空间复杂度下,对链表进行排序吗?
示例 1:
输入:head = [4,2,1,3] 输出:[1,2,3,4]
示例 2:
输入:head = [-1,5,3,4,0] 输出:[-1,0,3,4,5]
示例 3:
输入:head = [] 输出:[]
提示:
- 链表中节点的数目在范围
[0, 5 * 104]
内 -105 <= Node.val <= 105
ListNode* sortList(ListNode* head) {
auto dummy = ListNode(-1);
dummy.next = head;
int len = 0;
auto cur = dummy.next;
while(cur){
++len;
cur = cur->next;
}
for(int i = 1;i < len;i*=2){
cur = &dummy;
for(int j = 0;j + i < len;j += i*2){
auto left = cur->next,right = cur->next;
for(int k = 0;k < i;++k)
right = right->next;
int l = 0,r = 0;
while(l < i && r < i && right){
if(left->val <= right->val){
cur->next = left;
cur = left;
left = left->next;
++l;
}
else{
cur->next = right;
cur = right;
right = right->next;
++r;
}
}
while(l < i){
cur->next = left;
cur = left;
left = left->next;
++l;
}
while(r < i && right){
cur->next = right;
cur = right;
right = right->next;
++r;
}
cur->next = right;
}
}
return dummy.next;
}
难度简单
设计一个支持 push
,pop
,top
操作,并能在常数时间内检索到最小元素的栈。
push(x)
—— 将元素 x 推入栈中。pop()
—— 删除栈顶的元素。top()
—— 获取栈顶元素。getMin()
—— 检索栈中的最小元素。
示例:
输入: ["MinStack","push","push","push","getMin","pop","top","getMin"] [[],[-2],[0],[-3],[],[],[],[]] 输出: [null,null,null,null,-3,null,0,-2] 解释: MinStack minStack = new MinStack(); minStack.push(-2); minStack.push(0); minStack.push(-3); minStack.getMin(); --> 返回 -3. minStack.pop(); minStack.top(); --> 返回 0. minStack.getMin(); --> 返回 -2.
提示:
pop
、top
和getMin
操作总是在 非空栈 上调用。
class MinStack {
public:
/** initialize your data structure here. */
vector<int> nums;
int min_index = 0;
MinStack() {
//nothing to do
}
void push(int x) {
nums.push_back(x);
if(x < nums[min_index]){ //update the index
min_index = nums.size() - 1;
}
}
void pop() {
if(nums.size() == 0) cout<<'Empty stack!';
else{
nums.pop_back();
if(min_index != nums.size()) ; //nothing to do
else{
int min = nums[0];
min_index = 0;
for(int i = 0; i < nums.size(); i++){
if(nums[i] < min) {
min_index = i;
min = nums[i];
}
}
}
}
}
int top() {
if(nums.size() == 0) return -1;
else return nums.back();
}
int getMin() {
if(nums.size() == 0) return -1;
else return nums[min_index];
}
};