算法通关村——队栈的经典算法问题解析

1.用栈实现队列

LeetCode232:使用两个栈实现先入先出队列。队列应当支持一般队列支持的所有操作(push,pop,peek,empty)

思路:将一个栈当作输入栈,用于压入push插入的数据,另一个栈当作输出栈,用于pop和peek操作。每次pop和peek时,若输出栈为空则将输入栈的全部数据一次弹出并压入输出栈,这样输出栈从栈顶到栈底的顺序就是队列从队首往队尾的顺序。

class MyQueue:
    def __init__(self):
        self.stack_in = []
        self.stack_out = []

    def push(self, x):
        self.stack_in.append(x)

    def pop(self):
        if self.empty():
            return None
        if self.stack_out:
            return self.stack_out.pop()
        else:
            for i in range(len(self.stack_in)):
                self.stack_out.append(self.stack_in.pop())
            return self.stack_out.pop()

    def peek(self):
        ans = self.pop()    # 先弹出来再放入到栈里面去
        self.stack_out.append(ans)
        return ans

    def empty(self):
        return not (self.stack_in or self.stack_out)

if __name__ == '__main__':
    que = MyQueue()
    que.push(1)
    que.push(2)
    que.push(3)
    print(que.pop())
    print(que.empty())
    que.push(4)
    print(que.pop())

2.用队列实现栈

LeetCode225:使用两个队列实现一个后入先出的栈,并支持普通栈的全部四种操作(push,top,pop,empty)

思路:queue1用于存储栈内的元素,queue2作为入栈操作的辅助队列

入,此时栈操作时,首先将元素入队到queue2,然后将queue1的全部元素依次出队并入队到queue2,此时queue2的前端的元素即为新入栈的元素,再将queue1和queue2互换,则queue1的元素即为栈内的元素,queue1的前端和后端分别对应栈顶和栈底。

由于每次入栈操作都确保queue1的前端元素为栈顶元素,因此出栈操作和获得栈顶元素操作都可以简单实现。出栈操作只需要移除queue1的前端元素并返回即可,获得栈顶元素操作只需要获得queue1的前端元素并返回即可(不移除元素)。

由于queue1用于存储站内的元素,判断栈是否为空时,只需要判断queue1是否为空即可。

import collections

class MyStack():
    def __init__(self):
        self.queue1 = collections.deque()
        self.queue2 = collections.deque()

    def push(self, x):
        self.queue2.append(x)
        while self.queue1:
            self.queue2.append(self.queue1.popleft())
        self.queue1, self.queue2 = self.queue2, self.queue1

    def pop(self):
        return self.queue1.popleft()

    def top(self):
        return self.queue1[0]

    def empty(self):
        return not self.queue1

if __name__ == '__main__':
    stack = MyStack()
    stack.push(1)
    stack.push(2)
    stack.push(3)
    print(stack.pop())
    print(stack.top())
    print(stack.empty())

3.n数之和专题

3.1 两数之和

LeetCode1:给定一个整数数组nums和一个整数目标值target,请你在该数组中找出和为目标值target的那两个整数,并返回他们的数组下标。你可以假设每种输入只会对应一个答案。但是,数组中同一个元素在答案里不能重复出现。你可以按任意顺序返回答案。

class TwoSum:
    def twoSum(self, nums, target):
        n = len(nums)
        for i in range(n):
            for j in range(i+1, n):
                if nums[i] + nums[j] == target:
                    return [i, j]
        return []

    def twoSum1(self, nums, target):
        hashtable = {}
        for i, num in enumerate(nums):
            complement = target - num
            if complement in hashtable:
                return [hashtable[complement], i]
            hashtable[num] = i
        return []

if __name__ == '__main__':
    nums = [2, 7, 11, 15]
    target = 9
    twoSum = TwoSum()
    print(twoSum.twoSum(nums, target))

enumerate() 函数用于将一个可遍历的数据对象(如列表、元组或字符串)组合为一个索引序列,同时列出数据和数据下标,一般用在 for 循环当中。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值