Leetcod面试经典150题刷题记录——栈篇

栈篇刷题记录

    • 1. 有效的括号
      • Python3
        • 写法1 —— 官方题解(不直观较难理解)
        • 写法2 —— Krahets(简洁易懂)
        • 写法3 —— 综合
    • 2. 简化路径
      • Python3
        • 写法1 —— 奇技淫巧
        • 写法2 —— 栈

堆和栈是有区别的,平常经常连起来用,都逐渐模糊了,连起来说堆栈,往往特指栈。

1. 有效的括号

有效的括号 - leetcode

题目描述:
给定一个只包括 ‘(’,‘)’,‘{’,‘}’,‘[’,‘]’ 的字符串 s ,判断字符串是否有效。
有效字符串需满足:
左括号必须用相同类型的右括号闭合。
左括号必须以正确的顺序闭合。
每个右括号都有一个对应的相同类型的左括号。

解题思路:
(1) 此字符串长度需为偶数,否则不是有效括号字符串
(2) 用一个栈结构变量stack存储左括号(,[,{,并在遇到右括号时,将栈内元素出栈进行比对,但凡有一次没比对上,即不是有效字符串
(3) 最后,若字符串遍历完成且堆栈为空,为有效字符串

Python3

写法1 —— 官方题解(不直观较难理解)
class Solution:
    def isValid(self, s: str) -> bool: # -> bool意思是指该函数要返回一个bool值,Python 3.5 引入的类型注解功能,不具有强制性,可以返回任意类型的值
        # 1.首先判断括号数量
        if len(s) % 2 == 1:
            return False
        
        # 括号匹配字典,key值都是右括号
        pairs_dic = {
            ")" : "(",
            "]" : "[",
            "}" : "{"
        }

        stack = list() # 空链表,append是往末尾插值,pop默认也是移除末尾的元素,list的这点性质不像队列
        for ch in s:
            if ch in pairs_dic: # 判断ch是否有出现在pairs里的key值中
                if not stack or stack[-1] != pairs_dic[ch]: # stack[-1]是末尾的元素
                    return False
                stack.pop() # 匹配上了,移除在list的末尾移除元素
            else:
                stack.append(ch) # stack继续存储左括号
        return not stack # stack是否非空,若stack空,not stack返回True,表明是有效的括号字符串

# 作者:力扣官方题解
# 链接:https://leetcode.cn/problems/valid-parentheses/
# 来源:力扣(LeetCode)
# 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
写法2 —— Krahets(简洁易懂)
class Solution:
    def isValid(self, s: str) -> bool:
        dic = {'{': '}',  '[': ']', '(': ')', '?': '?'}
        stack = ['?'] # 为防止stack.pop()报错
        for c in s:
            if c in dic: stack.append(c)
            elif dic[stack.pop()] != c: return False # 当stack为空(即只剩下?)且c为右括号时,可以正常提前返回false
        return len(stack) == 1
        
# 作者:Krahets
# 链接:https://leetcode.cn/problems/valid-parentheses/
# 来源:力扣(LeetCode)
# 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
写法3 —— 综合
class Solution:
    def isValid(self, s: str) -> bool:
        # 1.若长度为奇数,则不是有效括号字符串
        if len(s) % 2 == 1: return False

        dic = {'(':')', '[':']', '{':'}', '?':'?'}
        stack = ['?']
        for ch in s:
            if ch in dic: # 2.是左括号则入栈
                stack.append(ch)
            else:         # 3.是右括号或非法字符,则将stack的值出栈进行比对
                if(dic[stack.pop()] != ch):
                    return False
        
        return len(stack) == 1

2. 简化路径

简化路径 —— leetcode

题目描述:
给你一个字符串 path ,表示指向某一文件或目录的 Unix 风格 绝对路径 (以 ‘/’ 开头),请你将其转化为更加简洁的规范路径。
在 Unix 风格的文件系统中,一个点(.)表示当前目录本身;此外,两个点 (…) 表示将目录切换到上一级(指向父目录);两者都可以是复杂相对路径的组成部分。任意多个连续的斜杠(即,‘//’)都被视为单个斜杠 ‘/’ 。 对于此问题,任何其他格式的点(例如,‘…’)均被视为文件/目录名称。
请注意,返回的 规范路径 必须遵循下述格式:
始终以斜杠 ‘/’ 开头。
两个目录名之间必须只有一个斜杠 ‘/’ 。
最后一个目录名(如果存在)不能 以 ‘/’ 结尾。 此外,路径仅包含从根目录到目标文件或目录的路径上的目录(即,不含 ‘.’ 或 ‘…’)。
返回简化后得到的 规范路径 。
题目归纳:
(1) (.)表示当前目录本身,(…)表示父目录,其他格式的点(例如,‘…’)均被视为文件/目录名称
(2) 多个连续的斜杠(即,‘//’)被视为单个斜杠 ‘/’
(3) 规范路径以’/'开头
(4) 两个目录名之间必须只有一个斜杠 ‘/’ 。
(5) 最后一个目录名(如果存在)不能 以 ‘/’ 结尾。 此外,路径仅包含从根目录到目标文件或目录的路径上的目录(即,不含 ‘.’ 或 ‘…’)

解题思路:
leetcode官方题解
(1) 首先,将//替换为/
(1) 遇到正常的目录,就用一个栈结构变量stack存起来
(2) 遇到/.就丢弃;遇到/..,若stack非空,就将stack的内容出栈;
(3) 将stack里的内容的倒转即为简洁的规范路径
(1) 首先是分割路径字符串,将path分割成一个由若干字符串组成的列表,

Python3

写法1 —— 奇技淫巧

调用内置函数

class Solution:
    def simplifyPath(self, path: str) -> str:
        return os.path.realpath(path)
写法2 —— 栈
class Solution:
    def simplifyPath(self, path: str) -> str:
        names = path.split("/")
        stack = list()
        for name in names:            
            if name == "..":
                if stack:
                    stack.pop()
            elif name and name != ".": # ignore the "."
                stack.append(name)
                
        return "/" + "/".join(stack)

你可能感兴趣的:(Algorithm,面试,python,职场和发展)