leetcode练习题第二次训练

1.0155. 最小栈

1.1 题目大意

要求:设计一个「栈」。实现 push ,pop ,top ,getMin 操作,其中 getMin 要求能在常数时间内实现。

说明

  • −231≤𝑣𝑎𝑙≤231−1。
  • poptop 和 getMin 操作总是在非空栈上调用
  • pushpoptop 和 getMin 最多被调用 3∗104 次。

运行:

class MinStack:
 
    def __init__(self):
        """
        initialize your data structure here.
        """
        self.stack_=[]
        self.min_stack=[]
    def push(self, x):
        self.stack_.append(x)
        if(len(self.min_stack)==0):
            self.min_stack.append(x)
        elif(x<=self.min_stack[-1]):
            self.min_stack.append(x)
    def pop(self):
        if self.stack_[-1]==self.min_stack[-1]:
            self.min_stack.pop()
        self.stack_.pop()
    def top(self):
        return self.stack_[-1]
    def getMin(self):
        return self.min_stack[-1]
 
 
# Your MinStack object will be instantiated and called as such:
# obj = MinStack()
# obj.push(x)
# obj.pop()
# param_3 = obj.top()
# param_4 = obj.getMin()

2.0020. 有效的括号

2.1 题目大意

描述:给定一个只包括 '('')''{''}''['']' 的字符串 s 。

要求:判断字符串 s 是否有效(即括号是否匹配)。

说明

  • 有效字符串需满足:
    1. 左括号必须用相同类型的右括号闭合。
    2. 左括号必须以正确的顺序闭合。

运行:

class Solution:
    def isValid(self, s):
        """
        :type s: str
        :rtype: bool
        """
        stack=[]                            #设置一个列表,把该列表当做栈来使用即可。
        dic={')':'(','}':'{',']':'['}       #使用字典存储括号,并且右括号为key,左括号为value
        for char in s:
            if char in dic.values():        #左括号就入栈
                stack.append(char)
            elif char in dic.keys():        #有右括号的话就进行比较,
                if stack==[] or dic[char] != stack.pop():
                    return False
            else:
                return False                #不再字典中的输入直接输出错误

        return stack==[]                    #如果栈最后是空的,那么则符合要求,输出true,如果不是,则输出false,使用一个条件表达式

3.0227. 基本计算器 II

3.1 题目大意

描述:给定一个字符串表达式 s,表达式中所有整数为非负整数,运算符只有 +-*/,没有括号。

要求:实现一个基本计算器来计算并返回它的值。

说明

  • 1≤𝑠.𝑙𝑒𝑛𝑔𝑡ℎ≤3∗105。
  • s 由整数和算符(+-*/)组成,中间由一些空格隔开。
  • s 表示一个有效表达式。
  • 表达式中的所有整数都是非负整数,且在范围 [0,231−1] 内。
  • 题目数据保证答案是一个 32-bit 整数。

示例

输入:s = "3+2*2"
输出:7


输入:s = " 3/2 "
输出:1

运行:

class Solution(object):
    def calculate(self, s):
        """
        :type s: str
        :rtype: int
        """
        s = s.replace(" ", "")
        stack = []
        operation = []
        
        i = 0
        while i < len(s): #分离数字和运算符
            if s[i].isdigit():
                cur = int(s[i])
                while i + 1 < len(s) and s[i + 1].isdigit():
                    cur = cur * 10 + int(s[i + 1])
                    i += 1
                stack.append(cur)
            else:
                operation.append(s[i])
            i += 1
        print stack, operation
        
        i = 0
        while i < len(operation): #处理乘除法
            op = operation[i]
            if op == "*":
                stack[i] = stack[i] * stack[i + 1]
                stack = stack[:i + 1] + stack[i + 2:]
                operation = operation[:i] + operation[i + 1:]
            elif op == "/":
                stack[i] = stack[i] // stack[i + 1]
                stack = stack[:i + 1] + stack[i + 2:]
                operation = operation[:i] + operation[i + 1:]
            else:
                i += 1
            # print stack, operation
            
        res = stack[0]
        for i in range(len(operation)): #计算加减法
            op = operation[i]
            if op == "+":
                res += stack[i + 1]
            elif op == "-":
                res -= stack[i + 1]
        return res
        

1.0150. 逆波兰表达式求值

1.1 题目大意

描述:给定一个字符串数组 tokens,表示「逆波兰表达式」。

要求:求解表达式的值。

说明

  • 逆波兰表达式:也称为后缀表达式。

    • 中缀表达式 ( 1 + 2 ) * ( 3 + 4 ) ,对应的逆波兰表达式为  ( ( 1 2 + ) ( 3 4 + ) * ) 。
  • 1≤𝑡𝑜𝑘𝑒𝑛𝑠.𝑙𝑒𝑛𝑔𝑡ℎ≤104。
  • tokens[i] 是一个算符(+-* 或 /),或是在范围 [−200,200] 内的一个整数。

