前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Leetcode【227、468、848、1081】

Leetcode【227、468、848、1081】

作者头像
echobingo
发布2019-07-10 17:45:59
5810
发布2019-07-10 17:45:59
举报
问题描述:【Stack】227. Basic Calculator II
解题思路:

这道题是实现一个基本计算器,即给一个只包括 +、-、*、/、数字和空格的字符串,计算结果。

这道题很容易想到用栈来记录结果。根据“先乘除,后加减”的原则,没有遇到乘除法之前,数字和 +、- 都入栈。遇到乘除号,在栈中找第一个因子,并在字符串中往后找第二个因子,将两者相乘除的结果压入栈中。最后,栈中就只剩下加减法了。然后对栈从头遍历,从左到右计算加减法即可得到最终答案。

这道题代码虽然比较长,但写起来不难,注意字符串和数字之间的转化即可。

Python3 实现:
代码语言:javascript
复制
class Solution:
    def calculate(self, s: str) -> int:
        stack = []
        i = 0
        while i < len(s):
            if s[i] != ' ':
                stack.append(s[i])
                # 先做乘除法,并将结果压入栈
                if s[i] == '*' or s[i] == '/':
                    num1, num2, op = 0, 0, stack.pop()
                    # 从栈中计算第一个乘法或除法因子
                    cnt = 0
                    while stack and stack[-1].isdigit():
                        num1 += int(stack.pop()) * (10 ** cnt)
                        cnt += 1
                    # 计算第二个乘法或除法因子,往后遍历
                    j = i + 1
                    while j < len(s):
                        if s[j] != ' ':
                            if s[j].isdigit():
                                num2 = num2 * 10 + int(s[j])
                            else:
                                break
                        j += 1
                    # 将结果压入栈中
                    if op == '*':
                        stack.append(str(num1 * num2))
                    else:
                        stack.append(str(num1 // num2))
                    i = j
                    continue
            i += 1
        # 栈中只有加减法
        i, ans, op = 0, 0, ''
        while i < len(stack):
            if stack[i] == '+' or stack[i] == '-':
                op = stack[i]
            else:
                if op == '':
                    ans = ans * 10 + int(stack[i])
                else:
                    # 从栈中得到第二个加数或减数
                    j, num2 = i, 0
                    while j < len(stack):
                        if stack[j].isdigit():
                            num2 = num2 * 10 + int(stack[j])
                        else:
                            break
                        j += 1
                    # 结果累加或累减
                    if op == '+':
                        ans += num2
                    else:
                        ans -= num2
                    i = j
                    continue
            i += 1
        return ans  # 最终的结果

问题描述:【String】468. Validate IP Address
解题思路:

这道题给一个字符串,判断其是否是有效的 IPv4 地址或者是 IPv6 地址。

这题只要认真读题,没有任何难度。可以根据字符串中是否含有 "." 或者 ":" 来分为可疑 IPv4 和可疑 IPv6,然后写两个函数分别判断即可。对于每个函数,遇到非法的情况就返回 "Neither",那么剩下的就是合法的 IPv4 和 IPv6 地址了。

Python3 实现:
代码语言:javascript
复制
class Solution:
    def validIPAddress(self, IP: str) -> str:
        def validIPV4(IP):
            groups = IP.split(".")
            if len(groups) != 4:
                return "Neither"
            for group in groups:
                if len(group) > 1 and group[0] == '0':  # 不能包含前导0
                    return "Neither"
                if group.isdigit() == False:  # 空串和负数也包括在这种情况
                    return "Neither"
                if int(group) > 255:
                    return "Neither"
            return "IPv4"
                
        def validIPV6(IP):
            groups = IP.split(":")
            if len(groups) != 8:
                return "Neither"
            for group in groups:
                if len(group) == 0:
                    return "Neither"  # 防止::情况出现 
                if len(group) > 4:
                    return "Neither"
                for g in group:  # 含有其他字符
                    if g not in "0123456789abcdefABCDEF":
                        return "Neither"
            return "IPv6"
            
        if IP.find('.') != -1:
            return validIPV4(IP)
        elif IP.find(':') != -1:
            return validIPV6(IP)
        else:
            return "Neither"

问题描述:【String】848. Shifting Letters
解题思路:

这道题是给一个字符串 S 和数组 shifts,将 S 中前 i+1 个字母移位 shifts[i] 次,返回移位后的字符串。

观察所给的例子,shifts = [3,5,9],"abc" -> "rpl",其中 "a" 移动了 3+5+9 次,"b" 移动了 5+9 次,"c" 移动了 9 次。

因此,我们只需要重新构造 shifts,将其每一项 shift[i] 变成 shifts[i] 与后面项的累加值之和。然后,对于 S 中的每个字符,移动 shifts[i] 就是答案。时间复杂度为 O(n),空间复杂度为 O(1)。

注意:循环移动,写代码时要对总移动数进行 %26 操作,防止字符越界。

Python3 实现:
代码语言:javascript
复制
class Solution:
    def shiftingLetters(self, S: str, shifts: List[int]) -> str:
        for i in range(len(shifts)-2, -1, -1):
            shifts[i] += shifts[i+1]
        ans = ""
        for s, shift in zip(S, shifts):
            ans += chr(ord('a') + (ord(s) - ord('a') + shift) % 26)
        return ans

问题描述:【Stack】1081. Smallest Subsequence of Distinct Characters
解题思路:

这道题是返回字符串 text 中按字典序排列最小的子序列,该子序列包含 text 中所有不同字符一次。

此题可以使用栈来保存结果。如果字符单调递增,就依次入栈;否则就要看已经在栈中的字符将来还有没有可能再次出现,如果还会出现,就把栈中字符依次删去

以 text = cdadabcc 为例,算法过程如下:

这是一种贪心的思想,栈中总是维持最小的字典序,局部最优则全局最优。时间复杂度为 O(n),空间复杂度为 O(26) (最多保存26个小写字母)。

Python3 实现:
代码语言:javascript
复制
class Solution:
    def smallestSubsequence(self, text: str) -> str:
        dic = dict()  # 记录每个字符最后的位置
        for i in range(len(text)):
            dic[text[i]] = i
        stack = []
        for i in range(len(text)):
            if text[i] in stack:  # 已经在栈中出现过,跳过
                continue
            # 对于栈中每个大于text[i]的字符,如果之后还会出现,就弹出
            while stack and stack[-1] > text[i] and dic[stack[-1]] > i:
                stack.pop()
            stack.append(text[i])  # 判断完成后,将当前字符入栈
        return "".join(stack)
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2019.07.08 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 问题描述:【Stack】227. Basic Calculator II
  • 解题思路:
  • Python3 实现:
  • 问题描述:【String】468. Validate IP Address
  • 解题思路:
  • Python3 实现:
  • 问题描述:【String】848. Shifting Letters
  • 解题思路:
  • Python3 实现:
  • 问题描述:【Stack】1081. Smallest Subsequence of Distinct Characters
  • 解题思路:
  • Python3 实现:
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档