每日刷题

使用栈实现队列的下列操作:

push(x) – 将一个元素放入队列的尾部。
pop() – 从队列首部移除元素。
peek() – 返回队列首部的元素。
empty() – 返回队列是否为空。

示例:

MyQueue queue = new MyQueue();

queue.push(1);
queue.push(2);
queue.peek(); // 返回 1
queue.pop(); // 返回 1
queue.empty(); // 返回 false

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/implement-queue-using-stacks

思想
简单思想:由于栈是先进先出,队列是先进后出,那么只需要两个栈,即可将顺序理顺。

from collections import deque

class Stack:
    def __init__(self):
        self.item = deque()

    def pop(self):
        return self.item.pop()

    def push(self, val):
        return self.item.append(val)

    def top(self):
        return self.item[-1]

    def __len__(self):
        return len(self.item)

class MyQueue(object):

    def __init__(self):
        """
        Initialize your data structure here.
        """
        self.s1 = Stack()
        self.s2 = Stack()

    def push(self, x):
        """
        Push element x to the back of queue.
        :type x: int
        :rtype: None
        """
        self.s1.push(x)



    def pop(self):
        """
        Removes the element from in front of queue and returns that element.
        :rtype: int
        """
        if self.s2:
            return self.s2.pop()
        while self.s1:
            val = self.s1.pop()
            self.s2.push(val)
        return self.s2.pop()


    def peek(self):
        """
        Get the front element.
        :rtype: int
        """
        if self.s2:
            return self.s2.top()
        while self.s1:
            val = self.s1.pop()
            self.s2.push(val)
        return self.s2.top()


    def empty(self):
        """
        Returns whether the queue is empty.
        :rtype: bool
        """
        return len(self.s1) == 0 and len(self.s2) == 0

最小栈

设计一个支持 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.

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/min-stack

思想:用两个栈,其中一个栈正常进出元素,第二个栈在第一个栈进出元素的同时,比较第二个栈的栈顶元素和要进栈的元素大小区别,如果栈顶元素更小,则栈顶元素再次进栈。反之元素进栈。
在这里插入图片描述

from collections import deque
class Stack:
    def __init__(self):
        self.item = deque()
    def push(self,x):
        self.item.append(x)
    def pop(self):
        self.item.pop()
    def empty(self):
        return len(self.item) == 0
    def top(self):
        return self.item[-1]

class MinStack(object):

    def __init__(self):
        """
        initialize your data structure here.
        """
        self.s = Stack()
        self.M_s = Stack()


    def push(self, x):
        """
        :type x: int
        :rtype: None
        """
        if self.s.empty():
            self.s.push(x)
            self.M_s.push(x)
        else:
            top = self.M_s.top()
            if x < top:
                self.M_s.push(x)
            else:
                self.M_s.push(top)
            self.s.push(x)

    def pop(self):
        """
        :rtype: None
        """
        self.M_s.pop()
        return self.s.pop()

    def top(self):
        """
        :rtype: int
        """
        return self.s.top()


    def getMin(self):
        """
        :rtype: int
        """
        return self.M_s.top()

有效括号

给定一个只包括 ‘(’,’)’,’{’,’}’,’[’,’]’ 的字符串,判断字符串是否有效。

有效字符串需满足:

左括号必须用相同类型的右括号闭合。
左括号必须以正确的顺序闭合。
注意空字符串可被认为是有效字符串。

示例 1:

输入: “()”
输出: true
示例 2:

输入: “()[]{}”
输出: true

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/valid-parentheses

思想:用栈即可快速实现。若栈顶元素和入栈元素匹配,则将栈顶元素出栈。最后若栈为空,则匹配。若栈不为空,则不匹配

from collections import deque

class Stack():
    def __init__(self):
        self.item = deque()

    def __len__(self):
        return len(self.item)

    def pop(self):
        return self.item.pop()
    def push(self,x):
        return self.item.append(x)
    def empty(self):
        return len(self.item) == 0
    def top(self):
        return self.item[-1]

def get_pair(i):
    if i == ')':
        return '('
    if i == ']':
        return '['
    if i == '}':
        return '{'
class Solution:
    def isValid(self, s: str):
        if not s:
            return True
        stack = Stack()
        for i in s:
            if stack.empty():
                stack.push(i)
            else:
                top = stack.top()
                if get_pair(i) == top:
                    stack.pop()
                else:
                    stack.push(i)
        return stack.empty()

