数据结构算法刷题笔记(13)栈、队列的应用

class Solution:

    def isValid(self, s: str) -> bool:

        #利用栈的先入后出原理,当字符串中的字符和字典中的key值相同入栈,如果栈顶的元素在字典中对应的value和字符串当前指针不符,就退出。因为栈的pop操作,栈空报错,因此提前给栈输入一个值。

        dict_kuohao = {'(': ')', '{': '}', '[': ']','?':'?'}

        stack = ['?']

        for i in s:

            if i in dict_kuohao:

                stack.append(i)

            elif dict_kuohao[stack.pop()] != i:

                return False

        return len(stack) == 1#如果最后的栈只剩?,则括号匹配,否则就一定不匹配

 

class Solution:

    def minAddToMakeValid(self, s: str) -> int:

        need = 0    #记录右括号的插入量

        res = 0    #记录左括号的插入量

        for i in s:    #遍历字符串

            if i == '(':    #如果是左括号

                need += 1     #右括号需求+1

            if i == ')':     #碰到右括号时

                need -= 1     #给右括号需求-1

                if need == -1:    #如果右括号需求是-1

                    need = 0    # 让右括号需求归零

                    res += 1     #此时需要插入左括号

        return need + res     #返回左右括号的插入和

class Solution:

    def minInsertions(self, s: str) -> int:

        need = 0 #右括号的需求数

        res = 0 #括号的插入数,因为左括号必须在两个右括号之前,所以当需求数是奇数时,要在左括号前插入一个右括号,并把需求数减一

        for i in s:

            if i == '(':

                need += 2 #遇到左括号,右括号的需求+2

                if need % 2 == 1: #如果右括号的需求是奇数

                    need -= 1 #给需求数减一

                    res += 1 #插入一个右括号

            if i == ')':

                need -= 1

                if need == -1:

                    res += 1 #插入一个左括号

                    need = 1  

        return need + res   

 栈是一种先进后出的数据结构,下面解决单调栈解决的一类问题:下一个更大元素

python中对栈和队列的内置函数如下:

 一、单调栈模板

class Solution:

    def nextGreaterElements(self, nums: List[int]) -> List[int]:

        num = nums + nums  #把数组拼接到一块,这样不会出现超下标

        stack = []  #栈,存储当前倒着进来的元素

        res = [0]*len(num)

        i = len(num) - 1

        while i >= 0:

            while len(stack) != 0 and stack[-1] <= num[i]: #如果栈不空而且栈顶还比当前元素小,出栈

                stack.pop()

            res[i] = -1 if len(stack) == 0 else stack[-1] #上一个循环结束后,如果栈中仍有元素,说明该栈顶比当前元素大,写入res相应位置,如果栈空,则写入-1

            stack.append(num[i])  #入栈当前元素

            i -= 1

        return res[0:len(nums)]  #最后返回和nums相同长度的res即可

 

class Solution:

    def nextGreaterElement(self, nums1: List[int], nums2: List[int]) -> List[int]:

        res = dict(zip(nums2,[0]*len(nums2)))  #存储nums2中每个元素对应的下一个更大

        stack = []

        i = len(nums2) - 1

        ans = [] #答案数组

        while i >= 0:

            while len(stack) and stack[-1] <= nums2[i]:

                stack.pop()

            res[nums2[i]] = -1 if len(stack) == 0 else stack[-1]

            stack.append(nums2[i])

            i -= 1

        for i in nums1:

            ans.append(res[i]) #查表并插入答案中

        return ans

 

class Solution:

    def dailyTemperatures(self, temperatures: List[int]) -> List[int]:

        answer = []

        res = [0]*len(temperatures)

        i = len(temperatures) - 1

        stack = []

        while i >= 0:

            while len(stack) and temperatures[stack[-1]] <= temperatures[i]:

                stack.pop()

            res[i] = 0 if len(stack) == 0 else stack[-1] - i 

            stack.append(i)  #将索引压入栈

            i -= 1

        return res

 

class Solution:

    def maxSlidingWindow(self, nums: List[int], k: int) -> List[int]:

        import collections

        queue = collections.deque()

        res = [0]*(len(nums)-k+1)

        for i in range(len(nums)):

            while queue and nums[queue[-1]] <= nums[i]: #如果队尾的数据小于当前数据,弹出

                queue.pop() #右出,保证队尾一定是最大值

            queue.append(i) #右边进队

            if queue[0] <= i - k: #如果队头超出窗口边界了,左出

                queue.popleft()#左出

            if i - k >= -1: #绕过前k个值

                res[i-k+1] = nums[queue[0]] #把队尾最大值写入res中

        return res

该题目有三个要求:(1)去重,(2)顺序不变,(3)字典最小。

使用一个栈来存储遍历的数据,首先我们给字符串中出现的字符计数,然后遍历该字符串,每次遍历都给计数减一,如果该元素已经出现在栈中,就跳过,不操作。没有出现在栈中,我们要尽可能保证栈底是字典小的字符,所以,当元素小于栈顶时,并且后面还有该元素,就出栈该元素。

class Solution:

    def removeDuplicateLetters(self, s: str) -> str:

        count = [0]*256 #小写字母的ASCII码不会超过256

        for i in s:

            count[ord(i)] += 1 #ord(char)会将char的ASCII码返回

        import collections

        queue = collections.deque()

        for j in range(len(s)):

            count[ord(s[j])] -= 1 #每遍历一个字符就给相应的count减一

            if s[j] in queue: #如果该元素已经在栈里了,忽略

                continue

            while queue and queue[-1] >s[j] and count[ord(queue[-1])] != 0:

                queue.pop() #栈顶元素大于当前元素且该元素计数不为0,出栈

            queue.append(s[j]) #入栈

        ans = ''

        while queue:

            ans = ans + ans.join(queue.popleft()) #因为栈的底部是最小的,所以让底部先出

        return ans

 

class Solution:

    def smallestSubsequence(self, s: str) -> str:

        count = [0]*256

        for c in s:

            count[ord(c)] += 1

        import collections

        queue = collections.deque()

        ans = ''

        for i in range(len(s)):

            count[ord(s[i])] -= 1

            if s[i] in queue:

                continue

            while queue and queue[-1] > s[i] and count[ord(queue[-1])] != 0:

                queue.pop()

            queue.append(s[i])

        while queue:

            ans = ans + ans.join(queue.popleft())

        return ans

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值