Python剑指offer打卡-36

Python剑指offer打卡-36

最长有效括号

题目类型:动态规划

题目难度:🌟🌟🌟🌟

  • 问题描述

    问题描述:
    给你一个只包含 '(' 和 ')' 的字符串,找出最长有效(格式正确且连续)括号子串的长度。
    
    示例:
    输入:s = ")()())"
    输出:4
    解释:最长有效括号子串是 "()()"
    
    解题方法:
    动态规划
    时间复杂度:O(N)
    空间复杂度:O(N)
    
    原题链接:https://leetcode-cn.com/problems/longest-valid-parentheses/
    相似题目:有效的括号、括号生成
    
  • 代码

    图解算法

    在这里插入图片描述

    class Solution:
        def longestValidParentheses(self, s: str) -> int:
            n = len(s)
            # 定义dp
            dp = [0] * n  # 到第i位置的最大括号
            res = 0
            # 转态转移
            for i in range(1, n):
                if s[i] == ")":
                    if s[i - 1] == "(":
                        # "()()()"
                        dp[i] = (dp[i - 2] if i >= 2 else 0) + 2
                    else:
                        # "()(())"
                        if i - dp[i - 1] >= 1 and s[i - dp[i - 1] - 1] == "(":
                            dp[i] = dp[i - 1] + (dp[i - dp[i - 1] - 2] if i - dp[i - 1] >= 2 else 0) + 2
    
                    res = max(dp[i], res)
            # 返回值
            return res
    

括号生成

题目类型:DFS

题目难度:🌟🌟🌟

  • 问题描述

    问题描述:
    数字 n 代表生成括号的对数,请你设计一个函数,用于能够生成所有可能的并且 有效的 括号组合。
    
    示例:
    输入:n = 3
    输出:["((()))","(()())","(())()","()(())","()()()"]
    
    解题方法:
    DFS
    时间复杂度:O()
    空间复杂度:O()
    
    原题链接:https://leetcode-cn.com/problems/generate-parentheses/
    
  • 代码

    图解算法

    在这里插入图片描述

    class Solution:
    
        def generateParenthsis(self, n: int):
            if n <= 0: return []
            res = []
    
            def dfs(paths, left, right):
                if left > n or right > left: return
                if len(paths) == n*2:
                    res.append(paths)
                    return
                dfs(paths + "(", left + 1, right)
                dfs(paths + ")", left, right + 1)
            dfs("", 0, 0)
    
            return res
    

平方数之和

题目类型:二分法、双指针

题目难度:🌟🌟

  • 问题描述

    问题描述:
    给定一个非负整数 c ,你要判断是否存在两个整数 a 和 b,使得 a2 + b2 = c 。
    
    示例:
    输入:c = 5
    输出:true
    解释:1 * 1 + 2 * 2 = 5
    
    解题方法:
    双指针
    时间复杂度:O(sqrt(c))
    空间复杂度:O(1)
    
    原题链接:https://leetcode-cn.com/problems/sum-of-square-numbers/
    相似题目:x的平法根、二维数据查找
    
  • 代码

    class Solution:
        def judgeSquareSum(self, c: int) -> bool:
    
            low, high = 0, int(c**0.5)
            while low <= high:
                sum_of = low*low + high * high
                if sum_of < c:
                    low += 1
                elif sum_of > c:
                    high -= 1
                else:
                    return True
            return False
    

轮转数组

题目类型:字符串

题目难度:🌟🌟

  • 问题描述

    问题描述:
    给你一个数组,将数组中的元素向右轮转 k 个位置,其中 k 是非负数。
    (注意:使用O(1)的空间复杂度)
    示例:
    输入: nums = [1,2,3,4,5,6,7], k = 3
    输出: [5,6,7,1,2,3,4]
    解释:
    向右轮转 1 步: [7,1,2,3,4,5,6]
    向右轮转 2 步: [6,7,1,2,3,4,5]
    向右轮转 3 步: [5,6,7,1,2,3,4]
    
    解题方法:
    局部翻转排序算法
    时间复杂度:O(n)
    空间复杂度:O(1)
    
    原题链接:https://leetcode-cn.com/problems/rotate-array/
    
  • 代码

    图解算法

    在这里插入图片描述

    class Solution:
        def rotate(self, nums: List[int], k: int) -> None:
            """
            Do not return anything, modify nums in-place instead.
            """
    
            def reverse(i, j):
                while i < j:
                    nums[i], nums[j] = nums[j], nums[i]
                    i += 1
                    j -= 1
            n = len(nums)
            k %= n
            # 整体翻转
            reverse(0, n - 1)
            # 左半部分
            reverse(0, k - 1)
            # 有半部分
            reverse(k, n - 1)
    

阶乘后的零

题目类型:数学

题目难度:🌟🌟

  • 问题描述

    问题描述:
    给定一个整数 n ,返回 n! 结果中尾随零的数量。
    提示 n! = n * (n - 1) * (n - 2) * ... * 3 * 2 * 1
    
    解题方法:
    归纳总结
    1. 肯定不可能真去把 n! 的结果算出来,阶乘增长可是比指数增长都恐怖
    2. 两个数相乘结果末尾有 0,一定是因为两个数中有因子 2 和 5,因为 10 = 2 x 5
    3. 也就是说,问题转化为:n! 最多可以分解出多少个因子 2 和 5
    4. 举例来说,n = 25,那么 25! 最多可以分解出几个 2 和 5 相乘?这个主要取决于能分解出几个因子 5,因为每个
    偶数都能分解出因子 2,因子 2 肯定比因子 5 多得多
    5. 现在,问题转化为:n! 最多可以分解出多少个因子 5
    6. 假设 n = 125,来算一算 125! 的结果末尾有几个 0
    7. 125 / 5 = 25,这一步就是计算有多少个像 5,15,20,25 这些 5 的倍数,它们一共可以提供一个因子 5
    8. 像 25,50,75 这些 25 的倍数,可以提供两个因子 5,那么我们再计算出 125! 中有 125 / 25 = 5 个 25 的倍
    数,它们每人可以额外再提供一个因子 5
    9. 我们发现 125 = 5 x 5 x 5,像 125,250 这些 125 的倍数,可以提供 3 个因子 5,那么我们还得再计算出 125!
    中有 125 / 125 = 1 个 125 的倍数,它还可以额外再提供一个因子 5
    10.125! 最多可以分解出 25 + 5 + 1 = 31 个因子 5,也就是说阶乘结果的末尾有 31 个 0
    
    时间复杂度:O(N)
    空间复杂度:O(1)
    
    原题链接:https://leetcode-cn.com/problems/factorial-trailing-zeroes/
    
  • 代码

    class Solution:
        def trailingZeroes(self, n: int) -> int:
    
            zero_cnts = 0
    
            for i in range(5, n + 1, 5):
                current = i
                while current % 5 == 0:
                    zero_cnts += 1
                    current //= 5
    
            return zero_cnts
    
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值