两个数组的交集II

给定两个数组,编写一个函数来计算它们的交集。

示例 1:

输入:nums1 = [1,2,2,1], nums2 = [2,2]
输出:[2,2]
示例 2:

输入:nums1 = [4,9,5], nums2 = [9,4,9,8,4]
输出:[4,9]

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/intersection-of-two-arrays-ii

思想:既然是找交集,首先就想到了通过哈希计数,但dict若没有初始值,就会报错,考虑到这个问题,采用defaultdict 来解决。不过一定要注意初始化defaultdict的初始值类型
在这里插入图片描述

from collections import defaultdict
class Solution:
    def intersect(self, nums1, nums2):
        dd = defaultdict(int) # 默认的val值为int
        for num in nums1:
            dd[num] += 1
        res = []
        for i in nums2:
            if dd[i] > 0:
                res.append(i)
                dd[i] -= 1
        return res

思想2:双指针。
首先对两个数组排序,然后通过快慢指针查找两个数组的子集。若 找到相同元素,则两个指针同时后移,若 第一个数组的当前元素小于 第二个数组的当前元素,则第一个数组后移。若第一个数组的当前元素大于第二个数组的当前元素。第二个数组后移。

class Solution(object):
    def intersect(self, nums1, nums2):
        """
        :type nums1: List[int]
        :type nums2: List[int]
        :rtype: List[int]
        """
        nums1 = sorted(nums1)
        nums2 = sorted(nums2)
        r = []
        i, j = 0, 0
        while i < (len(nums1)) and j < len(nums2):
            if nums1[i] < nums2[j]:
                i += 1
            elif nums1[i] == nums2[j]:
                r.append(nums1[i])
                i += 1
                j += 1
            else:
                j += 1
        return r

运用你所掌握的数据结构,设计和实现一个 LRU (最近最少使用) 缓存机制。它应该支持以下操作: 获取数据 get 和 写入数据 put 。

获取数据 get(key) - 如果关键字 (key) 存在于缓存中,则获取关键字的值(总是正数),否则返回 -1。
写入数据 put(key, value) - 如果关键字已经存在,则变更其数据值;如果关键字不存在,则插入该组「关键字/值」。当缓存容量达到上限时,它应该在写入新数据之前删除最久未使用的数据值,从而为新的数据值留出空间。

进阶:

你是否可以在 O(1) 时间复杂度内完成这两种操作?

示例:

LRUCache cache = new LRUCache( 2 /* 缓存容量 */ );

cache.put(1, 1);
cache.put(2, 2);
cache.get(1); // 返回 1
cache.put(3, 3); // 该操作会使得关键字 2 作废
cache.get(2); // 返回 -1 (未找到)
cache.put(4, 4); // 该操作会使得关键字 1 作废
cache.get(1); // 返回 -1 (未找到)
cache.get(3); // 返回 3
cache.get(4); // 返回 4

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/lru-cache
整理一下:
在这里插入图片描述
难点有一下几个:
1、最右侧加入元素(数组 ,队列,链表)
2、最左侧删除元素(数组,队列,链表)
3、可以把最右侧元素后延(链表)
可以实现数据结构:dict + 循环双端链表
但是,好在python提供了一个有序字典OrderedDict
在这里插入图片描述
两个操作:
1、get
判断key是否在OrderedDict中,若在,返回对应val,同时通过move_to_end(key)将其移动到最后,若不在,返回-1
2、put
判断key值是否在OrderedDict中,若在,更新key对应的val,若不在将其存入OrderedDict。同时判断OrderedDict的长度,若>预设长度,则通过OrderedDict.popitem(last = False)函数,将最OrderedDict内最左侧元素移除。

from collections import OrderedDict

class LRUCache:

    def __init__(self, capacity: int):
        self.od = OrderedDict()
        self.cap = capacity

    def get(self, key: int) -> int:
        if key in self.od:
            val = self.od[key]
            self.od.move_to_end(key)
            return val
        else:
            return -1
    def put(self, key: int, value: int) -> None:
        if key in self.od:
            self.od[key] = value
        else:
            self.od[key] = value
            if len(self.od) > self.cap:
                self.od.popitem(last=False)
        self.od.move_to_end(key)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值