示例

输入:tokens = ["4","13","5","/","+"]
输出:6
解释:该算式转化为常见的中缀算术表达式为:(4 + (13 / 5)) = 6


输入:tokens = ["10","6","9","3","+","-11","*","/","*","17","+","5","+"]
输出:22
解释:该算式转化为常见的中缀算术表达式为:
  ((10 * (6 / ((9 + 3) * -11))) + 17) + 5
= ((10 * (6 / (12 * -11))) + 17) + 5
= ((10 * (6 / -132)) + 17) + 5
= ((10 * 0) + 17) + 5
= (0 + 17) + 5
= 17 + 5
= 22

运行:

class Solution(object):
    def evalRPN(self, tokens):
        """
        :type tokens: List[str]
        :rtype: int
        """
        # 逆波兰表达式:是一种后缀表达式,所谓后缀就是指算符写在后面。
        # 两个优点 1 去掉括号后无歧义 2 适合栈运算
        stack = []
        for i in tokens:
            if  tokens and i not in {"+", "-", "*", "/"}:
                stack.append(i)
            else:
                x = stack.pop()
                y = stack.pop()
                if i == "+":
                    temp = int(y) + int(x)
                elif i == "-":
                    temp = int(y) - int(x)
                elif i == "*":
                    temp  = int(y) * int(x)
                # python的 b / a 会向下取整, 比如 -1 / 132 = -1。 
                #题目要求是取整数部分,那么负数的时候,实际应该是向上取整, 解决方法: (b / float(a))
                elif i == "/":
                    temp = (int(y) / float(x))
                stack.append(temp)
        return int(stack.pop())

2.0394. 字符串解码

2.1 题目大意

描述:给定一个经过编码的字符串 s

要求:返回 s 经过解码之后的字符串。

说明

  • 编码规则:k[encoded_string]encoded_string 为字符串,k 为整数。表示字符串 encoded_string 重复 k 次。
  • 1≤𝑠.𝑙𝑒𝑛𝑔𝑡ℎ≤30。
  • s 由小写英文字母、数字和方括号 [] 组成。
  • s 保证是一个有效的输入。
  • s 中所有整数的取值范围为 [1,300]。

示例

输入:s = "3[a]2[bc]"
输出:"aaabcbc"


输入:s = "3[a2[c]]"
输出:"accaccacc"

运行:

class Solution:
    def decodeString(self, s):
        res, stack, tmp_cnt = '', [], 0

        for c in s:
            if c == '[':  # 遇到 [ 进栈
                stack.append((tmp_cnt, res))
                tmp_cnt, res = 0, ''   # 重置为0和空,重新开始进入下一个 []
            elif c == ']':  # 出栈的情况
                cnt, last_res = stack.pop()
                res = last_res + cnt * res
            elif '0' <= c <= '9':  # 处理数字部分
                tmp_cnt = tmp_cnt * 10 + int(c)
            else:
                res += c
        return res



3.0946. 验证栈序列

3.1 题目大意

描述:给定两个整数序列 pushed 和 popped,每个序列中的值都不重复。

要求:如果第一个序列为空栈的压入顺序,而第二个序列 popped 为该栈的压出序列,则返回 True,否则返回 False

说明

  • 1≤𝑝𝑢𝑠ℎ𝑒𝑑.𝑙𝑒𝑛𝑔𝑡ℎ≤1000。
  • 0≤𝑝𝑢𝑠ℎ𝑒𝑑[𝑖]≤1000。
  • 𝑝𝑢𝑠ℎ𝑒𝑑 的所有元素互不相同。
  • 𝑝𝑜𝑝𝑝𝑒𝑑.𝑙𝑒𝑛𝑔𝑡ℎ==𝑝𝑢𝑠ℎ𝑒𝑑.𝑙𝑒𝑛𝑔𝑡ℎ。
  • 𝑝𝑜𝑝𝑝𝑒𝑑 是 𝑝𝑢𝑠ℎ𝑒𝑑 的一个排列。

示例

输入:pushed = [1,2,3,4,5], popped = [4,5,3,2,1]
输出:true
解释:我们可以按以下顺序执行:
push(1), push(2), push(3), push(4), pop() -> 4,
push(5), pop() -> 5, pop() -> 3, pop() -> 2, pop() -> 1


输入:pushed = [1,2,3,4,5], popped = [4,3,5,1,2]
输出:false
解释:1 不能在 2 之前弹出。

 运行:

