【leetcode】【剑指】
BJFU_vth
这个作者很懒,什么都没留下…
展开
-
【leetcode】剑指 Offer 19. 正则表达式匹配
剑指 Offer 19. 正则表达式匹配 分析 这题给我恶心吐了。 两年前还能写出来优雅的dp,现在只能靠递归+ifelse大法勉强a掉的样子。 递归法 动态规划法 递归法 class Solution: def isMatch(self, s: str, p: str) -> bool: # pattern串用完了的情况 if len(p) == 0: return len(s) == 0 # 原串用完了的情况 if len原创 2022-01-05 18:45:59 · 264 阅读 · 0 评论 -
【leetcode】剑指 Offer 18. 删除链表的节点
剑指 Offer 18. 删除链表的节点 分析 这题就是删除链表中的结点问题。 为了对链表进行统一处理,我们可以弄一个空结点给他接上,然后用双指针法就能进行归一化处理了。 双指针法 # Definition for singly-linked list. # class ListNode: # def __init__(self, x): # self.val = x # self.next = None class Solution: def deleteN原创 2022-01-04 13:30:06 · 341 阅读 · 0 评论 -
【leetcode】剑指 Offer 17. 打印从1到最大的n位数
剑指 Offer 17. 打印从1到最大的n位数 分析 这个题,python直接暴力解就行。搞到一个最大值,然后用列表推导。 Python法 class Solution: def printNumbers(self, n: int) -> List[int]: maxs = 10**n return [i for i in range(1, maxs)] ...原创 2022-01-04 13:22:40 · 484 阅读 · 0 评论 -
【leetcode】剑指 Offer 16. 数值的整数次方
剑指 Offer 16. 数值的整数次方 分析 这题看似简单,用模拟法就能搞定,但用模拟法会超时。即用O(n)的办法会超时。 按照一个正统的CS学生来说,用动态规划法更符合从技术上解决问题。 快速幂法更数学一些。 模拟法 - O(n) 快速幂 - O(logn) 动态规划 - O(logn) 且题目中说的n是整数,即可能是负数,所以要处理一下。动态规划法其实就是记忆化递归法。 模拟法 class Solution: def myPow(self, x: float, n: int) ->原创 2022-01-04 13:15:53 · 196 阅读 · 0 评论 -
【leetcode】剑指 Offer 15. 二进制中1的个数
剑指 Offer 15. 二进制中1的个数 分析 这题能用很多种办法做出来,但没意义浪费时间。 除N取余法 python自带转换法 递归法 除N取余法 class Solution: def hammingWeight(self, n: int) -> int: return self.chu_N_quyu(n) def chu_N_quyu(self, n): res = 0 while n: res +=原创 2022-01-04 11:22:15 · 725 阅读 · 0 评论 -
【leetcode】剑指 Offer 14- II. 剪绳子 II
剑指 Offer 14- II. 剪绳子 II 分析 跟上个题目一样,继续dp就行。只不过题目要求模一个数。 动态规划法 class Solution: def cuttingRope(self, n: int) -> int: dp = [1 for i in range(n+1)] for i in range(3, n+1): border = i//2 for j in range(1, border+1)原创 2022-01-04 11:03:08 · 159 阅读 · 0 评论 -
【leetcode】剑指 Offer 14- I. 剪绳子
剑指 Offer 14- I. 剪绳子 这种无穷无尽的题,只能通过递归or动态规划的方式来解决。 有大佬用贪心法做出来的,但我理解不了,就不给自己找不自在了。用动态规划做出来也挺好的。 分析 这题,分析一下,意思是我们至少要剪掉一次绳子。咦,剪掉绳子,岂不是就是相当于缩小了问题规模?是的没错。说干就干。先搞一个转移方程。其中dp[i]是长度为i的绳子剪断后能得到的最大乘积。 dp[3] = dp[1] + dp[2] dp[4] = max(dp[1]+dp[3], dp[2]+dp[2]) dp[5] =原创 2022-01-03 16:20:20 · 218 阅读 · 0 评论 -
【leetcode】剑指 Offer 13. 机器人的运动范围
剑指 Offer 13. 机器人的运动范围 分析 这题和之前做过的12有不同之处。12是可以从每一个点遍历,而本题只能从原点遍历。 注意,这题的关键之处在于求和。把上下左右的和都加起来,这才是真正的和。 DFS法 class Solution: def movingCount(self, m: int, n: int, k: int) -> int: return self.dfs(m, n, 0, 0, k, 0, set()) def dfs(self, m, n,原创 2022-01-03 14:53:27 · 207 阅读 · 0 评论 -
【leetcode】剑指 Offer 12. 矩阵中的路径
剑指 Offer 12. 矩阵中的路径 分析 其实就是个深度优先搜索。可以设置一个visit数组,标记已经走过的路段。注意判断dfs的退出条件。 写递归就是这样,先想好退出条件,再不断的缩小问题规模,就这样。 深度优先搜索法 class Solution: def exist(self, board: List[List[str]], word: str) -> bool: if len(board) == 0 or len(board[0]) == 0: return wor原创 2022-01-01 23:12:30 · 293 阅读 · 0 评论 -
【leetcode】剑指 Offer 11. 旋转数组的最小数字
剑指 Offer 11. 旋转数组的最小数字 分析 题意说了是有序数组的旋转,那就代表可以用二分法。 遍历法 - 一次遍历,找出来右侧的值小于左侧值,即为最小值。如果找不到,那代表这是个非递减数组,直接返回第一个值即可。 二分法 - 根据二分法,找到最小值并返回即可。-二分法有限制。 在二分的时候,要想清楚对于哪些情况应该drop哪边。 二分的核心是drop。 具体题解看这里 遍历法 class Solution: def minArray(self, numbers: List[int])原创 2022-01-01 23:09:22 · 187 阅读 · 0 评论 -
【leetcode】剑指 Offer 10- II. 青蛙跳台阶问题
剑指 Offer 10- II. 青蛙跳台阶问题 分析 根据题意,在第0级时还没跳,应当设置为1. 在第一级台阶上,只能从第0级台阶跳1步过来。 第二级台阶上,可以从第0级跳2步过来,也可以从第1级跳一步过来。 故,第N级台阶可以从第N-1级台阶和第N-2级台阶过来。 设跳到第N级台阶有f(N)种方法,那f(N) = f(N-1) + f(N-2) 动态规划法 class Solution: def numWays(self, n: int) -> int: if n == 0原创 2021-12-24 15:12:27 · 630 阅读 · 0 评论 -
【leetcode】剑指 Offer 10- I. 斐波那契数列
剑指 Offer 10- I. 斐波那契数列 分析 斐波那契数列。我有100种办法可以解决(装个逼)。 递归法。 打表法(动态规划-记忆化搜索,咋叫都行)。 循环法(其实就是打表法的升级,因为打表法只关心前两个元素的值)。 递归法 class Solution: def fib(self, n: int) -> int: if n < 2: return n return self.fib(n-1) + self.fib(n-2原创 2021-12-24 10:19:39 · 421 阅读 · 0 评论 -
【leetcode】剑指 Offer 09. 用两个栈实现队列
剑指 Offer 09. 用两个栈实现队列 分析 两个栈当成一个队列玩。 栈是后入先出,队列是先入先出。 如果把一个栈的数据,倒入到另外一个空栈中,那就会形成一个队列。 为啥非得是空栈? 假如有A、B两个栈来模拟队列。 我们要保证入队操作只入A栈,然后在恰当的时机把A栈中的东西倒入B栈。 也就是说,B栈的栈顶要求始终是队头。如果B栈不为空时A栈就倒入了B栈,那么B栈的栈顶就不是队头了。 所以我们写代码要做到的就是控制A栈倒入B栈的时机是B栈为空时。 解决方案 class CQueue: def _原创 2021-12-24 09:59:41 · 597 阅读 · 0 评论 -
【leetcode】剑指 Offer 07. 重建二叉树
剑指 Offer 07. 重建二叉树 分析 给先序遍历和中序遍历,建树。 先序遍历是:根-左-右。 中序遍历是:左-根-右。 所以根据先序遍历可以确认根的位置。根据根的值,可以确定中序遍历左子树的范围。根据左子树的范围可以确定先序遍历左子树的范围。 根据以上可以得到右子树的范围。 然后递归的建立左子树和右子树即可。 记住,涉及到树,递归就对了! 递归法 class Solution: def buildTree(self, preorder, inorder): if len(pr原创 2021-12-23 20:20:37 · 210 阅读 · 0 评论 -
【leetcode】剑指 Offer 06. 从尾到头打印链表
剑指 Offer 06. 从尾到头打印链表 分析 链表只能顺序访问。所以可以遍历链表,把遇到的元素都放到一个list里,然后翻转这个list。 或者是用递归的方式做到从后往前访问。 所以本题的解决方式: 翻转列表法. 时间复杂度:O(n), 空间复杂度:O(1) 递归法. 时间复杂度:O(n), 空间复杂度: O(1) 翻转列表法 # Definition for singly-linked list. # class ListNode: # def __init__(self, x): #原创 2021-12-23 14:11:13 · 175 阅读 · 0 评论 -
【leetcode】剑指 Offer 05. 替换空格
剑指 Offer 05. 替换空格 分析 这题好那啥 先说两种办法吧。 用内部API。 遍历字符串,碰到空格就拼接。(有性能问题,会有大量的字符串拼接操作) 把字符串变成数组,遍历数组,再join起来。(比2性能好一些) 内部API class Solution: def replaceSpace(self, s: str) -> str: return s.replace(' ', '%20') 遍历字符串法 class Solution: def replac原创 2021-12-23 11:50:27 · 631 阅读 · 0 评论 -
【leetcode】剑指 Offer 04. 二维数组中的查找
传送门 分析 这题分析题意,首先是看到n*m的数组,每行每列都是递增的。所以这题肯定不能暴力的找,很可能会超时。 有序,首先想到二分。先做两次二分,找到要查找的数组范围(即最小值小于等于目标值,最大值大于等于目标值的数组)。再对范围中每一个数组做二分。 这题根据矩阵特点,还可以从左下或者右上开始查找。 以右上为例,我们可以保证目标值小于当前值时,只能向左一格搜索(因为向下的话,当前值肯定更大,因为是递增的)。目标值大于当前值时,只能向下搜索(因为向左的话,肯定越来越小)。 从左下开始搜索同理。 其实说起来,原创 2021-12-23 11:18:39 · 221 阅读 · 0 评论 -
【leetcode】剑指 Offer 03. 数组中重复的数字
剑指 Offer 03. 数组中重复的数字 分析 这是一个查找类问题,有很多种方法能够解决这个问题。 双重for循环法。 — 时间:O(n2) 空间:O(1) 集合法。 — 时间:O(n). 空间:O(n) 桶法。— 时间:O(n). 空间:O(n) 原地交换法。 — 时间:O(n). 空间:O(1). 排序法。 —时间O(nlogn). 空间: O(1). 双重for循环法 这是最傻瓜的方法。我怀疑它都过不了oj. class Solution: def findRepeatNumber(se原创 2021-12-20 13:33:15 · 77 阅读 · 0 评论