class Solution:
    def validateStackSequences(self, pushed, popped):
        # 利用栈来模拟入栈和出栈操作
        stack = []

        # index 表示 popped 数组中元素的下标
        # 比如 popped 是 [4,5,3,2,1]
        # 那么第 0 个下标元素是 4 这个数字
        # 先去判断这个数字能否正常的出栈
        index = 0

        # 遍历 pushed 数组中的每个元素
        for item in pushed:

            # 在遍历 pushed 数组时,把当前遍历的元素加入到栈中
            stack.append(item)

            # 加入完之后,不断的执行以下的判断
            # 1、栈中是否有元素
            # 2、栈顶元素是否和 popped 当前下标的元素相同
            # 如果同时满足这两个条件
            # 说明这个元素可以满足要求,即可以在最初空栈上进行推入 push 和弹出 pop 操作

            while stack and stack[-1] == popped[index] :
                # 那么就把栈顶元素弹出
                stack.pop()

                # 同时 index++,观察 popped 下一个元素
                index += 1
        return len(stack) ==0

 

1.0496. 下一个更大元素 I

1.1 题目大意

描述:给定两个没有重复元素的数组 nums1 和 nums2 ,其中 nums1 是 nums2 的子集。

要求:找出 nums1 中每个元素在 nums2 中的下一个比其大的值。

说明

  • nums1 中数字 x 的下一个更大元素是指: x 在 nums2 中对应位置的右边的第一个比 x 大的元素。如果不存在,对应位置输出 -1
  • 1≤𝑛𝑢𝑚𝑠1.𝑙𝑒𝑛𝑔𝑡ℎ≤𝑛𝑢𝑚𝑠2.𝑙𝑒𝑛𝑔𝑡ℎ≤1000。
  • 0≤𝑛𝑢𝑚𝑠1[𝑖],𝑛𝑢𝑚𝑠2[𝑖]≤104。
  • 𝑛𝑢𝑚𝑠1 和 𝑛𝑢𝑚𝑠2 中所有整数互不相同。
  • 𝑛𝑢𝑚𝑠1 中的所有整数同样出现在 𝑛𝑢𝑚𝑠2 中。

  运行:

class Solution(object):
   def nextGreaterElement(self, nums1, nums2):
    # 生成下一个更大元素对应哈希表
    hashmap = {}
    stack = []
    for num in nums2:
        while stack:
            if stack[-1] < num:
                hashmap[stack.pop(-1)] = num
            else:
                break
        stack.append(num)
    for num in stack:
        hashmap[num] = -1

    # 返回结果
    return [hashmap[num] for num in nums1]

2.0739. 每日温度

2.1 题目大意

描述:给定一个列表 temperaturestemperatures[i] 表示第 i 天的气温。

要求:输出一个列表,列表上每个位置代表「如果要观测到更高的气温,至少需要等待的天数」。如果之后的气温不再升高,则用 0 来代替。

说明

  • 1≤𝑡𝑒𝑚𝑝𝑒𝑟𝑎𝑡𝑢𝑟𝑒𝑠.𝑙𝑒𝑛𝑔𝑡ℎ≤105。
  • 30≤𝑡𝑒𝑚𝑝𝑒𝑟𝑎𝑡𝑢𝑟𝑒𝑠[𝑖]≤100。

示例

输入: temperatures = [73,74,75,71,69,72,76,73]
输出: [1,1,4,2,1,1,0,0]


输入: temperatures = [30,40,50,60]
输出: [1,1,1,0]

   运行:

class Solution:
    def dailyTemperatures(self, temperatures):
        sta=[]
        ret=[0]*len(temperatures)
        i=0
        for t in temperatures: 
            while len(sta)>0 and i >0:
                if t >temperatures[sta[-1]]:
                    n=sta.pop()
                    ret[n]=i-n
                else:
                    break
            sta.append(i)
            i+=1
        return ret

3.0316. 去除重复字母

3.1 题目大意

描述:给定一个字符串 s

要求:去除字符串中重复的字母,使得每个字母只出现一次。需要保证 「返回结果的字典序最小(要求不能打乱其他字符的相对位置)」

说明

  • 1≤𝑠.𝑙𝑒𝑛𝑔𝑡ℎ≤104。
  • s 由小写英文字母组成。

示例

输入:s = "bcabc"
输出:"abc"


输入:s = "cbacdcbc"
输出:"acdb"

    运行:

class Solution(object):
    def removeDuplicateLetters(self, s):
        if not s:
            return ""
        count = Counter(s)
        pos = 0
        for i in range(len(s)):
            if s[i] < s[pos]:
                pos = i
            count[s[i]] -= 1
            if count[s[i]] == 0:
                break
        return s[pos] + self.removeDuplicateLetters(s[pos:].replace(s[pos], ""))

 

 

 

 

 

 

 

 

  • 22
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值