diff --git a/README.md b/README.md index 2fa61d3..8261f4d 100644 --- a/README.md +++ b/README.md @@ -1,9 +1,9 @@ -# Leetcode Python 不完全解答指南~ +# Leetcode Python解答 -答案进度:407 以Easy,Medium为主少量Hard +答案进度:408 以Easy,Medium为主少量Hard 子Folder:每道题是单独md文件 .md: 该分类下所有答案拼接的文档 -scripts/ : Leetcode 原题解答 +scripts/ : Leetcode 原题解答,pycharm Leetcode插件py文件,设为执行目录后可以直接测试 diff --git "a/script/[1035]\344\270\215\347\233\270\344\272\244\347\232\204\347\272\277.py" "b/script/[1035]\344\270\215\347\233\270\344\272\244\347\232\204\347\272\277.py" new file mode 100644 index 0000000..b5adade --- /dev/null +++ "b/script/[1035]\344\270\215\347\233\270\344\272\244\347\232\204\347\272\277.py" @@ -0,0 +1,70 @@ +# 在两条独立的水平线上按给定的顺序写下 nums1 和 nums2 中的整数。 +# +# 现在,可以绘制一些连接两个数字 nums1[i] 和 nums2[j] 的直线,这些直线需要同时满足满足: +# +# +# nums1[i] == nums2[j] +# 且绘制的直线不与任何其他连线(非水平线)相交。 +# +# +# 请注意,连线即使在端点也不能相交:每个数字只能属于一条连线。 +# +# 以这种方法绘制线条,并返回可以绘制的最大连线数。 +# +# +# +# 示例 1: +# +# +# 输入:nums1 = [1,4,2], nums2 = [1,2,4] +# 输出:2 +# 解释:可以画出两条不交叉的线,如上图所示。 +# 但无法画出第三条不相交的直线,因为从 nums1[1]=4 到 nums2[2]=4 的直线将与从 nums1[2]=2 到 nums2[1]=2 的直线相 +# 交。 +# +# +# +# 示例 2: +# +# +# 输入:nums1 = [2,5,1,2,5], nums2 = [10,5,2,1,5,2] +# 输出:3 +# +# +# +# 示例 3: +# +# +# 输入:nums1 = [1,3,7,1,7,5], nums2 = [1,9,2,5,1] +# 输出:2 +# +# +# +# +# +# 提示: +# +# +# 1 <= nums1.length, nums2.length <= 500 +# 1 <= nums1[i], nums2[j] <= 2000 +# +# +# +# Related Topics 数组 动态规划 +# 👍 346 👎 0 + + +# leetcode submit region begin(Prohibit modification and deletion) +class Solution: + def maxUncrossedLines(self, nums1: List[int], nums2: List[int]) -> int: + l1 = len(nums1) + l2 = len(nums2) + dp = [[0] * (l2+1)for i in range(l1+1)] + for i in range(1,l1+1): + for j in range(1, l2+1): + if nums1[i-1]==nums2[j-1]: + dp[i][j] = dp[i-1][j-1]+1 + else: + dp[i][j] = max(dp[i][j-1],dp[i-1][j],dp[i-1][j-1]) + return dp[-1][-1] +# leetcode submit region end(Prohibit modification and deletion) diff --git "a/script/[1047]\345\210\240\351\231\244\345\255\227\347\254\246\344\270\262\344\270\255\347\232\204\346\211\200\346\234\211\347\233\270\351\202\273\351\207\215\345\244\215\351\241\271.py" "b/script/[1047]\345\210\240\351\231\244\345\255\227\347\254\246\344\270\262\344\270\255\347\232\204\346\211\200\346\234\211\347\233\270\351\202\273\351\207\215\345\244\215\351\241\271.py" new file mode 100644 index 0000000..b0d4b13 --- /dev/null +++ "b/script/[1047]\345\210\240\351\231\244\345\255\227\347\254\246\344\270\262\344\270\255\347\232\204\346\211\200\346\234\211\347\233\270\351\202\273\351\207\215\345\244\215\351\241\271.py" @@ -0,0 +1,40 @@ +# 给出由小写字母组成的字符串 S,重复项删除操作会选择两个相邻且相同的字母,并删除它们。 +# +# 在 S 上反复执行重复项删除操作,直到无法继续删除。 +# +# 在完成所有重复项删除操作后返回最终的字符串。答案保证唯一。 +# +# +# +# 示例: +# +# 输入:"abbaca" +# 输出:"ca" +# 解释: +# 例如,在 "abbaca" 中,我们可以删除 "bb" 由于两字母相邻且相同,这是此时唯一可以执行删除操作的重复项。之后我们得到字符串 "aaca",其中又 +# 只有 "aa" 可以执行重复项删除操作,所以最后的字符串为 "ca"。 +# +# +# +# +# 提示: +# +# +# 1 <= S.length <= 20000 +# S 仅由小写英文字母组成。 +# +# Related Topics 栈 字符串 +# 👍 410 👎 0 + + +# leetcode submit region begin(Prohibit modification and deletion) +class Solution: + def removeDuplicates(self, s: str) -> str: + stack = [] + for i in s: + if stack and stack[-1]==i: + stack.pop() + else: + stack.append(i) + return ''.join(stack) +# leetcode submit region end(Prohibit modification and deletion) diff --git "a/script/[1049]\346\234\200\345\220\216\344\270\200\345\235\227\347\237\263\345\244\264\347\232\204\351\207\215\351\207\217 II.py" "b/script/[1049]\346\234\200\345\220\216\344\270\200\345\235\227\347\237\263\345\244\264\347\232\204\351\207\215\351\207\217 II.py" new file mode 100644 index 0000000..871e4a2 --- /dev/null +++ "b/script/[1049]\346\234\200\345\220\216\344\270\200\345\235\227\347\237\263\345\244\264\347\232\204\351\207\215\351\207\217 II.py" @@ -0,0 +1,55 @@ +# 有一堆石头,用整数数组 stones 表示。其中 stones[i] 表示第 i 块石头的重量。 +# +# 每一回合,从中选出任意两块石头,然后将它们一起粉碎。假设石头的重量分别为 x 和 y,且 x <= y。那么粉碎的可能结果如下: +# +# +# 如果 x == y,那么两块石头都会被完全粉碎; +# 如果 x != y,那么重量为 x 的石头将会完全粉碎,而重量为 y 的石头新重量为 y-x。 +# +# +# 最后,最多只会剩下一块 石头。返回此石头 最小的可能重量 。如果没有石头剩下,就返回 0。 +# +# +# +# 示例 1: +# +# +# 输入:stones = [2,7,4,1,8,1] +# 输出:1 +# 解释: +# 组合 2 和 4,得到 2,所以数组转化为 [2,7,1,8,1], +# 组合 7 和 8,得到 1,所以数组转化为 [2,1,1,1], +# 组合 2 和 1,得到 1,所以数组转化为 [1,1,1], +# 组合 1 和 1,得到 0,所以数组转化为 [1],这就是最优值。 +# +# +# 示例 2: +# +# +# 输入:stones = [31,26,33,21,40] +# 输出:5 +# +# +# +# +# 提示: +# +# +# 1 <= stones.length <= 30 +# 1 <= stones[i] <= 100 +# +# Related Topics 数组 动态规划 +# 👍 499 👎 0 + + +# leetcode submit region begin(Prohibit modification and deletion) +class Solution: + def lastStoneWeightII(self, stones: List[int]) -> int: + total = sum(stones) + l = total//2 + dp = [0] * (l+1) + for s in stones: + for i in range(l, s-1, -1): + dp[i] = max(dp[i], dp[i-s]+s) + return total - 2* dp[-1] +# leetcode submit region end(Prohibit modification and deletion) diff --git "a/script/[1143]\346\234\200\351\225\277\345\205\254\345\205\261\345\255\220\345\272\217\345\210\227.py" "b/script/[1143]\346\234\200\351\225\277\345\205\254\345\205\261\345\255\220\345\272\217\345\210\227.py" new file mode 100644 index 0000000..1f3bc9b --- /dev/null +++ "b/script/[1143]\346\234\200\351\225\277\345\205\254\345\205\261\345\255\220\345\272\217\345\210\227.py" @@ -0,0 +1,62 @@ +# 给定两个字符串 text1 和 text2,返回这两个字符串的最长 公共子序列 的长度。如果不存在 公共子序列 ,返回 0 。 +# +# 一个字符串的 子序列 是指这样一个新的字符串:它是由原字符串在不改变字符的相对顺序的情况下删除某些字符(也可以不删除任何字符)后组成的新字符串。 +# +# +# 例如,"ace" 是 "abcde" 的子序列,但 "aec" 不是 "abcde" 的子序列。 +# +# +# 两个字符串的 公共子序列 是这两个字符串所共同拥有的子序列。 +# +# +# +# 示例 1: +# +# +# 输入:text1 = "abcde", text2 = "ace" +# 输出:3 +# 解释:最长公共子序列是 "ace" ,它的长度为 3 。 +# +# +# 示例 2: +# +# +# 输入:text1 = "abc", text2 = "abc" +# 输出:3 +# 解释:最长公共子序列是 "abc" ,它的长度为 3 。 +# +# +# 示例 3: +# +# +# 输入:text1 = "abc", text2 = "def" +# 输出:0 +# 解释:两个字符串没有公共子序列,返回 0 。 +# +# +# +# +# 提示: +# +# +# 1 <= text1.length, text2.length <= 1000 +# text1 和 text2 仅由小写英文字符组成。 +# +# Related Topics 字符串 动态规划 +# 👍 1065 👎 0 + + +# leetcode submit region begin(Prohibit modification and deletion) +class Solution: + def longestCommonSubsequence(self, text1: str, text2: str) -> int: + l1 = len(text1) + l2 = len(text2) + dp = [[0] * (l2+1)for i in range(l1+1)] + for i in range(1,l1+1): + for j in range(1, l2+1): + if text1[i-1]==text2[j-1]: + dp[i][j] = dp[i-1][j-1]+1 + else: + dp[i][j] = max(dp[i][j-1],dp[i-1][j],dp[i-1][j-1]) + return dp[-1][-1] +# leetcode submit region end(Prohibit modification and deletion) diff --git "a/script/[1155]\346\216\267\351\252\260\345\255\220\347\232\204N\347\247\215\346\226\271\346\263\225.py" "b/script/[1155]\346\216\267\351\252\260\345\255\220\347\232\204N\347\247\215\346\226\271\346\263\225.py" new file mode 100644 index 0000000..469fd94 --- /dev/null +++ "b/script/[1155]\346\216\267\351\252\260\345\255\220\347\232\204N\347\247\215\346\226\271\346\263\225.py" @@ -0,0 +1,60 @@ +# 这里有 n 个一样的骰子,每个骰子上都有 k 个面,分别标号为 1 到 k 。 +# +# 给定三个整数 n , k 和 target ,返回可能的方式(从总共 kn 种方式中)滚动骰子的数量,使正面朝上的数字之和等于 target 。 +# +# 答案可能很大,你需要对 109 + 7 取模 。 +# +# +# +# 示例 1: +# +# +# 输入:n = 1, k = 6, target = 3 +# 输出:1 +# 解释:你扔一个有6张脸的骰子。 +# 得到3的和只有一种方法。 +# +# +# 示例 2: +# +# +# 输入:n = 2, k = 6, target = 7 +# 输出:6 +# 解释:你扔两个骰子,每个骰子有6个面。 +# 得到7的和有6种方法1+6 2+5 3+4 4+3 5+2 6+1。 +# +# +# 示例 3: +# +# +# 输入:n = 30, k = 30, target = 500 +# 输出:222616187 +# 解释:返回的结果必须是对 109 + 7 取模。 +# +# +# +# 提示: +# +# +# 1 <= n, k <= 30 +# 1 <= target <= 1000 +# +# Related Topics 动态规划 +# 👍 140 👎 0 + + +# leetcode submit region begin(Prohibit modification and deletion) +class Solution: + def numRollsToTarget(self, n: int, k: int, target: int) -> int: + dp = [[0] * (target+1) for i in range(n+1)] + dp[0][0]=1 + for i in range(1,n+1): + for t in range(1, target+1): + for j in range(1, min(t,k)+1): + dp[i][t] += dp[i-1][t-j] + dp[i][t] %= 1000000007 + return dp[-1][-1] + + + +# leetcode submit region end(Prohibit modification and deletion) diff --git "a/script/[115]\344\270\215\345\220\214\347\232\204\345\255\220\345\272\217\345\210\227.py" "b/script/[115]\344\270\215\345\220\214\347\232\204\345\255\220\345\272\217\345\210\227.py" new file mode 100644 index 0000000..76f1679 --- /dev/null +++ "b/script/[115]\344\270\215\345\220\214\347\232\204\345\255\220\345\272\217\345\210\227.py" @@ -0,0 +1,61 @@ +# 给定一个字符串 s 和一个字符串 t ,计算在 s 的子序列中 t 出现的个数。 +# +# 字符串的一个 子序列 是指,通过删除一些(也可以不删除)字符且不干扰剩余字符相对位置所组成的新字符串。(例如,"ACE" 是 "ABCDE" 的一个子序列 +# ,而 "AEC" 不是) +# +# 题目数据保证答案符合 32 位带符号整数范围。 +# +# +# +# 示例 1: +# +# +# 输入:s = "rabbbit", t = "rabbit" +# 输出:3 +# 解释: +# 如下图所示, 有 3 种可以从 s 中得到 "rabbit" 的方案。 +# rabbbit +# rabbbit +# rabbbit +# +# 示例 2: +# +# +# 输入:s = "babgbag", t = "bag" +# 输出:5 +# 解释: +# 如下图所示, 有 5 种可以从 s 中得到 "bag" 的方案。 +# babgbag +# babgbag +# babgbag +# babgbag +# babgbag +# +# +# +# +# 提示: +# +# +# 0 <= s.length, t.length <= 1000 +# s 和 t 由英文字母组成 +# +# Related Topics 字符串 动态规划 +# 👍 823 👎 0 + + +# leetcode submit region begin(Prohibit modification and deletion) +class Solution: + def numDistinct(self, s: str, t: str) -> int: + ls = len(s) + lt = len(t) + dp = [[1] + [0] * lt for i in range(ls+1)] # t=''的时候出现1次 + # dp[i][j]是前i个s里面有几个前j个t字符= 前i-1个s有多少个j-1个t+ 前i-个s有多少个j个t + for i in range(1, ls+1): + for j in range(1, lt+1): + if s[i-1]==t[j-1]: + dp[i][j] = dp[i-1][j-1] + dp[i-1][j] + else: + dp[i][j] = dp[i-1][j] + return dp[-1][-1] +# leetcode submit region end(Prohibit modification and deletion) diff --git "a/script/[121]\344\271\260\345\215\226\350\202\241\347\245\250\347\232\204\346\234\200\344\275\263\346\227\266\346\234\272.py" "b/script/[121]\344\271\260\345\215\226\350\202\241\347\245\250\347\232\204\346\234\200\344\275\263\346\227\266\346\234\272.py" new file mode 100644 index 0000000..4dc10c3 --- /dev/null +++ "b/script/[121]\344\271\260\345\215\226\350\202\241\347\245\250\347\232\204\346\234\200\344\275\263\346\227\266\346\234\272.py" @@ -0,0 +1,54 @@ +# 给定一个数组 prices ,它的第 i 个元素 prices[i] 表示一支给定股票第 i 天的价格。 +# +# 你只能选择 某一天 买入这只股票,并选择在 未来的某一个不同的日子 卖出该股票。设计一个算法来计算你所能获取的最大利润。 +# +# 返回你可以从这笔交易中获取的最大利润。如果你不能获取任何利润,返回 0 。 +# +# +# +# 示例 1: +# +# +# 输入:[7,1,5,3,6,4] +# 输出:5 +# 解释:在第 2 天(股票价格 = 1)的时候买入,在第 5 天(股票价格 = 6)的时候卖出,最大利润 = 6-1 = 5 。 +# 注意利润不能是 7-1 = 6, 因为卖出价格需要大于买入价格;同时,你不能在买入前卖出股票。 +# +# +# 示例 2: +# +# +# 输入:prices = [7,6,4,3,1] +# 输出:0 +# 解释:在这种情况下, 没有交易完成, 所以最大利润为 0。 +# +# +# +# +# 提示: +# +# +# 1 <= prices.length <= 105 +# 0 <= prices[i] <= 104 +# +# Related Topics 数组 动态规划 +# 👍 2461 👎 0 + + +# leetcode submit region begin(Prohibit modification and deletion) +class Solution: + def maxProfit(self, prices: List[int]) -> int: + # buy = prices[0] + # profit = 0 + # for i in prices[1:]: + # profit = max(profit, i-buy) + # buy = min(buy,i) + # return profit + l = len(prices) + dp0 = [prices[0]] + [0] * (l-1) + dp1 = [0] * l + for i in range(1, l): + dp0[i] = min(dp0[i-1], prices[i]) + dp1[i] = max(dp1[i-1], prices[i]-dp0[i-1]) + return dp1[-1] +# leetcode submit region end(Prohibit modification and deletion) diff --git "a/script/[122]\344\271\260\345\215\226\350\202\241\347\245\250\347\232\204\346\234\200\344\275\263\346\227\266\346\234\272 II.py" "b/script/[122]\344\271\260\345\215\226\350\202\241\347\245\250\347\232\204\346\234\200\344\275\263\346\227\266\346\234\272 II.py" new file mode 100644 index 0000000..68f9164 --- /dev/null +++ "b/script/[122]\344\271\260\345\215\226\350\202\241\347\245\250\347\232\204\346\234\200\344\275\263\346\227\266\346\234\272 II.py" @@ -0,0 +1,52 @@ +# 给你一个整数数组 prices ,其中 prices[i] 表示某支股票第 i 天的价格。 +# +# 在每一天,你可以决定是否购买和/或出售股票。你在任何时候 最多 只能持有 一股 股票。你也可以先购买,然后在 同一天 出售。 +# +# 返回 你能获得的 最大 利润 。 +# +# +# +# 示例 1: +# +# +# 输入:prices = [7,1,5,3,6,4] +# 输出:7 +# 解释:在第 2 天(股票价格 = 1)的时候买入,在第 3 天(股票价格 = 5)的时候卖出, 这笔交易所能获得利润 = 5 - 1 = 4 。 +#   随后,在第 4 天(股票价格 = 3)的时候买入,在第 5 天(股票价格 = 6)的时候卖出, 这笔交易所能获得利润 = 6 - 3 = 3 。 +# 总利润为 4 + 3 = 7 。 +# +# 示例 2: +# +# +# 输入:prices = [1,2,3,4,5] +# 输出:4 +# 解释:在第 1 天(股票价格 = 1)的时候买入,在第 5 天 (股票价格 = 5)的时候卖出, 这笔交易所能获得利润 = 5 - 1 = 4 。 +#   总利润为 4 。 +# +# 示例 3: +# +# +# 输入:prices = [7,6,4,3,1] +# 输出:0 +# 解释:在这种情况下, 交易无法获得正利润,所以不参与交易可以获得最大利润,最大利润为 0 。 +# +# +# +# 提示: +# +# +# 1 <= prices.length <= 3 * 104 +# 0 <= prices[i] <= 104 +# +# Related Topics 贪心 数组 动态规划 +# 👍 1771 👎 0 + + +# leetcode submit region begin(Prohibit modification and deletion) +class Solution: + def maxProfit(self, prices: List[int]) -> int: + profit = 0 + for i in range(1, len(prices)): + profit += max(prices[i]-prices[i-1],0) + return profit +# leetcode submit region end(Prohibit modification and deletion) diff --git "a/script/[123]\344\271\260\345\215\226\350\202\241\347\245\250\347\232\204\346\234\200\344\275\263\346\227\266\346\234\272 III.py" "b/script/[123]\344\271\260\345\215\226\350\202\241\347\245\250\347\232\204\346\234\200\344\275\263\346\227\266\346\234\272 III.py" new file mode 100644 index 0000000..88cb5c3 --- /dev/null +++ "b/script/[123]\344\271\260\345\215\226\350\202\241\347\245\250\347\232\204\346\234\200\344\275\263\346\227\266\346\234\272 III.py" @@ -0,0 +1,67 @@ +# 给定一个数组,它的第 i 个元素是一支给定的股票在第 i 天的价格。 +# +# 设计一个算法来计算你所能获取的最大利润。你最多可以完成 两笔 交易。 +# +# 注意:你不能同时参与多笔交易(你必须在再次购买前出售掉之前的股票)。 +# +# +# +# 示例 1: +# +# +# 输入:prices = [3,3,5,0,0,3,1,4] +# 输出:6 +# 解释:在第 4 天(股票价格 = 0)的时候买入,在第 6 天(股票价格 = 3)的时候卖出,这笔交易所能获得利润 = 3-0 = 3 。 +#   随后,在第 7 天(股票价格 = 1)的时候买入,在第 8 天 (股票价格 = 4)的时候卖出,这笔交易所能获得利润 = 4-1 = 3 。 +# +# 示例 2: +# +# +# 输入:prices = [1,2,3,4,5] +# 输出:4 +# 解释:在第 1 天(股票价格 = 1)的时候买入,在第 5 天 (股票价格 = 5)的时候卖出, 这笔交易所能获得利润 = 5-1 = 4 。   +#   注意你不能在第 1 天和第 2 天接连购买股票,之后再将它们卖出。   +#   因为这样属于同时参与了多笔交易,你必须在再次购买前出售掉之前的股票。 +# +# +# 示例 3: +# +# +# 输入:prices = [7,6,4,3,1] +# 输出:0 +# 解释:在这个情况下, 没有交易完成, 所以最大利润为 0。 +# +# 示例 4: +# +# +# 输入:prices = [1] +# 输出:0 +# +# +# +# +# 提示: +# +# +# 1 <= prices.length <= 105 +# 0 <= prices[i] <= 105 +# +# Related Topics 数组 动态规划 +# 👍 1181 👎 0 + + +# leetcode submit region begin(Prohibit modification and deletion) +class Solution: + def maxProfit(self, prices: List[int]) -> int: + l = len(prices) + dp1 ,dp2, dp3, dp4 = [0] * l, [0] * l, [0] * l, [0] * l + dp1[0]=-prices[0] + dp3[0]=-prices[0] + for i in range(1,l): + dp1[i] = max(dp1[i-1], -prices[i]) + dp2[i] = max(dp2[i-1], prices[i]+dp1[i-1]) + dp3[i] = max(dp3[i-1], dp2[i-1]-prices[i]) + dp4[i] = max(dp4[i-1], prices[i] + dp3[i-1]) + return dp4[-1] + +# leetcode submit region end(Prohibit modification and deletion) diff --git "a/script/[130]\350\242\253\345\233\264\347\273\225\347\232\204\345\214\272\345\237\237.py" "b/script/[130]\350\242\253\345\233\264\347\273\225\347\232\204\345\214\272\345\237\237.py" new file mode 100644 index 0000000..1b08d4d --- /dev/null +++ "b/script/[130]\350\242\253\345\233\264\347\273\225\347\232\204\345\214\272\345\237\237.py" @@ -0,0 +1,72 @@ +# 给你一个 m x n 的矩阵 board ,由若干字符 'X' 和 'O' ,找到所有被 'X' 围绕的区域,并将这些区域里所有的 'O' 用 'X' 填充 +# 。 +# +# +# +# +# 示例 1: +# +# +# 输入:board = [["X","X","X","X"],["X","O","O","X"],["X","X","O","X"],["X","O","X" +# ,"X"]] +# 输出:[["X","X","X","X"],["X","X","X","X"],["X","X","X","X"],["X","O","X","X"]] +# 解释:被围绕的区间不会存在于边界上,换句话说,任何边界上的 'O' 都不会被填充为 'X'。 任何不在边界上,或不与边界上的 'O' 相连的 'O' 最终都 +# 会被填充为 'X'。如果两个元素在水平或垂直方向相邻,则称它们是“相连”的。 +# +# +# 示例 2: +# +# +# 输入:board = [["X"]] +# 输出:[["X"]] +# +# +# +# +# 提示: +# +# +# m == board.length +# n == board[i].length +# 1 <= m, n <= 200 +# board[i][j] 为 'X' 或 'O' +# +# +# +# Related Topics 深度优先搜索 广度优先搜索 并查集 数组 矩阵 +# 👍 830 👎 0 + + +# leetcode submit region begin(Prohibit modification and deletion) +class Solution: + def solve(self, board: List[List[str]]) -> None: + """ + Do not return anything, modify board in-place instead. + """ + nrow = len(board) + ncol = len(board[0]) + stack = [] + for i in range(ncol): + if board[0][i] == 'O': + stack.append((0, i)) + if board[nrow - 1][i] == 'O': + stack.append((nrow - 1, i)) + for i in range(nrow): + if board[i][0] == 'O': + stack.append((i, 0)) + if board[i][ncol - 1] == 'O': + stack.append(((i, ncol - 1))) + while stack: + node = stack.pop() + board[node[0]][node[1]] = 'M' + for nr,nc in [(node[0]+1, node[1]),(node[0]-1,node[1]), (node[0],node[1]+1), (node[0],node[1]-1)]: + if nr < nrow and nr>=0 and nc=0 and board[nr][nc]=='O': + stack.append((nr,nc)) + + for i in range(nrow): + for j in range(ncol): + if board[i][j] =='M': + board[i][j] = 'O' + elif board[i][j]=='O': + board[i][j] = 'X' +# leetcode submit region end(Prohibit modification and deletion) diff --git "a/script/[134]\345\212\240\346\262\271\347\253\231.py" "b/script/[134]\345\212\240\346\262\271\347\253\231.py" new file mode 100644 index 0000000..bded594 --- /dev/null +++ "b/script/[134]\345\212\240\346\262\271\347\253\231.py" @@ -0,0 +1,63 @@ +# 在一条环路上有 n 个加油站,其中第 i 个加油站有汽油 gas[i] 升。 +# +# 你有一辆油箱容量无限的的汽车,从第 i 个加油站开往第 i+1 个加油站需要消耗汽油 cost[i] 升。你从其中的一个加油站出发,开始时油箱为空。 +# +# 给定两个整数数组 gas 和 cost ,如果你可以绕环路行驶一周,则返回出发时加油站的编号,否则返回 -1 。如果存在解,则 保证 它是 唯一 的。 +# +# +# +# 示例 1: +# +# +# 输入: gas = [1,2,3,4,5], cost = [3,4,5,1,2] +# 输出: 3 +# 解释: +# 从 3 号加油站(索引为 3 处)出发,可获得 4 升汽油。此时油箱有 = 0 + 4 = 4 升汽油 +# 开往 4 号加油站,此时油箱有 4 - 1 + 5 = 8 升汽油 +# 开往 0 号加油站,此时油箱有 8 - 2 + 1 = 7 升汽油 +# 开往 1 号加油站,此时油箱有 7 - 3 + 2 = 6 升汽油 +# 开往 2 号加油站,此时油箱有 6 - 4 + 3 = 5 升汽油 +# 开往 3 号加油站,你需要消耗 5 升汽油,正好足够你返回到 3 号加油站。 +# 因此,3 可为起始索引。 +# +# 示例 2: +# +# +# 输入: gas = [2,3,4], cost = [3,4,3] +# 输出: -1 +# 解释: +# 你不能从 0 号或 1 号加油站出发,因为没有足够的汽油可以让你行驶到下一个加油站。 +# 我们从 2 号加油站出发,可以获得 4 升汽油。 此时油箱有 = 0 + 4 = 4 升汽油 +# 开往 0 号加油站,此时油箱有 4 - 3 + 2 = 3 升汽油 +# 开往 1 号加油站,此时油箱有 3 - 3 + 3 = 3 升汽油 +# 你无法返回 2 号加油站,因为返程需要消耗 4 升汽油,但是你的油箱只有 3 升汽油。 +# 因此,无论怎样,你都不可能绕环路行驶一周。 +# +# +# +# 提示: +# +# +# gas.length == n +# cost.length == n +# 1 <= n <= 105 +# 0 <= gas[i], cost[i] <= 104 +# +# Related Topics 贪心 数组 +# 👍 991 👎 0 + + +# leetcode submit region begin(Prohibit modification and deletion) +class Solution: + def canCompleteCircuit(self, gas: List[int], cost: List[int]) -> int: + if sum(gas)< sum(cost): + return -1 + delta = 0 + pos =0 + for i in range(len(gas)): + delta += gas[i]-cost[i] + if delta<0: + pos = i+1 + delta =0 + return pos +# leetcode submit region end(Prohibit modification and deletion) diff --git "a/script/[135]\345\210\206\345\217\221\347\263\226\346\236\234.py" "b/script/[135]\345\210\206\345\217\221\347\263\226\346\236\234.py" new file mode 100644 index 0000000..ce30392 --- /dev/null +++ "b/script/[135]\345\210\206\345\217\221\347\263\226\346\236\234.py" @@ -0,0 +1,56 @@ +# n 个孩子站成一排。给你一个整数数组 ratings 表示每个孩子的评分。 +# +# 你需要按照以下要求,给这些孩子分发糖果: +# +# +# 每个孩子至少分配到 1 个糖果。 +# 相邻两个孩子评分更高的孩子会获得更多的糖果。 +# +# +# 请你给每个孩子分发糖果,计算并返回需要准备的 最少糖果数目 。 +# +# +# +# 示例 1: +# +# +# 输入:ratings = [1,0,2] +# 输出:5 +# 解释:你可以分别给第一个、第二个、第三个孩子分发 2、1、2 颗糖果。 +# +# +# 示例 2: +# +# +# 输入:ratings = [1,2,2] +# 输出:4 +# 解释:你可以分别给第一个、第二个、第三个孩子分发 1、2、1 颗糖果。 +# 第三个孩子只得到 1 颗糖果,这满足题面中的两个条件。 +# +# +# +# 提示: +# +# +# n == ratings.length +# 1 <= n <= 2 * 104 +# 0 <= ratings[i] <= 2 * 104 +# +# Related Topics 贪心 数组 +# 👍 934 👎 0 + + +# leetcode submit region begin(Prohibit modification and deletion) +class Solution: + def candy(self, ratings: List[int]) -> int: + l = len(ratings) + dp = [1] * l + for i in range(1, l): + if ratings[i]>ratings[i-1]: + dp[i] = max(dp[i],dp[i-1]+1) + for i in range(l-2,-1,-1): + if ratings[i]>ratings[i+1]: + dp[i] = max(dp[i],dp[i+1]+1) + return sum(dp) + +# leetcode submit region end(Prohibit modification and deletion) diff --git "a/script/[138]\345\244\215\345\210\266\345\270\246\351\232\217\346\234\272\346\214\207\351\222\210\347\232\204\351\223\276\350\241\250.py" "b/script/[138]\345\244\215\345\210\266\345\270\246\351\232\217\346\234\272\346\214\207\351\222\210\347\232\204\351\223\276\350\241\250.py" new file mode 100644 index 0000000..18fd86e --- /dev/null +++ "b/script/[138]\345\244\215\345\210\266\345\270\246\351\232\217\346\234\272\346\214\207\351\222\210\347\232\204\351\223\276\350\241\250.py" @@ -0,0 +1,89 @@ +# 给你一个长度为 n 的链表,每个节点包含一个额外增加的随机指针 random ,该指针可以指向链表中的任何节点或空节点。 +# +# 构造这个链表的 深拷贝。 深拷贝应该正好由 n 个 全新 节点组成,其中每个新节点的值都设为其对应的原节点的值。新节点的 next 指针和 random +# 指针也都应指向复制链表中的新节点,并使原链表和复制链表中的这些指针能够表示相同的链表状态。复制链表中的指针都不应指向原链表中的节点 。 +# +# 例如,如果原链表中有 X 和 Y 两个节点,其中 X.random --> Y 。那么在复制链表中对应的两个节点 x 和 y ,同样有 x.random +# --> y 。 +# +# 返回复制链表的头节点。 +# +# 用一个由 n 个节点组成的链表来表示输入/输出中的链表。每个节点用一个 [val, random_index] 表示: +# +# +# val:一个表示 Node.val 的整数。 +# random_index:随机指针指向的节点索引(范围从 0 到 n-1);如果不指向任何节点,则为 null 。 +# +# +# 你的代码 只 接受原链表的头节点 head 作为传入参数。 +# +# +# +# 示例 1: +# +# +# +# +# 输入:head = [[7,null],[13,0],[11,4],[10,2],[1,0]] +# 输出:[[7,null],[13,0],[11,4],[10,2],[1,0]] +# +# +# 示例 2: +# +# +# +# +# 输入:head = [[1,1],[2,1]] +# 输出:[[1,1],[2,1]] +# +# +# 示例 3: +# +# +# +# +# 输入:head = [[3,null],[3,0],[3,null]] +# 输出:[[3,null],[3,0],[3,null]] +# +# +# +# +# 提示: +# +# +# 0 <= n <= 1000 +# -104 <= Node.val <= 104 +# Node.random 为 null 或指向链表中的节点。 +# +# Related Topics 哈希表 链表 +# 👍 944 👎 0 + + +# leetcode submit region begin(Prohibit modification and deletion) +""" +# Definition for a Node. +class Node: + def __init__(self, x: int, next: 'Node' = None, random: 'Node' = None): + self.val = int(x) + self.next = next + self.random = random +""" + +class Solution: + def copyRandomList(self, head: 'Optional[Node]') -> 'Optional[Node]': + hash = dict() + ptr = head + while ptr: + hash[ptr] = ListNode(ptr.val) + ptr = ptr.next + ptr = head + hash[None] = None + while ptr: + hash[ptr].next = hash[ptr.next] + hash[ptr].random = hash[ptr.random] + ptr = ptr.next + return hash[head] + + + +# leetcode submit region end(Prohibit modification and deletion) diff --git "a/script/[139]\345\215\225\350\257\215\346\213\206\345\210\206.py" "b/script/[139]\345\215\225\350\257\215\346\213\206\345\210\206.py" new file mode 100644 index 0000000..fc7299e --- /dev/null +++ "b/script/[139]\345\215\225\350\257\215\346\213\206\345\210\206.py" @@ -0,0 +1,59 @@ +# 给你一个字符串 s 和一个字符串列表 wordDict 作为字典。请你判断是否可以利用字典中出现的单词拼接出 s 。 +# +# 注意:不要求字典中出现的单词全部都使用,并且字典中的单词可以重复使用。 +# +# +# +# 示例 1: +# +# +# 输入: s = "leetcode", wordDict = ["leet", "code"] +# 输出: true +# 解释: 返回 true 因为 "leetcode" 可以由 "leet" 和 "code" 拼接成。 +# +# +# 示例 2: +# +# +# 输入: s = "applepenapple", wordDict = ["apple", "pen"] +# 输出: true +# 解释: 返回 true 因为 "applepenapple" 可以由 "apple" "pen" "apple" 拼接成。 +#   注意,你可以重复使用字典中的单词。 +# +# +# 示例 3: +# +# +# 输入: s = "catsandog", wordDict = ["cats", "dog", "sand", "and", "cat"] +# 输出: false +# +# +# +# +# 提示: +# +# +# 1 <= s.length <= 300 +# 1 <= wordDict.length <= 1000 +# 1 <= wordDict[i].length <= 20 +# s 和 wordDict[i] 仅有小写英文字母组成 +# wordDict 中的所有字符串 互不相同 +# +# Related Topics 字典树 记忆化搜索 哈希表 字符串 动态规划 +# 👍 1725 👎 0 + + +# leetcode submit region begin(Prohibit modification and deletion) +class Solution: + def wordBreak(self, s: str, wordDict: List[str]) -> bool: + ls = len(s) + dp = [False]* (ls+1) + dp[0]=True + wordDict = set(wordDict) + for i in range(1, ls+1): + for ss in wordDict: + lw = len(ss) + if i>=lw: + dp[i] = dp[i] or (dp[i-lw] and s[(i-lw):i]==ss) + return dp[-1] +# leetcode submit region end(Prohibit modification and deletion) diff --git "a/script/[141]\347\216\257\345\275\242\351\223\276\350\241\250.py" "b/script/[141]\347\216\257\345\275\242\351\223\276\350\241\250.py" new file mode 100644 index 0000000..2c43a71 --- /dev/null +++ "b/script/[141]\347\216\257\345\275\242\351\223\276\350\241\250.py" @@ -0,0 +1,74 @@ +# 给你一个链表的头节点 head ,判断链表中是否有环。 +# +# 如果链表中有某个节点,可以通过连续跟踪 next 指针再次到达,则链表中存在环。 为了表示给定链表中的环,评测系统内部使用整数 pos 来表示链表尾连接到 +# 链表中的位置(索引从 0 开始)。注意:pos 不作为参数进行传递 。仅仅是为了标识链表的实际情况。 +# +# 如果链表中存在环 ,则返回 true 。 否则,返回 false 。 +# +# +# +# 示例 1: +# +# +# +# +# 输入:head = [3,2,0,-4], pos = 1 +# 输出:true +# 解释:链表中有一个环,其尾部连接到第二个节点。 +# +# +# 示例 2: +# +# +# +# +# 输入:head = [1,2], pos = 0 +# 输出:true +# 解释:链表中有一个环,其尾部连接到第一个节点。 +# +# +# 示例 3: +# +# +# +# +# 输入:head = [1], pos = -1 +# 输出:false +# 解释:链表中没有环。 +# +# +# +# +# 提示: +# +# +# 链表中节点的数目范围是 [0, 104] +# -105 <= Node.val <= 105 +# pos 为 -1 或者链表中的一个 有效索引 。 +# +# +# +# +# 进阶:你能用 O(1)(即,常量)内存解决此问题吗? +# Related Topics 哈希表 链表 双指针 +# 👍 1553 👎 0 + + +# leetcode submit region begin(Prohibit modification and deletion) +# Definition for singly-linked list. +# class ListNode: +# def __init__(self, x): +# self.val = x +# self.next = None + +class Solution: + def hasCycle(self, head: Optional[ListNode]) -> bool: + fast, slow = head, head + while fast and fast.next: + fast = fast.next.next + slow = slow.next + if slow==fast: + return True + return False + +# leetcode submit region end(Prohibit modification and deletion) diff --git "a/script/[142]\347\216\257\345\275\242\351\223\276\350\241\250 II.py" "b/script/[142]\347\216\257\345\275\242\351\223\276\350\241\250 II.py" new file mode 100644 index 0000000..d15b86f --- /dev/null +++ "b/script/[142]\347\216\257\345\275\242\351\223\276\350\241\250 II.py" @@ -0,0 +1,81 @@ +# 给定一个链表的头节点 head ,返回链表开始入环的第一个节点。 如果链表无环,则返回 null。 +# +# 如果链表中有某个节点,可以通过连续跟踪 next 指针再次到达,则链表中存在环。 为了表示给定链表中的环,评测系统内部使用整数 pos 来表示链表尾连接到 +# 链表中的位置(索引从 0 开始)。如果 pos 是 -1,则在该链表中没有环。注意:pos 不作为参数进行传递,仅仅是为了标识链表的实际情况。 +# +# 不允许修改 链表。 +# +# +# +# +# + +# +# 示例 1: +# +# +# +# +# 输入:head = [3,2,0,-4], pos = 1 +# 输出:返回索引为 1 的链表节点 +# 解释:链表中有一个环,其尾部连接到第二个节点。 +# +# +# 示例 2: +# +# +# +# +# 输入:head = [1,2], pos = 0 +# 输出:返回索引为 0 的链表节点 +# 解释:链表中有一个环,其尾部连接到第一个节点。 +# +# +# 示例 3: +# +# +# +# +# 输入:head = [1], pos = -1 +# 输出:返回 null +# 解释:链表中没有环。 +# +# +# +# +# 提示: +# +# +# 链表中节点的数目范围在范围 [0, 104] 内 +# -105 <= Node.val <= 105 +# pos 的值为 -1 或者链表中的一个有效索引 +# +# +# +# +# 进阶:你是否可以使用 O(1) 空间解决此题? +# Related Topics 哈希表 链表 双指针 +# 👍 1685 👎 0 + + +# leetcode submit region begin(Prohibit modification and deletion) +# Definition for singly-linked list. +# class ListNode: +# def __init__(self, x): +# self.val = x +# self.next = None + +class Solution: + def detectCycle(self, head: ListNode) -> ListNode: + slow, fast = head,head + while fast and fast.next: + slow = slow.next + fast = fast.next.next + if slow == fast: + fast = head + while slow!=fast: + slow = slow.next + fast = fast.next + return slow + return None +# leetcode submit region end(Prohibit modification and deletion) diff --git "a/script/[1438]\347\273\235\345\257\271\345\267\256\344\270\215\350\266\205\350\277\207\351\231\220\345\210\266\347\232\204\346\234\200\351\225\277\350\277\236\347\273\255\345\255\220\346\225\260\347\273\204.py" "b/script/[1438]\347\273\235\345\257\271\345\267\256\344\270\215\350\266\205\350\277\207\351\231\220\345\210\266\347\232\204\346\234\200\351\225\277\350\277\236\347\273\255\345\255\220\346\225\260\347\273\204.py" new file mode 100644 index 0000000..d452f59 --- /dev/null +++ "b/script/[1438]\347\273\235\345\257\271\345\267\256\344\270\215\350\266\205\350\277\207\351\231\220\345\210\266\347\232\204\346\234\200\351\225\277\350\277\236\347\273\255\345\255\220\346\225\260\347\273\204.py" @@ -0,0 +1,79 @@ +# 给你一个整数数组 nums ,和一个表示限制的整数 limit,请你返回最长连续子数组的长度,该子数组中的任意两个元素之间的绝对差必须小于或者等于 limi +# t 。 +# +# 如果不存在满足条件的子数组,则返回 0 。 +# +# +# +# 示例 1: +# +# 输入:nums = [8,2,4,7], limit = 4 +# 输出:2 +# 解释:所有子数组如下: +# [8] 最大绝对差 |8-8| = 0 <= 4. +# [8,2] 最大绝对差 |8-2| = 6 > 4. +# [8,2,4] 最大绝对差 |8-2| = 6 > 4. +# [8,2,4,7] 最大绝对差 |8-2| = 6 > 4. +# [2] 最大绝对差 |2-2| = 0 <= 4. +# [2,4] 最大绝对差 |2-4| = 2 <= 4. +# [2,4,7] 最大绝对差 |2-7| = 5 > 4. +# [4] 最大绝对差 |4-4| = 0 <= 4. +# [4,7] 最大绝对差 |4-7| = 3 <= 4. +# [7] 最大绝对差 |7-7| = 0 <= 4. +# 因此,满足题意的最长子数组的长度为 2 。 +# +# +# 示例 2: +# +# 输入:nums = [10,1,2,4,7,2], limit = 5 +# 输出:4 +# 解释:满足题意的最长子数组是 [2,4,7,2],其最大绝对差 |2-7| = 5 <= 5 。 +# +# +# 示例 3: +# +# 输入:nums = [4,2,2,2,4,4,2,2], limit = 0 +# 输出:3 +# +# +# +# +# 提示: +# +# +# 1 <= nums.length <= 10^5 +# 1 <= nums[i] <= 10^9 +# 0 <= limit <= 10^9 +# +# Related Topics 队列 数组 有序集合 滑动窗口 单调队列 堆(优先队列) +# 👍 256 👎 0 + + +# leetcode submit region begin(Prohibit modification and deletion) +class Solution: + def longestSubarray(self, nums: List[int], limit: int) -> int: + from collections import deque + minstack = deque([nums[0]]) #单调递减, top最大 + maxstack = deque([nums[0]]) #单调递增,top最小 + maxlen = 1 + left =0 + for i in range(1, len(nums)): + while minstack and nums[i]>minstack[-1]: + minstack.pop() + minstack.append(nums[i]) + while maxstack and nums[i]limit: + if minstack[0] == nums[left]: + minstack.popleft() + if maxstack[0] ==nums[left]: + maxstack.popleft() + left +=1 + maxlen = max(maxlen, i-left+1) + return maxlen + + + + +# leetcode submit region end(Prohibit modification and deletion) diff --git "a/script/[143]\351\207\215\346\216\222\351\223\276\350\241\250.py" "b/script/[143]\351\207\215\346\216\222\351\223\276\350\241\250.py" new file mode 100644 index 0000000..29337ff --- /dev/null +++ "b/script/[143]\351\207\215\346\216\222\351\223\276\350\241\250.py" @@ -0,0 +1,93 @@ +# 给定一个单链表 L 的头节点 head ,单链表 L 表示为: +# +# +# L0 → L1 → … → Ln - 1 → Ln +# +# +# 请将其重新排列后变为: +# +# +# L0 → Ln → L1 → Ln - 1 → L2 → Ln - 2 → … +# +# 不能只是单纯的改变节点内部的值,而是需要实际的进行节点交换。 +# +# +# +# 示例 1: +# +# +# +# +# 输入:head = [1,2,3,4] +# 输出:[1,4,2,3] +# +# 示例 2: +# +# +# +# +# 输入:head = [1,2,3,4,5] +# 输出:[1,5,2,4,3] +# +# +# +# 提示: +# +# +# 链表的长度范围为 [1, 5 * 104] +# 1 <= node.val <= 1000 +# +# Related Topics 栈 递归 链表 双指针 +# 👍 969 👎 0 + + +# leetcode submit region begin(Prohibit modification and deletion) +# Definition for singly-linked list. +# class ListNode: +# def __init__(self, val=0, next=None): +# self.val = val +# self.next = next +class Solution: + def reorderList(self, head: ListNode) -> None: + """ + Do not return anything, modify head in-place instead. + """ + if not head: + return None + + def reverse(head): + newnode = None + cur = head + while cur: + nextnode = cur.next + cur.next=newnode + newnode = cur + cur = nextnode + return newnode + + def getmid(head): + slow, fast = head, head + while fast.next and fast.next.next: + slow = slow.next + fast = fast.next.next + return slow + + def merge(l1, l2): + while l1 and l2: + l1_tmp = l1.next + l2_tmp = l2.next + + l1.next = l2 + l1 = l1_tmp + + l2.next = l1 + l2 = l2_tmp + ptr1 = head + left_mid = getmid(head) + mid = left_mid.next + left_mid.next=None + + ptr2 = reverse(mid) + merge(ptr1, ptr2) + +# leetcode submit region end(Prohibit modification and deletion) diff --git "a/script/[147]\345\257\271\351\223\276\350\241\250\350\277\233\350\241\214\346\217\222\345\205\245\346\216\222\345\272\217.py" "b/script/[147]\345\257\271\351\223\276\350\241\250\350\277\233\350\241\214\346\217\222\345\205\245\346\216\222\345\272\217.py" new file mode 100644 index 0000000..4c22098 --- /dev/null +++ "b/script/[147]\345\257\271\351\223\276\350\241\250\350\277\233\350\241\214\346\217\222\345\205\245\346\216\222\345\272\217.py" @@ -0,0 +1,73 @@ +# 给定单个链表的头 head ,使用 插入排序 对链表进行排序,并返回 排序后链表的头 。 +# +# 插入排序 算法的步骤: +# +# +# 插入排序是迭代的,每次只移动一个元素,直到所有元素可以形成一个有序的输出列表。 +# 每次迭代中,插入排序只从输入数据中移除一个待排序的元素,找到它在序列中适当的位置,并将其插入。 +# 重复直到所有输入数据插入完为止。 +# +# +# 下面是插入排序算法的一个图形示例。部分排序的列表(黑色)最初只包含列表中的第一个元素。每次迭代时,从输入数据中删除一个元素(红色),并就地插入已排序的列表 +# 中。 +# +# 对链表进行插入排序。 +# +# +# +# +# +# 示例 1: +# +# +# +# +# 输入: head = [4,2,1,3] +# 输出: [1,2,3,4] + +# +# 示例 2: +# +# +# +# +# 输入: head = [-1,5,3,4,0] +# 输出: [-1,0,3,4,5] +# +# +# +# 提示: +# +# +# +# +# 列表中的节点数在 [1, 5000]范围内 +# -5000 <= Node.val <= 5000 +# +# Related Topics 链表 排序 +# 👍 535 👎 0 + + +# leetcode submit region begin(Prohibit modification and deletion) +# Definition for singly-linked list. +# class ListNode: +# def __init__(self, val=0, next=None): +# self.val = val +# self.next = next +class Solution: + def insertionSortList(self, head: ListNode) -> ListNode: + newnode =ListNode(-1) + cur = newnode + while head: + if head.val < cur.val: + cur = newnode + #永远不对当前状态进行修改 + while cur.next and head.val > cur.next.val: + cur = cur.next + cur_next = cur.next + cur.next = ListNode(head.val) + cur.next.next = cur_next + cur = cur.next + head = head.next + return newnode.next +# leetcode submit region end(Prohibit modification and deletion) diff --git "a/script/[148]\346\216\222\345\272\217\351\223\276\350\241\250.py" "b/script/[148]\346\216\222\345\272\217\351\223\276\350\241\250.py" new file mode 100644 index 0000000..41cb6e0 --- /dev/null +++ "b/script/[148]\346\216\222\345\272\217\351\223\276\350\241\250.py" @@ -0,0 +1,88 @@ +# 给你链表的头结点 head ,请将其按 升序 排列并返回 排序后的链表 。 +# +# +# +# +# +# +# 示例 1: +# +# +# 输入:head = [4,2,1,3] +# 输出:[1,2,3,4] +# +# +# 示例 2: +# +# +# 输入:head = [-1,5,3,4,0] +# 输出:[-1,0,3,4,5] +# +# +# 示例 3: +# +# +# 输入:head = [] +# 输出:[] +# +# +# +# +# 提示: +# +# +# 链表中节点的数目在范围 [0, 5 * 104] 内 +# -105 <= Node.val <= 105 +# +# +# +# +# 进阶:你可以在 O(n log n) 时间复杂度和常数级空间复杂度下,对链表进行排序吗? +# Related Topics 链表 双指针 分治 排序 归并排序 +# 👍 1718 👎 0 + + +# leetcode submit region begin(Prohibit modification and deletion) +# Definition for singly-linked list. +# class ListNode: +# def __init__(self, val=0, next=None): +# self.val = val +# self.next = next +class Solution: + def sortList(self, head: Optional[ListNode]) -> Optional[ListNode]: + def merge(l1, l2): + newnode = ListNode(-1) + ptr = newnode + while l1 and l2: + if l1.val < l2.val: + ptr.next =l1 + l1 = l1.next + else: + ptr.next=l2 + l2 = l2.next + ptr = ptr.next + if l1: + ptr.next=l1 + if l2: + ptr.next=l2 + return newnode.next + + def getmid(head): + slow, fast = head, head + while fast.next and fast.next.next: + slow = slow.next + fast = fast.next.next + return slow + + def sort_merge(head): + if not head or not head.next: + return head + left = getmid(head) + right = left.next + left.next=None + left = sort_merge(head) + right = sort_merge(right) + return merge(left, right ) + return sort_merge(head) + +# leetcode submit region end(Prohibit modification and deletion) diff --git "a/script/[150]\351\200\206\346\263\242\345\205\260\350\241\250\350\276\276\345\274\217\346\261\202\345\200\274.py" "b/script/[150]\351\200\206\346\263\242\345\205\260\350\241\250\350\276\276\345\274\217\346\261\202\345\200\274.py" new file mode 100644 index 0000000..59417fc --- /dev/null +++ "b/script/[150]\351\200\206\346\263\242\345\205\260\350\241\250\350\276\276\345\274\217\346\261\202\345\200\274.py" @@ -0,0 +1,92 @@ +# 根据 逆波兰表示法,求表达式的值。 +# +# 有效的算符包括 +、-、*、/ 。每个运算对象可以是整数,也可以是另一个逆波兰表达式。 +# +# 注意 两个整数之间的除法只保留整数部分。 +# +# 可以保证给定的逆波兰表达式总是有效的。换句话说,表达式总会得出有效数值且不存在除数为 0 的情况。 +# +# +# +# 示例 1: +# +# +# 输入:tokens = ["2","1","+","3","*"] +# 输出:9 +# 解释:该算式转化为常见的中缀算术表达式为:((2 + 1) * 3) = 9 +# +# +# 示例 2: +# +# +# 输入:tokens = ["4","13","5","/","+"] +# 输出:6 +# 解释:该算式转化为常见的中缀算术表达式为:(4 + (13 / 5)) = 6 +# +# +# 示例 3: +# +# +# 输入: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 +# +# +# +# 提示: +# +# +# 1 <= tokens.length <= 104 +# tokens[i] 是一个算符("+"、"-"、"*" 或 "/"),或是在范围 [-200, 200] 内的一个整数 +# +# +# +# +# 逆波兰表达式: +# +# 逆波兰表达式是一种后缀表达式,所谓后缀就是指算符写在后面。 +# +# +# 平常使用的算式则是一种中缀表达式,如 ( 1 + 2 ) * ( 3 + 4 ) 。 +# 该算式的逆波兰表达式写法为 ( ( 1 2 + ) ( 3 4 + ) * ) 。 +# +# +# 逆波兰表达式主要有以下两个优点: +# +# +# 去掉括号后表达式无歧义,上式即便写成 1 2 + 3 4 + * 也可以依据次序计算出正确结果。 +# 适合用栈操作运算:遇到数字则入栈;遇到算符则取出栈顶两个数字进行计算,并将结果压入栈中 +# +# Related Topics 栈 数组 数学 +# 👍 572 👎 0 + + +class Solution: + def evalRPN(self, tokens: List[str]) -> int: + stack = [] + for token in tokens: + if token not in ['+','-','*','/']: + stack.append(int(token)) + else: + b = stack.pop() + a = stack.pop() + if token=='+': + stack.append(a+b) + elif token=='-': + stack.append(a-b) + elif token =='*': + stack.append(a*b) + else: + if a*b<0: + stack.append(-(abs(a)//abs(b))) + else: + stack.append(a//b) + return int(stack.pop()) +# leetcode submit region end(Prohibit modification and deletion) diff --git "a/script/[155]\346\234\200\345\260\217\346\240\210.py" "b/script/[155]\346\234\200\345\260\217\346\240\210.py" new file mode 100644 index 0000000..e667128 --- /dev/null +++ "b/script/[155]\346\234\200\345\260\217\346\240\210.py" @@ -0,0 +1,83 @@ +# 设计一个支持 push ,pop ,top 操作,并能在常数时间内检索到最小元素的栈。 +# +# 实现 MinStack 类: +# +# +# MinStack() 初始化堆栈对象。 +# void push(int val) 将元素val推入堆栈。 +# void pop() 删除堆栈顶部的元素。 +# int top() 获取堆栈顶部的元素。 +# int getMin() 获取堆栈中的最小元素。 +# +# +# +# +# 示例 1: +# +# +# 输入: +# ["MinStack","push","push","push","getMin","pop","top","getMin"] +# [[],[-2],[0],[-3],[],[],[],[]] +# +# 输出: +# [null,null,null,null,-3,null,0,-2] +# +# 解释: +# MinStack minStack = new MinStack(); +# minStack.push(-2); +# minStack.push(0); +# minStack.push(-3); +# minStack.getMin(); --> 返回 -3. +# minStack.pop(); +# minStack.top(); --> 返回 0. +# minStack.getMin(); --> 返回 -2. +# +# +# +# +# 提示: +# +# +# -231 <= val <= 231 - 1 +# pop、top 和 getMin 操作总是在 非空栈 上调用 +# push, pop, top, and getMin最多被调用 3 * 104 次 +# +# Related Topics 栈 设计 +# 👍 1362 👎 0 + + +# leetcode submit region begin(Prohibit modification and deletion) +class MinStack: + + def __init__(self): + self.stack = [] + self.minstack = [2**31] + + + def push(self, val: int) -> None: + self.stack.append(val) + if val < self.minstack[-1]: + self.minstack.append(val) + else: + self.minstack.append(self.minstack[-1]) + + def pop(self) -> None: + self.stack.pop() + self.minstack.pop() + + + def top(self) -> int: + return self.stack[-1] + + + def getMin(self) -> int: + return self.minstack[-1] + + +# Your MinStack object will be instantiated and called as such: +# obj = MinStack() +# obj.push(val) +# obj.pop() +# param_3 = obj.top() +# param_4 = obj.getMin() +# leetcode submit region end(Prohibit modification and deletion) diff --git "a/script/[160]\347\233\270\344\272\244\351\223\276\350\241\250.py" "b/script/[160]\347\233\270\344\272\244\351\223\276\350\241\250.py" new file mode 100644 index 0000000..38f4b54 --- /dev/null +++ "b/script/[160]\347\233\270\344\272\244\351\223\276\350\241\250.py" @@ -0,0 +1,117 @@ +# 给你两个单链表的头节点 headA 和 headB ,请你找出并返回两个单链表相交的起始节点。如果两个链表不存在相交节点,返回 null 。 +# +# 图示两个链表在节点 c1 开始相交: +# +# +# +# 题目数据 保证 整个链式结构中不存在环。 +# +# 注意,函数返回结果后,链表必须 保持其原始结构 。 +# +# 自定义评测: +# +# 评测系统 的输入如下(你设计的程序 不适用 此输入): +# +# +# intersectVal - 相交的起始节点的值。如果不存在相交节点,这一值为 0 +# listA - 第一个链表 +# listB - 第二个链表 +# skipA - 在 listA 中(从头节点开始)跳到交叉节点的节点数 +# skipB - 在 listB 中(从头节点开始)跳到交叉节点的节点数 +# +# +# 评测系统将根据这些输入创建链式数据结构,并将两个头节点 headA 和 headB 传递给你的程序。如果程序能够正确返回相交节点,那么你的解决方案将被 视 +# 作正确答案 。 +# +# +# +# 示例 1: +# +# +# +# +# 输入:intersectVal = 8, listA = [4,1,8,4,5], listB = [5,6,1,8,4,5], skipA = 2, sk +# ipB = 3 +# 输出:Intersected at '8' +# 解释:相交节点的值为 8 (注意,如果两个链表相交则不能为 0)。 +# 从各自的表头开始算起,链表 A 为 [4,1,8,4,5],链表 B 为 [5,6,1,8,4,5]。 +# 在 A 中,相交节点前有 2 个节点;在 B 中,相交节点前有 3 个节点。 +# +# +# 示例 2: +# +# +# +# +# 输入:intersectVal = 2, listA = [1,9,1,2,4], listB = [3,2,4], skipA = 3, skipB = +# 1 +# 输出:Intersected at '2' +# 解释:相交节点的值为 2 (注意,如果两个链表相交则不能为 0)。 +# 从各自的表头开始算起,链表 A 为 [1,9,1,2,4],链表 B 为 [3,2,4]。 +# 在 A 中,相交节点前有 3 个节点;在 B 中,相交节点前有 1 个节点。 +# +# +# 示例 3: +# +# +# +# +# 输入:intersectVal = 0, listA = [2,6,4], listB = [1,5], skipA = 3, skipB = 2 +# 输出:null +# 解释:从各自的表头开始算起,链表 A 为 [2,6,4],链表 B 为 [1,5]。 +# 由于这两个链表不相交,所以 intersectVal 必须为 0,而 skipA 和 skipB 可以是任意值。 +# 这两个链表不相交,因此返回 null 。 +# +# +# +# +# 提示: +# +# +# listA 中节点数目为 m +# listB 中节点数目为 n +# 1 <= m, n <= 3 * 104 +# 1 <= Node.val <= 105 +# 0 <= skipA <= m +# 0 <= skipB <= n +# 如果 listA 和 listB 没有交点,intersectVal 为 0 +# 如果 listA 和 listB 有交点,intersectVal == listA[skipA] == listB[skipB] +# +# +# +# +# 进阶:你能否设计一个时间复杂度 O(m + n) 、仅用 O(1) 内存的解决方案? +# Related Topics 哈希表 链表 双指针 +# 👍 1783 👎 0 + + +# leetcode submit region begin(Prohibit modification and deletion) +# Definition for singly-linked list. +# class ListNode: +# def __init__(self, x): +# self.val = x +# self.next = None + +class Solution: + def getIntersectionNode(self, headA: ListNode, headB: ListNode) -> ListNode: + la, lb = 0,0 + ptra,ptrb = headA,headB + while ptra: + ptra = ptra.next + la+=1 + while ptrb: + ptrb = ptrb.next + lb+=1 + + for i in range(la-lb): + headA = headA.next + for i in range(lb-la): + headB = headB.next + while headA and headB: + if headA==headB: + return headA + headA = headA.next + headB = headB.next + return None + +# leetcode submit region end(Prohibit modification and deletion) diff --git "a/script/[169]\345\244\232\346\225\260\345\205\203\347\264\240.py" "b/script/[169]\345\244\232\346\225\260\345\205\203\347\264\240.py" new file mode 100644 index 0000000..468b42d --- /dev/null +++ "b/script/[169]\345\244\232\346\225\260\345\205\203\347\264\240.py" @@ -0,0 +1,51 @@ +# 给定一个大小为 n 的数组 nums ,返回其中的多数元素。多数元素是指在数组中出现次数 大于 ⌊ n/2 ⌋ 的元素。 +# +# 你可以假设数组是非空的,并且给定的数组总是存在多数元素。 +# +# +# +# 示例 1: +# +# +# 输入:nums = [3,2,3] +# 输出:3 +# +# 示例 2: +# +# +# 输入:nums = [2,2,1,1,1,2,2] +# 输出:2 +# +# +# +# 提示: +# +# +# n == nums.length +# 1 <= n <= 5 * 104 +# -109 <= nums[i] <= 109 +# +# +# +# +# 进阶:尝试设计时间复杂度为 O(n)、空间复杂度为 O(1) 的算法解决此问题。 +# Related Topics 数组 哈希表 分治 计数 排序 +# 👍 1509 👎 0 + + +# leetcode submit region begin(Prohibit modification and deletion) +class Solution: + def majorityElement(self, nums: List[int]) -> int: + val = nums[0] + counter =1 + for i in range(1,len(nums)): + if nums[i]==val: + counter+=1 + else: + counter-=1 + if counter==0: + counter=1 + val = nums[i] + return val + +# leetcode submit region end(Prohibit modification and deletion) diff --git "a/script/[1721]\344\272\244\346\215\242\351\223\276\350\241\250\344\270\255\347\232\204\350\212\202\347\202\271.py" "b/script/[1721]\344\272\244\346\215\242\351\223\276\350\241\250\344\270\255\347\232\204\350\212\202\347\202\271.py" new file mode 100644 index 0000000..24deafe --- /dev/null +++ "b/script/[1721]\344\272\244\346\215\242\351\223\276\350\241\250\344\270\255\347\232\204\350\212\202\347\202\271.py" @@ -0,0 +1,74 @@ +# 给你链表的头节点 head 和一个整数 k 。 +# +# 交换 链表正数第 k 个节点和倒数第 k 个节点的值后,返回链表的头节点(链表 从 1 开始索引)。 +# +# +# +# 示例 1: +# +# +# 输入:head = [1,2,3,4,5], k = 2 +# 输出:[1,4,3,2,5] +# +# +# 示例 2: +# +# +# 输入:head = [7,9,6,6,7,8,3,0,9,5], k = 5 +# 输出:[7,9,6,6,8,7,3,0,9,5] +# +# +# 示例 3: +# +# +# 输入:head = [1], k = 1 +# 输出:[1] +# +# +# 示例 4: +# +# +# 输入:head = [1,2], k = 1 +# 输出:[2,1] +# +# +# 示例 5: +# +# +# 输入:head = [1,2,3], k = 2 +# 输出:[1,2,3] +# +# +# +# +# 提示: +# +# +# 链表中节点的数目是 n +# 1 <= k <= n <= 105 +# 0 <= Node.val <= 100 +# +# Related Topics 链表 双指针 +# 👍 60 👎 0 + + +# leetcode submit region begin(Prohibit modification and deletion) +# Definition for singly-linked list. +# class ListNode: +# def __init__(self, val=0, next=None): +# self.val = val +# self.next = next +class Solution: + def swapNodes(self, head: Optional[ListNode], k: int) -> Optional[ListNode]: + ptr1, ptr2 = head,head + for i in range(k-1): + ptr1 = ptr1.next + node1 = ptr1 + while ptr1 and ptr1.next: + ptr1 = ptr1.next + ptr2 = ptr2.next + node1.val, ptr2.val = ptr2.val, node1.val + return head + + +# leetcode submit region end(Prohibit modification and deletion) diff --git "a/script/[173]\344\272\214\345\217\211\346\220\234\347\264\242\346\240\221\350\277\255\344\273\243\345\231\250.py" "b/script/[173]\344\272\214\345\217\211\346\220\234\347\264\242\346\240\221\350\277\255\344\273\243\345\231\250.py" new file mode 100644 index 0000000..28043fb --- /dev/null +++ "b/script/[173]\344\272\214\345\217\211\346\220\234\347\264\242\346\240\221\350\277\255\344\273\243\345\231\250.py" @@ -0,0 +1,100 @@ +# 实现一个二叉搜索树迭代器类BSTIterator ,表示一个按中序遍历二叉搜索树(BST)的迭代器: +# +# +# +# BSTIterator(TreeNode root) 初始化 BSTIterator 类的一个对象。BST 的根节点 root 会作为构造函数的一部分给出 +# 。指针应初始化为一个不存在于 BST 中的数字,且该数字小于 BST 中的任何元素。 +# boolean hasNext() 如果向指针右侧遍历存在数字,则返回 true ;否则返回 false 。 +# int next()将指针向右移动,然后返回指针处的数字。 +# +# +# 注意,指针初始化为一个不存在于 BST 中的数字,所以对 next() 的首次调用将返回 BST 中的最小元素。 +# +# +# +# 你可以假设 next() 调用总是有效的,也就是说,当调用 next() 时,BST 的中序遍历中至少存在一个下一个数字。 +# +# +# +# 示例: +# +# +# 输入 +# ["BSTIterator", "next", "next", "hasNext", "next", "hasNext", "next", "hasNext +# ", "next", "hasNext"] +# [[[7, 3, 15, null, null, 9, 20]], [], [], [], [], [], [], [], [], []] +# 输出 +# [null, 3, 7, true, 9, true, 15, true, 20, false] +# +# 解释 +# BSTIterator bSTIterator = new BSTIterator([7, 3, 15, null, null, 9, 20]); +# bSTIterator.next(); // 返回 3 +# bSTIterator.next(); // 返回 7 +# bSTIterator.hasNext(); // 返回 True +# bSTIterator.next(); // 返回 9 +# bSTIterator.hasNext(); // 返回 True +# bSTIterator.next(); // 返回 15 +# bSTIterator.hasNext(); // 返回 True +# bSTIterator.next(); // 返回 20 +# bSTIterator.hasNext(); // 返回 False +# +# +# +# +# 提示: +# +# +# 树中节点的数目在范围 [1, 105] 内 +# 0 <= Node.val <= 106 +# 最多调用 105 次 hasNext 和 next 操作 +# +# +# +# +# 进阶: +# +# +# 你可以设计一个满足下述条件的解决方案吗?next() 和 hasNext() 操作均摊时间复杂度为 O(1) ,并使用 O(h) 内存。其中 h 是树的高 +# 度。 +# +# Related Topics 栈 树 设计 二叉搜索树 二叉树 迭代器 +# 👍 620 👎 0 + + +# leetcode submit region begin(Prohibit modification and deletion) +# Definition for a binary tree node. +# class TreeNode: +# def __init__(self, val=0, left=None, right=None): +# self.val = val +# self.left = left +# self.right = right +class BSTIterator: + + def __init__(self, root: TreeNode): + self.root = root + self.stack = [] + while self.root: + self.stack.append(self.root) + self.root = self.root.left + + def next(self) -> int: + node = self.stack.pop() + root = node.right + while root: + self.stack.append(root) + root = root.left + return node.val + + def hasNext(self) -> bool: + if self.stack: + return True + else: + return False + + + +# Your BSTIterator object will be instantiated and called as such: +# obj = BSTIterator(root) +# param_1 = obj.next() +# param_2 = obj.hasNext() +# leetcode submit region end(Prohibit modification and deletion) diff --git "a/script/[179]\346\234\200\345\244\247\346\225\260.py" "b/script/[179]\346\234\200\345\244\247\346\225\260.py" new file mode 100644 index 0000000..6f1f782 --- /dev/null +++ "b/script/[179]\346\234\200\345\244\247\346\225\260.py" @@ -0,0 +1,47 @@ +# 给定一组非负整数 nums,重新排列每个数的顺序(每个数不可拆分)使之组成一个最大的整数。 +# +# 注意:输出结果可能非常大,所以你需要返回一个字符串而不是整数。 +# +# +# +# 示例 1: +# +# +# 输入:nums = [10,2] +# 输出:"210" +# +# 示例 2: +# +# +# 输入:nums = [3,30,34,5,9] +# 输出:"9534330" +# +# +# +# +# 提示: +# +# +# 1 <= nums.length <= 100 +# 0 <= nums[i] <= 109 +# +# Related Topics 贪心 字符串 排序 +# 👍 978 👎 0 + + +# leetcode submit region begin(Prohibit modification and deletion) +class Solution: + def largestNumber(self, nums: List[int]) -> str: + def cmp(a,b): + if a+b int: + if not prices: + return 0 + l = len(prices) + dp = [[0] * l for i in range(2*k+1)] + for j in range(1, 2*k+1,2): + dp[j][0] = -prices[0] + for i in range(1,l): + for j in range(1, 2*k+1,2): + dp[j][i] = max(dp[j][i - 1], dp[j-1][i-1]-prices[i]) + dp[j+1][i] = max(dp[j+1][i - 1], dp[j][i-1] + prices[i]) + return dp[-1][-1] + + +# leetcode submit region end(Prohibit modification and deletion) diff --git "a/script/[198]\346\211\223\345\256\266\345\212\253\350\210\215.py" "b/script/[198]\346\211\223\345\256\266\345\212\253\350\210\215.py" new file mode 100644 index 0000000..83600a9 --- /dev/null +++ "b/script/[198]\346\211\223\345\256\266\345\212\253\350\210\215.py" @@ -0,0 +1,46 @@ +# 你是一个专业的小偷,计划偷窃沿街的房屋。每间房内都藏有一定的现金,影响你偷窃的唯一制约因素就是相邻的房屋装有相互连通的防盗系统,如果两间相邻的房屋在同一晚上 +# 被小偷闯入,系统会自动报警。 +# +# 给定一个代表每个房屋存放金额的非负整数数组,计算你 不触动警报装置的情况下 ,一夜之内能够偷窃到的最高金额。 +# +# +# +# 示例 1: +# +# +# 输入:[1,2,3,1] +# 输出:4 +# 解释:偷窃 1 号房屋 (金额 = 1) ,然后偷窃 3 号房屋 (金额 = 3)。 +#   偷窃到的最高金额 = 1 + 3 = 4 。 +# +# 示例 2: +# +# +# 输入:[2,7,9,3,1] +# 输出:12 +# 解释:偷窃 1 号房屋 (金额 = 2), 偷窃 3 号房屋 (金额 = 9),接着偷窃 5 号房屋 (金额 = 1)。 +#   偷窃到的最高金额 = 2 + 9 + 1 = 12 。 +# +# +# +# +# 提示: +# +# +# 1 <= nums.length <= 100 +# 0 <= nums[i] <= 400 +# +# Related Topics 数组 动态规划 +# 👍 2217 👎 0 + + +# leetcode submit region begin(Prohibit modification and deletion) +class Solution: + def rob(self, nums: List[int]) -> int: + l = len(nums) + dp = [0] * (l+1) + dp[1] = nums[0] + for i in range(2, l+1): + dp[i] = max(dp[i-1], dp[i-2]+nums[i-1]) + return dp[-1] +# leetcode submit region end(Prohibit modification and deletion) diff --git "a/script/[19]\345\210\240\351\231\244\351\223\276\350\241\250\347\232\204\345\200\222\346\225\260\347\254\254 N \344\270\252\347\273\223\347\202\271.py" "b/script/[19]\345\210\240\351\231\244\351\223\276\350\241\250\347\232\204\345\200\222\346\225\260\347\254\254 N \344\270\252\347\273\223\347\202\271.py" new file mode 100644 index 0000000..614aa16 --- /dev/null +++ "b/script/[19]\345\210\240\351\231\244\351\223\276\350\241\250\347\232\204\345\200\222\346\225\260\347\254\254 N \344\270\252\347\273\223\347\202\271.py" @@ -0,0 +1,64 @@ +# 给你一个链表,删除链表的倒数第 n 个结点,并且返回链表的头结点。 +# +# +# +# 示例 1: +# +# +# 输入:head = [1,2,3,4,5], n = 2 +# 输出:[1,2,3,5] +# +# +# 示例 2: +# +# +# 输入:head = [1], n = 1 +# 输出:[] +# +# +# 示例 3: +# +# +# 输入:head = [1,2], n = 1 +# 输出:[1] +# +# +# +# +# 提示: +# +# +# 链表中结点的数目为 sz +# 1 <= sz <= 30 +# 0 <= Node.val <= 100 +# 1 <= n <= sz +# +# +# +# +# 进阶:你能尝试使用一趟扫描实现吗? +# Related Topics 链表 双指针 +# 👍 2139 👎 0 + + +# leetcode submit region begin(Prohibit modification and deletion) +# Definition for singly-linked list. +# class ListNode: +# def __init__(self, val=0, next=None): +# self.val = val +# self.next = next +class Solution: + def removeNthFromEnd(self, head: ListNode, n: int) -> ListNode: + dummy = ListNode() + dummy.next = head + ptr1, ptr2 = dummy, dummy + for i in range(n): + ptr1 = ptr1.next + while ptr1.next: + ptr1 = ptr1.next + ptr2 = ptr2.next + ptr2.next = ptr2.next.next + return dummy.next + + +# leetcode submit region end(Prohibit modification and deletion) diff --git "a/script/[200]\345\262\233\345\261\277\346\225\260\351\207\217.py" "b/script/[200]\345\262\233\345\261\277\346\225\260\351\207\217.py" new file mode 100644 index 0000000..e6c216e --- /dev/null +++ "b/script/[200]\345\262\233\345\261\277\346\225\260\351\207\217.py" @@ -0,0 +1,67 @@ +# 给你一个由 '1'(陆地)和 '0'(水)组成的的二维网格,请你计算网格中岛屿的数量。 +# +# 岛屿总是被水包围,并且每座岛屿只能由水平方向和/或竖直方向上相邻的陆地连接形成。 +# +# 此外,你可以假设该网格的四条边均被水包围。 +# +# +# +# 示例 1: +# +# +# 输入:grid = [ +# ["1","1","1","1","0"], +# ["1","1","0","1","0"], +# ["1","1","0","0","0"], +# ["0","0","0","0","0"] +# ] +# 输出:1 +# +# +# 示例 2: +# +# +# 输入:grid = [ +# ["1","1","0","0","0"], +# ["1","1","0","0","0"], +# ["0","0","1","0","0"], +# ["0","0","0","1","1"] +# ] +# 输出:3 +# +# +# +# +# 提示: +# +# +# m == grid.length +# n == grid[i].length +# 1 <= m, n <= 300 +# grid[i][j] 的值为 '0' 或 '1' +# +# Related Topics 深度优先搜索 广度优先搜索 并查集 数组 矩阵 +# 👍 1816 👎 0 + + +# leetcode submit region begin(Prohibit modification and deletion) +class Solution: + def numIslands(self, grid: List[List[str]]) -> int: + def dfs(row, col): + for x,y in ([row-1,col], [row+1,col],[row, col-1],[row,col+1]): + if x>=0 and x=0 and y ListNode: + dummy = ListNode() + dummy.next = head + ptr =dummy + while dummy and dummy.next: + if dummy.next.val == val: + dummy.next = dummy.next.next + else: + dummy = dummy.next + return ptr.next +# leetcode submit region end(Prohibit modification and deletion) diff --git "a/script/[206]\345\217\215\350\275\254\351\223\276\350\241\250.py" "b/script/[206]\345\217\215\350\275\254\351\223\276\350\241\250.py" new file mode 100644 index 0000000..b40c97d --- /dev/null +++ "b/script/[206]\345\217\215\350\275\254\351\223\276\350\241\250.py" @@ -0,0 +1,61 @@ +# 给你单链表的头节点 head ,请你反转链表,并返回反转后的链表。 +# +# +# +# +# 示例 1: +# +# +# 输入:head = [1,2,3,4,5] +# 输出:[5,4,3,2,1] +# +# +# 示例 2: +# +# +# 输入:head = [1,2] +# 输出:[2,1] +# +# +# 示例 3: +# +# +# 输入:head = [] +# 输出:[] +# +# +# +# +# 提示: +# +# +# 链表中节点的数目范围是 [0, 5000] +# -5000 <= Node.val <= 5000 +# +# +# +# +# 进阶:链表可以选用迭代或递归方式完成反转。你能否用两种方法解决这道题? +# +# +# Related Topics 递归 链表 +# 👍 2647 👎 0 + + +# leetcode submit region begin(Prohibit modification and deletion) +# Definition for singly-linked list. +# class ListNode: +# def __init__(self, val=0, next=None): +# self.val = val +# self.next = next +class Solution: + def reverseList(self, head: ListNode) -> ListNode: + ptr = None + while head: + nextnode = head.next + head.next = ptr + ptr = head + head = nextnode + return ptr + +# leetcode submit region end(Prohibit modification and deletion) diff --git "a/script/[208]\345\256\236\347\216\260 Trie (\345\211\215\347\274\200\346\240\221).py" "b/script/[208]\345\256\236\347\216\260 Trie (\345\211\215\347\274\200\346\240\221).py" new file mode 100644 index 0000000..f9eea91 --- /dev/null +++ "b/script/[208]\345\256\236\347\216\260 Trie (\345\211\215\347\274\200\346\240\221).py" @@ -0,0 +1,101 @@ +# Trie(发音类似 "try")或者说 前缀树 是一种树形数据结构,用于高效地存储和检索字符串数据集中的键。这一数据结构有相当多的应用情景,例如自动补完和拼 +# 写检查。 +# +# 请你实现 Trie 类: +# +# +# Trie() 初始化前缀树对象。 +# void insert(String word) 向前缀树中插入字符串 word 。 +# boolean search(String word) 如果字符串 word 在前缀树中,返回 true(即,在检索之前已经插入);否则,返回 false +# 。 +# boolean startsWith(String prefix) 如果之前已经插入的字符串 word 的前缀之一为 prefix ,返回 true ;否 +# 则,返回 false 。 +# +# +# +# +# 示例: +# +# +# 输入 +# ["Trie", "insert", "search", "search", "startsWith", "insert", "search"] +# [[], ["apple"], ["apple"], ["app"], ["app"], ["app"], ["app"]] +# 输出 +# [null, null, true, false, true, null, true] +# +# 解释 +# Trie trie = new Trie(); +# trie.insert("apple"); +# trie.search("apple"); // 返回 True +# trie.search("app"); // 返回 False +# trie.startsWith("app"); // 返回 True +# trie.insert("app"); +# trie.search("app"); // 返回 True +# +# +# +# +# 提示: +# +# +# 1 <= word.length, prefix.length <= 2000 +# word 和 prefix 仅由小写英文字母组成 +# insert、search 和 startsWith 调用次数 总计 不超过 3 * 104 次 +# +# Related Topics 设计 字典树 哈希表 字符串 +# 👍 1255 👎 0 + + +# leetcode submit region begin(Prohibit modification and deletion) +class TreeNode(object): + def __init__(self, char=None): + self.char = char + self.is_end=False + self.children = {} + + def insert(self, c): + if c in self.children: + return self.children[c] + else: + self.children[c] = TreeNode(c) + return self.children[c] + + def search(self, c): + return self.children.get(c, None) +class Trie: + + def __init__(self): + self.root = TreeNode() + + def insert(self, word: str) -> None: + node = self.root + for c in word: + node = node.insert(c) + node.is_end=True + + def search(self, word: str) -> bool: + node = self.root + for c in word: + node = node.search(c) + if not node: + return False + if node.is_end: + return True + else: + return False + + def startsWith(self, prefix: str) -> bool: + node = self.root + for c in prefix: + node = node.search(c) + if not node: + return False + return True + + +# Your Trie object will be instantiated and called as such: +# obj = Trie() +# obj.insert(word) +# param_2 = obj.search(word) +# param_3 = obj.startsWith(prefix) +# leetcode submit region end(Prohibit modification and deletion) diff --git "a/script/[20]\346\234\211\346\225\210\347\232\204\346\213\254\345\217\267.py" "b/script/[20]\346\234\211\346\225\210\347\232\204\346\213\254\345\217\267.py" new file mode 100644 index 0000000..039e52d --- /dev/null +++ "b/script/[20]\346\234\211\346\225\210\347\232\204\346\213\254\345\217\267.py" @@ -0,0 +1,78 @@ +# 给定一个只包括 '(',')','{','}','[',']' 的字符串 s ,判断字符串是否有效。 +# +# 有效字符串需满足: +# +# +# 左括号必须用相同类型的右括号闭合。 +# 左括号必须以正确的顺序闭合。 +# +# +# +# +# 示例 1: +# +# +# 输入:s = "()" +# 输出:true +# +# +# 示例 2: +# +# +# 输入:s = "()[]{}" +# 输出:true +# +# +# 示例 3: +# +# +# 输入:s = "(]" +# 输出:false +# +# +# 示例 4: +# +# +# 输入:s = "([)]" +# 输出:false +# +# +# 示例 5: +# +# +# 输入:s = "{[]}" +# 输出:true +# +# +# +# 提示: +# +# +# 1 <= s.length <= 104 +# s 仅由括号 '()[]{}' 组成 +# +# Related Topics 栈 字符串 +# 👍 3410 👎 0 + + +# leetcode submit region begin(Prohibit modification and deletion) +class Solution: + def isValid(self, s: str) -> bool: + stack = [] + for i in s: + if i =='{': + stack.append('}') + elif i =='(': + stack.append(')') + elif i=='[': + stack.append(']') + else: + if stack and stack[-1]==i: + stack.pop() + else: + return False + if stack: + return False + else: + return True +# leetcode submit region end(Prohibit modification and deletion) diff --git "a/script/[213]\346\211\223\345\256\266\345\212\253\350\210\215 II.py" "b/script/[213]\346\211\223\345\256\266\345\212\253\350\210\215 II.py" new file mode 100644 index 0000000..87a1062 --- /dev/null +++ "b/script/[213]\346\211\223\345\256\266\345\212\253\350\210\215 II.py" @@ -0,0 +1,56 @@ +# 你是一个专业的小偷,计划偷窃沿街的房屋,每间房内都藏有一定的现金。这个地方所有的房屋都 围成一圈 ,这意味着第一个房屋和最后一个房屋是紧挨着的。同时,相邻的 +# 房屋装有相互连通的防盗系统,如果两间相邻的房屋在同一晚上被小偷闯入,系统会自动报警 。 +# +# 给定一个代表每个房屋存放金额的非负整数数组,计算你 在不触动警报装置的情况下 ,今晚能够偷窃到的最高金额。 +# +# +# +# 示例 1: +# +# +# 输入:nums = [2,3,2] +# 输出:3 +# 解释:你不能先偷窃 1 号房屋(金额 = 2),然后偷窃 3 号房屋(金额 = 2), 因为他们是相邻的。 +# +# +# 示例 2: +# +# +# 输入:nums = [1,2,3,1] +# 输出:4 +# 解释:你可以先偷窃 1 号房屋(金额 = 1),然后偷窃 3 号房屋(金额 = 3)。 +#   偷窃到的最高金额 = 1 + 3 = 4 。 +# +# 示例 3: +# +# +# 输入:nums = [1,2,3] +# 输出:3 +# +# +# +# +# 提示: +# +# +# 1 <= nums.length <= 100 +# 0 <= nums[i] <= 1000 +# +# Related Topics 数组 动态规划 +# 👍 1105 👎 0 + + +# leetcode submit region begin(Prohibit modification and deletion) +class Solution: + def rob(self, nums: List[int]) -> int: + def helper(nums): + l = len(nums) + dp = [0] * (l + 1) + dp[1] = nums[0] + for i in range(2, l + 1): + dp[i] = max(dp[i - 1], dp[i - 2] + nums[i - 1]) + return dp[-1] + if len(nums)==1: + return nums[0] + return max(helper(nums[1:]), helper(nums[:-1])) +# leetcode submit region end(Prohibit modification and deletion) diff --git "a/script/[215]\346\225\260\347\273\204\344\270\255\347\232\204\347\254\254K\344\270\252\346\234\200\345\244\247\345\205\203\347\264\240.py" "b/script/[215]\346\225\260\347\273\204\344\270\255\347\232\204\347\254\254K\344\270\252\346\234\200\345\244\247\345\205\203\347\264\240.py" new file mode 100644 index 0000000..923343c --- /dev/null +++ "b/script/[215]\346\225\260\347\273\204\344\270\255\347\232\204\347\254\254K\344\270\252\346\234\200\345\244\247\345\205\203\347\264\240.py" @@ -0,0 +1,61 @@ +# 给定整数数组 nums 和整数 k,请返回数组中第 k 个最大的元素。 +# +# 请注意,你需要找的是数组排序后的第 k 个最大的元素,而不是第 k 个不同的元素。 +# +# +# +# 示例 1: +# +# +# 输入: [3,2,1,5,6,4], k = 2 +# 输出: 5 +# +# +# 示例 2: +# +# +# 输入: [3,2,3,1,2,4,5,5,6], k = 4 +# 输出: 4 +# +# +# +# 提示: +# +# +# 1 <= k <= nums.length <= 105 +# -104 <= nums[i] <= 104 +# +# Related Topics 数组 分治 快速选择 排序 堆(优先队列) +# 👍 1787 👎 0 + + +# leetcode submit region begin(Prohibit modification and deletion) +class Solution: + def findKthLargest(self, nums: List[int], k: int) -> int: + def partition(nums, left, right): + key = left + while left=right: + return + mid = partition(nums, left, right) + if mid==k: + return + elif mid Optional[ListNode]: + node = ListNode() + ptr = node + while list1 and list2: + if list1.val < list2.val: + ptr.next = ListNode(list1.val) + list1 = list1.next + else: + ptr.next = ListNode(list2.val) + list2 = list2.next + ptr = ptr.next + + while list1: + ptr.next = ListNode(list1.val) + list1 = list1.next + ptr = ptr.next + while list2: + ptr.next = ListNode(list2.val) + list2 = list2.next + ptr = ptr.next + return node.next + + # leetcode submit region end(Prohibit modification and deletion) diff --git "a/script/[225]\347\224\250\351\230\237\345\210\227\345\256\236\347\216\260\346\240\210.py" "b/script/[225]\347\224\250\351\230\237\345\210\227\345\256\236\347\216\260\346\240\210.py" new file mode 100644 index 0000000..9c097e1 --- /dev/null +++ "b/script/[225]\347\224\250\351\230\237\345\210\227\345\256\236\347\216\260\346\240\210.py" @@ -0,0 +1,91 @@ +# 请你仅使用两个队列实现一个后入先出(LIFO)的栈,并支持普通栈的全部四种操作(push、top、pop 和 empty)。 +# +# 实现 MyStack 类: +# +# +# void push(int x) 将元素 x 压入栈顶。 +# int pop() 移除并返回栈顶元素。 +# int top() 返回栈顶元素。 +# boolean empty() 如果栈是空的,返回 true ;否则,返回 false 。 +# +# +# +# +# 注意: +# +# +# 你只能使用队列的基本操作 —— 也就是 push to back、peek/pop from front、size 和 is empty 这些操作。 +# 你所使用的语言也许不支持队列。 你可以使用 list (列表)或者 deque(双端队列)来模拟一个队列 , 只要是标准的队列操作即可。 +# +# +# +# +# 示例: +# +# +# 输入: +# ["MyStack", "push", "push", "top", "pop", "empty"] +# [[], [1], [2], [], [], []] +# 输出: +# [null, null, null, 2, 2, false] +# +# 解释: +# MyStack myStack = new MyStack(); +# myStack.push(1); +# myStack.push(2); +# myStack.top(); // 返回 2 +# myStack.pop(); // 返回 2 +# myStack.empty(); // 返回 False +# +# +# +# +# 提示: +# +# +# 1 <= x <= 9 +# 最多调用100 次 push、pop、top 和 empty +# 每次调用 pop 和 top 都保证栈不为空 +# +# +# +# +# 进阶:你能否仅用一个队列来实现栈。 +# Related Topics 栈 设计 队列 +# 👍 551 👎 0 + + +# leetcode submit region begin(Prohibit modification and deletion) +class MyStack: + from collections import deque + def __init__(self): + self.que = deque() + self.l = 0 + + def push(self, x: int) -> None: + self.que.append(x) + for i in range(self.l): + self.que.append(self.que.popleft()) + self.l+=1 + + def pop(self) -> int: + self.l-=1 + return self.que.popleft() + + + def top(self) -> int: + return self.que[0] + + + def empty(self) -> bool: + return self.l==0 + + + +# Your MyStack object will be instantiated and called as such: +# obj = MyStack() +# obj.push(x) +# param_2 = obj.pop() +# param_3 = obj.top() +# param_4 = obj.empty() +# leetcode submit region end(Prohibit modification and deletion) diff --git "a/script/[228]\346\261\207\346\200\273\345\214\272\351\227\264.py" "b/script/[228]\346\261\207\346\200\273\345\214\272\351\227\264.py" new file mode 100644 index 0000000..df148d7 --- /dev/null +++ "b/script/[228]\346\261\207\346\200\273\345\214\272\351\227\264.py" @@ -0,0 +1,72 @@ +# 给定一个 无重复元素 的 有序 整数数组 nums 。 +# +# 返回 恰好覆盖数组中所有数字 的 最小有序 区间范围列表 。也就是说,nums 的每个元素都恰好被某个区间范围所覆盖,并且不存在属于某个范围但不属于 nu +# ms 的数字 x 。 +# +# 列表中的每个区间范围 [a,b] 应该按如下格式输出: +# +# +# "a->b" ,如果 a != b +# "a" ,如果 a == b +# +# +# +# +# 示例 1: +# +# +# 输入:nums = [0,1,2,4,5,7] +# 输出:["0->2","4->5","7"] +# 解释:区间范围是: +# [0,2] --> "0->2" +# [4,5] --> "4->5" +# [7,7] --> "7" +# +# +# 示例 2: +# +# +# 输入:nums = [0,2,3,4,6,8,9] +# 输出:["0","2->4","6","8->9"] +# 解释:区间范围是: +# [0,0] --> "0" +# [2,4] --> "2->4" +# [6,6] --> "6" +# [8,9] --> "8->9" +# +# +# +# +# 提示: +# +# +# 0 <= nums.length <= 20 +# -231 <= nums[i] <= 231 - 1 +# nums 中的所有值都 互不相同 +# nums 按升序排列 +# +# Related Topics 数组 +# 👍 225 👎 0 + + +# leetcode submit region begin(Prohibit modification and deletion) +class Solution: + def summaryRanges(self, nums: List[int]) -> List[str]: + if len(nums)==0: + return [] + result = [] + tmp = [nums[0]] + for i in range(1, len(nums)): + if nums[i]-tmp[-1]==1: + if len(tmp)==2: + tmp[-1] = nums[i] + else: + tmp.append(nums[i]) + else: + result.append('->'.join((str(i) for i in tmp))) + tmp =[nums[i]] + if tmp: + result.append('->'.join((str(i) for i in tmp))) + return result + +# leetcode submit region end(Prohibit modification and deletion) diff --git "a/script/[232]\347\224\250\346\240\210\345\256\236\347\216\260\351\230\237\345\210\227.py" "b/script/[232]\347\224\250\346\240\210\345\256\236\347\216\260\351\230\237\345\210\227.py" new file mode 100644 index 0000000..c2a3b98 --- /dev/null +++ "b/script/[232]\347\224\250\346\240\210\345\256\236\347\216\260\351\230\237\345\210\227.py" @@ -0,0 +1,106 @@ +# 请你仅使用两个栈实现先入先出队列。队列应当支持一般队列支持的所有操作(push、pop、peek、empty): +# +# 实现 MyQueue 类: +# +# +# void push(int x) 将元素 x 推到队列的末尾 +# int pop() 从队列的开头移除并返回元素 +# int peek() 返回队列开头的元素 +# boolean empty() 如果队列为空,返回 true ;否则,返回 false +# +# +# 说明: +# +# +# 你 只能 使用标准的栈操作 —— 也就是只有 push to top, peek/pop from top, size, 和 is empty 操作是合法 +# 的。 +# 你所使用的语言也许不支持栈。你可以使用 list 或者 deque(双端队列)来模拟一个栈,只要是标准的栈操作即可。 +# +# +# +# +# 示例 1: +# +# +# 输入: +# ["MyQueue", "push", "push", "peek", "pop", "empty"] +# [[], [1], [2], [], [], []] +# 输出: +# [null, null, null, 1, 1, false] +# +# 解释: +# MyQueue myQueue = new MyQueue(); +# myQueue.push(1); // queue is: [1] +# myQueue.push(2); // queue is: [1, 2] (leftmost is front of the queue) +# myQueue.peek(); // return 1 +# myQueue.pop(); // return 1, queue is [2] +# myQueue.empty(); // return false +# +# +# +# +# +# +# +# 提示: +# +# +# 1 <= x <= 9 +# 最多调用 100 次 push、pop、peek 和 empty +# 假设所有操作都是有效的 (例如,一个空的队列不会调用 pop 或者 peek 操作) +# +# +# +# +# 进阶: +# +# +# 你能否实现每个操作均摊时间复杂度为 O(1) 的队列?换句话说,执行 n 个操作的总时间复杂度为 O(n) ,即使其中一个操作可能花费较长时间。 +# +# Related Topics 栈 设计 队列 +# 👍 712 👎 0 + + +# leetcode submit region begin(Prohibit modification and deletion) +class MyQueue: + + def __init__(self): + self.instack= [] + self.outstack = [] + + + def push(self, x: int) -> None: + self.instack.append(x) + + + def pop(self) -> int: + if self.outstack: + return self.outstack.pop() + else: + while self.instack: + self.outstack.append(self.instack.pop()) + return self.outstack.pop() + + + def peek(self) -> int: + if self.outstack: + return self.outstack[-1] + else: + return self.instack[0] + + + def empty(self) -> bool: + if self.outstack or self.instack: + return False + else: + return True + + + +# Your MyQueue object will be instantiated and called as such: +# obj = MyQueue() +# obj.push(x) +# param_2 = obj.pop() +# param_3 = obj.peek() +# param_4 = obj.empty() +# leetcode submit region end(Prohibit modification and deletion) diff --git "a/script/[234]\345\233\236\346\226\207\351\223\276\350\241\250.py" "b/script/[234]\345\233\236\346\226\207\351\223\276\350\241\250.py" new file mode 100644 index 0000000..c2c09d0 --- /dev/null +++ "b/script/[234]\345\233\236\346\226\207\351\223\276\350\241\250.py" @@ -0,0 +1,69 @@ +# 给你一个单链表的头节点 head ,请你判断该链表是否为回文链表。如果是,返回 true ;否则,返回 false 。 +# +# +# +# 示例 1: +# +# +# 输入:head = [1,2,2,1] +# 输出:true +# +# +# 示例 2: +# +# +# 输入:head = [1,2] +# 输出:false +# +# +# +# +# 提示: +# +# +# 链表中节点数目在范围[1, 105] 内 +# 0 <= Node.val <= 9 +# +# +# +# +# 进阶:你能否用 O(n) 时间复杂度和 O(1) 空间复杂度解决此题? +# Related Topics 栈 递归 链表 双指针 +# 👍 1451 👎 0 + + +# leetcode submit region begin(Prohibit modification and deletion) +# Definition for singly-linked list. +# class ListNode: +# def __init__(self, val=0, next=None): +# self.val = val +# self.next = next +class Solution: + def isPalindrome(self, head: ListNode) -> bool: + def reverse(head): + newnode = None + while head: + nextnode = head.next + head.next=newnode + newnode = head + head = nextnode + return newnode + + def getmid(head): + slow, fast = head, head + while fast and fast.next: + slow = slow.next + fast = fast.next.next + return slow + + ptr1 = head + ptr2 = getmid(head) + ptr2 = reverse(ptr2) + while ptr1 and ptr2: + if ptr1.val !=ptr2.val: + return False + ptr1 = ptr1.next + ptr2 = ptr2.next + return True + +# leetcode submit region end(Prohibit modification and deletion) diff --git "a/script/[237]\345\210\240\351\231\244\351\223\276\350\241\250\344\270\255\347\232\204\350\212\202\347\202\271.py" "b/script/[237]\345\210\240\351\231\244\351\223\276\350\241\250\344\270\255\347\232\204\350\212\202\347\202\271.py" new file mode 100644 index 0000000..a8c5d91 --- /dev/null +++ "b/script/[237]\345\210\240\351\231\244\351\223\276\350\241\250\344\270\255\347\232\204\350\212\202\347\202\271.py" @@ -0,0 +1,52 @@ +# 请编写一个函数,用于 删除单链表中某个特定节点 。在设计函数时需要注意,你无法访问链表的头节点 head ,只能直接访问 要被删除的节点 。 +# +# 题目数据保证需要删除的节点 不是末尾节点 。 +# +# +# +# 示例 1: +# +# +# 输入:head = [4,5,1,9], node = 5 +# 输出:[4,1,9] +# 解释:指定链表中值为 5 的第二个节点,那么在调用了你的函数之后,该链表应变为 4 -> 1 -> 9 +# +# +# 示例 2: +# +# +# 输入:head = [4,5,1,9], node = 1 +# 输出:[4,5,9] +# 解释:指定链表中值为 1 的第三个节点,那么在调用了你的函数之后,该链表应变为 4 -> 5 -> 9 +# +# +# +# 提示: +# +# +# 链表中节点的数目范围是 [2, 1000] +# -1000 <= Node.val <= 1000 +# 链表中每个节点的值都是 唯一 的 +# 需要删除的节点 node 是 链表中的节点 ,且 不是末尾节点 +# +# Related Topics 链表 +# 👍 1168 👎 0 + + +# leetcode submit region begin(Prohibit modification and deletion) +# Definition for singly-linked list. +# class ListNode: +# def __init__(self, x): +# self.val = x +# self.next = None + +class Solution: + def deleteNode(self, node): + """ + :type node: ListNode + :rtype: void Do not return anything, modify node in-place instead. + """ + node.val = node.next.val + node.next = node.next.next + +# leetcode submit region end(Prohibit modification and deletion) diff --git "a/script/[238]\351\231\244\350\207\252\350\272\253\344\273\245\345\244\226\346\225\260\347\273\204\347\232\204\344\271\230\347\247\257.py" "b/script/[238]\351\231\244\350\207\252\350\272\253\344\273\245\345\244\226\346\225\260\347\273\204\347\232\204\344\271\230\347\247\257.py" new file mode 100644 index 0000000..311191f --- /dev/null +++ "b/script/[238]\351\231\244\350\207\252\350\272\253\344\273\245\345\244\226\346\225\260\347\273\204\347\232\204\344\271\230\347\247\257.py" @@ -0,0 +1,54 @@ +# 给你一个整数数组 nums,返回 数组 answer ,其中 answer[i] 等于 nums 中除 nums[i] 之外其余各元素的乘积 。 +# +# 题目数据 保证 数组 nums之中任意元素的全部前缀元素和后缀的乘积都在 32 位 整数范围内。 +# +# 请不要使用除法,且在 O(n) 时间复杂度内完成此题。 +# +# +# +# 示例 1: +# +# +# 输入: nums = [1,2,3,4] +# 输出: [24,12,8,6] +# +# +# 示例 2: +# +# +# 输入: nums = [-1,1,0,-3,3] +# 输出: [0,0,9,0,0] +# +# +# +# +# 提示: +# +# +# 2 <= nums.length <= 105 +# -30 <= nums[i] <= 30 +# 保证 数组 nums之中任意元素的全部前缀元素和后缀的乘积都在 32 位 整数范围内 +# +# +# +# +# 进阶:你可以在 O(1) 的额外空间复杂度内完成这个题目吗?( 出于对空间复杂度分析的目的,输出数组不被视为额外空间。) +# Related Topics 数组 前缀和 +# 👍 1212 👎 0 + + +# leetcode submit region begin(Prohibit modification and deletion) +class Solution: + def productExceptSelf(self, nums: List[int]) -> List[int]: + l = len(nums) + answers= [1] * l + # 每个数左边的 + for i in range(1, l): + answers[i] *= answers[i-1] * nums[i-1] + # 每个数右边的 + R=1 + for i in range(l-1,-1,-1): + answers[i] = answers[i] * R + R*=nums[i] + return answers +# leetcode submit region end(Prohibit modification and deletion) diff --git "a/script/[239]\346\273\221\345\212\250\347\252\227\345\217\243\346\234\200\345\244\247\345\200\274.py" "b/script/[239]\346\273\221\345\212\250\347\252\227\345\217\243\346\234\200\345\244\247\345\200\274.py" new file mode 100644 index 0000000..b6412bb --- /dev/null +++ "b/script/[239]\346\273\221\345\212\250\347\252\227\345\217\243\346\234\200\345\244\247\345\200\274.py" @@ -0,0 +1,67 @@ +# 给你一个整数数组 nums,有一个大小为 k 的滑动窗口从数组的最左侧移动到数组的最右侧。你只可以看到在滑动窗口内的 k 个数字。滑动窗口每次只向右移动一位 +# 。 +# +# 返回 滑动窗口中的最大值 。 +# +# +# +# 示例 1: +# +# +# 输入:nums = [1,3,-1,-3,5,3,6,7], k = 3 +# 输出:[3,3,5,5,6,7] +# 解释: +# 滑动窗口的位置 最大值 +# --------------- ----- +# [1 3 -1] -3 5 3 6 7 3 +# 1 [3 -1 -3] 5 3 6 7 3 +# 1 3 [-1 -3 5] 3 6 7 5 +# 1 3 -1 [-3 5 3] 6 7 5 +# 1 3 -1 -3 [5 3 6] 7 6 +# 1 3 -1 -3 5 [3 6 7] 7 +# +# +# 示例 2: +# +# +# 输入:nums = [1], k = 1 +# 输出:[1] +# +# +# +# +# 提示: +# +# +# 1 <= nums.length <= 105 +# -104 <= nums[i] <= 104 +# 1 <= k <= nums.length +# +# Related Topics 队列 数组 滑动窗口 单调队列 堆(优先队列) +# 👍 1759 👎 0 + + +# leetcode submit region begin(Prohibit modification and deletion) +class Solution: + def maxSlidingWindow(self, nums: List[int], k: int) -> List[int]: + from collections import deque + que = deque([nums[0]]) + # 维护一个k个元素内部的单调减的队列 + for i in range(1, k): + while que and nums[i]>que[-1]: + que.pop() + que.append(nums[i]) + result = [] + for i in range(k, len(nums)): + result.append(que[0]) + if nums[i-k]==que[0]: + que.popleft() + while que and nums[i]>que[-1]: + que.pop() + que.append(nums[i]) + result.append(que[0]) + + return result + + +# leetcode submit region end(Prohibit modification and deletion) diff --git "a/script/[23]\345\220\210\345\271\266K\344\270\252\345\215\207\345\272\217\351\223\276\350\241\250.py" "b/script/[23]\345\220\210\345\271\266K\344\270\252\345\215\207\345\272\217\351\223\276\350\241\250.py" new file mode 100644 index 0000000..c6b309d --- /dev/null +++ "b/script/[23]\345\220\210\345\271\266K\344\270\252\345\215\207\345\272\217\351\223\276\350\241\250.py" @@ -0,0 +1,84 @@ +# 给你一个链表数组,每个链表都已经按升序排列。 +# +# 请你将所有链表合并到一个升序链表中,返回合并后的链表。 +# +# +# +# 示例 1: +# +# 输入:lists = [[1,4,5],[1,3,4],[2,6]] +# 输出:[1,1,2,3,4,4,5,6] +# 解释:链表数组如下: +# [ +# 1->4->5, +# 1->3->4, +# 2->6 +# ] +# 将它们合并到一个有序链表中得到。 +# 1->1->2->3->4->4->5->6 +# +# +# 示例 2: +# +# 输入:lists = [] +# 输出:[] +# +# +# 示例 3: +# +# 输入:lists = [[]] +# 输出:[] +# +# +# +# +# 提示: +# +# +# k == lists.length +# 0 <= k <= 10^4 +# 0 <= lists[i].length <= 500 +# -10^4 <= lists[i][j] <= 10^4 +# lists[i] 按 升序 排列 +# lists[i].length 的总和不超过 10^4 +# +# Related Topics 链表 分治 堆(优先队列) 归并排序 +# 👍 2074 👎 0 + + +# leetcode submit region begin(Prohibit modification and deletion) +# Definition for singly-linked list. +# class ListNode: +# def __init__(self, val=0, next=None): +# self.val = val +# self.next = next +class Solution: + def mergeKLists(self, lists: List[Optional[ListNode]]) -> Optional[ListNode]: + if not lists: + return None + def sort_merge(l1, l2): + ptr = ListNode() + head =ptr + while l1 and l2: + if l1.val < l2.val: + ptr.next = ListNode(l1.val) + l1 = l1.next + else: + ptr.next = ListNode(l2.val) + l2 = l2.next + ptr = ptr.next + if l1: + ptr.next =l1 + if l2: + ptr.next =l2 + return head.next + + def dfs(start, end): + if start==end: + return lists[start] + mid = (start+end)//2 + left = dfs(start, mid) + right = dfs(mid+1, end) + return sort_merge(left, right) + return dfs(0, len(lists)-1) +# leetcode submit region end(Prohibit modification and deletion) diff --git "a/script/[241]\344\270\272\350\277\220\347\256\227\350\241\250\350\276\276\345\274\217\350\256\276\350\256\241\344\274\230\345\205\210\347\272\247.py" "b/script/[241]\344\270\272\350\277\220\347\256\227\350\241\250\350\276\276\345\274\217\350\256\276\350\256\241\344\274\230\345\205\210\347\272\247.py" new file mode 100644 index 0000000..d9b9de5 --- /dev/null +++ "b/script/[241]\344\270\272\350\277\220\347\256\227\350\241\250\350\276\276\345\274\217\350\256\276\350\256\241\344\274\230\345\205\210\347\272\247.py" @@ -0,0 +1,66 @@ +# 给你一个由数字和运算符组成的字符串 expression ,按不同优先级组合数字和运算符,计算并返回所有可能组合的结果。你可以 按任意顺序 返回答案。 +# +# 生成的测试用例满足其对应输出值符合 32 位整数范围,不同结果的数量不超过 104 。 +# +# +# +# 示例 1: +# +# +# 输入:expression = "2-1-1" +# 输出:[0,2] +# 解释: +# ((2-1)-1) = 0 +# (2-(1-1)) = 2 +# +# +# 示例 2: +# +# +# 输入:expression = "2*3-4*5" +# 输出:[-34,-14,-10,-10,10] +# 解释: +# (2*(3-(4*5))) = -34 +# ((2*3)-(4*5)) = -14 +# ((2*(3-4))*5) = -10 +# (2*((3-4)*5)) = -10 +# (((2*3)-4)*5) = 10 +# +# +# +# +# 提示: +# +# +# 1 <= expression.length <= 20 +# expression 由数字和算符 '+'、'-' 和 '*' 组成。 +# 输入表达式中的所有整数值在范围 [0, 99] +# +# Related Topics 递归 记忆化搜索 数学 字符串 动态规划 +# 👍 732 👎 0 + + +# leetcode submit region begin(Prohibit modification and deletion) +class Solution: + def diffWaysToCompute(self, expression: str) -> List[int]: + hash = {} + def dfs(expression): + if expression.isdigit(): + return [int(expression)] + if expression in hash: + return hash[expression] + res = [] + for i, n in enumerate(expression): + if n in ['+','-','*','']: + left= dfs(expression[:i]) + right=dfs(expression[(i+1):]) + for l in left: + for r in right: + res.append(eval('{}{}{}'.format(l,n,r))) + hash[expression] = res + return res + return dfs(expression) + + + +# leetcode submit region end(Prohibit modification and deletion) diff --git "a/script/[24]\344\270\244\344\270\244\344\272\244\346\215\242\351\223\276\350\241\250\344\270\255\347\232\204\350\212\202\347\202\271.py" "b/script/[24]\344\270\244\344\270\244\344\272\244\346\215\242\351\223\276\350\241\250\344\270\255\347\232\204\350\212\202\347\202\271.py" new file mode 100644 index 0000000..e4409d6 --- /dev/null +++ "b/script/[24]\344\270\244\344\270\244\344\272\244\346\215\242\351\223\276\350\241\250\344\270\255\347\232\204\350\212\202\347\202\271.py" @@ -0,0 +1,58 @@ +# 给你一个链表,两两交换其中相邻的节点,并返回交换后链表的头节点。你必须在不修改节点内部的值的情况下完成本题(即,只能进行节点交换)。 +# +# +# +# 示例 1: +# +# +# 输入:head = [1,2,3,4] +# 输出:[2,1,4,3] +# +# +# 示例 2: +# +# +# 输入:head = [] +# 输出:[] +# +# +# 示例 3: +# +# +# 输入:head = [1] +# 输出:[1] +# +# +# +# +# 提示: +# +# +# 链表中节点的数目在范围 [0, 100] 内 +# 0 <= Node.val <= 100 +# +# Related Topics 递归 链表 +# 👍 1478 👎 0 + + +# leetcode submit region begin(Prohibit modification and deletion) +# Definition for singly-linked list. +# class ListNode: +# def __init__(self, val=0, next=None): +# self.val = val +# self.next = next +class Solution: + def swapPairs(self, head: ListNode) -> ListNode: + dummy = ListNode() + dummy.next =head + ptr = dummy + while ptr.next and ptr.next.next: + n1 = ptr.next + n2 = ptr.next.next + n1.next = n2.next + ptr.next = n2 + n2.next = n1 + ptr = n1 + return dummy.next + +# leetcode submit region end(Prohibit modification and deletion) diff --git "a/script/[279]\345\256\214\345\205\250\345\271\263\346\226\271\346\225\260.py" "b/script/[279]\345\256\214\345\205\250\345\271\263\346\226\271\346\225\260.py" new file mode 100644 index 0000000..0328d7e --- /dev/null +++ "b/script/[279]\345\256\214\345\205\250\345\271\263\346\226\271\346\225\260.py" @@ -0,0 +1,41 @@ +# 给你一个整数 n ,返回 和为 n 的完全平方数的最少数量 。 +# +# 完全平方数 是一个整数,其值等于另一个整数的平方;换句话说,其值等于一个整数自乘的积。例如,1、4、9 和 16 都是完全平方数,而 3 和 11 不是。 +# +# +# +# +# 示例 1: +# +# +# 输入:n = 12 +# 输出:3 +# 解释:12 = 4 + 4 + 4 +# +# 示例 2: +# +# +# 输入:n = 13 +# 输出:2 +# 解释:13 = 4 + 9 +# +# +# 提示: +# +# +# 1 <= n <= 104 +# +# Related Topics 广度优先搜索 数学 动态规划 +# 👍 1440 👎 0 + + +# leetcode submit region begin(Prohibit modification and deletion) +class Solution: + def numSquares(self, n: int) -> int: + dp = [n] * (n+1) + dp[0]=0 + for i in range(1,int(n**0.5)+1): + for j in range(i**2,n+1): + dp[j] = min(dp[j], dp[j-i**2]+1) + return dp[-1] +# leetcode submit region end(Prohibit modification and deletion) diff --git "a/script/[28]\345\256\236\347\216\260 strStr().py" "b/script/[28]\345\256\236\347\216\260 strStr().py" new file mode 100644 index 0000000..2a6f077 --- /dev/null +++ "b/script/[28]\345\256\236\347\216\260 strStr().py" @@ -0,0 +1,76 @@ +# 实现 strStr() 函数。 +# +# 给你两个字符串 haystack 和 needle ,请你在 haystack 字符串中找出 needle 字符串出现的第一个位置(下标从 0 开始)。如 +# 果不存在,则返回 -1 。 +# +# 说明: +# +# 当 needle 是空字符串时,我们应当返回什么值呢?这是一个在面试中很好的问题。 +# +# 对于本题而言,当 needle 是空字符串时我们应当返回 0 。这与 C 语言的 strstr() 以及 Java 的 indexOf() 定义相符。 +# +# +# +# 示例 1: +# +# +# 输入:haystack = "hello", needle = "ll" +# 输出:2 +# +# +# 示例 2: +# +# +# 输入:haystack = "aaaaa", needle = "bba" +# 输出:-1 +# +# +# +# +# 提示: +# +# +# 1 <= haystack.length, needle.length <= 104 +# haystack 和 needle 仅由小写英文字符组成 +# +# Related Topics 双指针 字符串 字符串匹配 +# 👍 1520 👎 0 + + +# leetcode submit region begin(Prohibit modification and deletion) +class Solution: + def strStr(self, haystack: str, needle: str) -> int: + def getnext(needle): + l = len(needle) + ptr1 = 0 + ptr2 = -1 + next = [-1] * l #相同前缀长度 + while ptr1<(l-1): + if ptr2==-1 or needle[ptr1] ==needle[ptr2]: + # 每一步更新的是下一个字符的前缀长度 + ptr1+=1 #下一个字符 + ptr2+=1 # 从哪一个位置开始匹配 + next[ptr1] = ptr2 + else: + # 上一个字符匹配到的位置重新开始匹配 + ptr2 = next[ptr2] + return next + next = getnext(needle) + l1 = len(haystack) + l2 = len(needle) + ptr1 =0 + ptr2 =0 + while ptr1 Optional[ListNode]: + total = 0 + remainder =0 + def helper(l1, l2): + if l1 and l2: + return l1.val +l2.val + elif l1: + return l1.val + else: + return l2.val + + node = ListNode() + ptr = node + while l1 or l2: + val = helper(l1,l2) + remainder + remainder = val//10 + node.next = ListNode(val%10) + node = node.next + if l1: + l1 = l1.next + if l2: + l2 = l2.next + if remainder: + node.next =ListNode(1) + return ptr.next +# leetcode submit region end(Prohibit modification and deletion) diff --git "a/script/[300]\346\234\200\351\225\277\351\200\222\345\242\236\345\255\220\345\272\217\345\210\227.py" "b/script/[300]\346\234\200\351\225\277\351\200\222\345\242\236\345\255\220\345\272\217\345\210\227.py" new file mode 100644 index 0000000..91e9755 --- /dev/null +++ "b/script/[300]\346\234\200\351\225\277\351\200\222\345\242\236\345\255\220\345\272\217\345\210\227.py" @@ -0,0 +1,62 @@ +# 给你一个整数数组 nums ,找到其中最长严格递增子序列的长度。 +# +# 子序列 是由数组派生而来的序列,删除(或不删除)数组中的元素而不改变其余元素的顺序。例如,[3,6,2,7] 是数组 [0,3,1,6,2,2,7] 的子 +# 序列。 +# +# +# 示例 1: +# +# +# 输入:nums = [10,9,2,5,3,7,101,18] +# 输出:4 +# 解释:最长递增子序列是 [2,3,7,101],因此长度为 4 。 +# +# +# 示例 2: +# +# +# 输入:nums = [0,1,0,3,2,3] +# 输出:4 +# +# +# 示例 3: +# +# +# 输入:nums = [7,7,7,7,7,7,7] +# 输出:1 +# +# +# +# +# 提示: +# +# +# 1 <= nums.length <= 2500 +# -104 <= nums[i] <= 104 +# +# +# +# +# 进阶: +# +# +# 你能将算法的时间复杂度降低到 O(n log(n)) 吗? +# +# Related Topics 数组 二分查找 动态规划 +# 👍 2649 👎 0 + + +# leetcode submit region begin(Prohibit modification and deletion) +class Solution: + def lengthOfLIS(self, nums: List[int]) -> int: + l = len(nums) + dp = [1] * l + maxlen = 1 + for i in range(1, l): + for j in range(i): + if nums[i]>nums[j]: + dp[i] = max(dp[i], dp[j]+1) + maxlen = max(maxlen, dp[i]) + return maxlen + +# leetcode submit region end(Prohibit modification and deletion) diff --git "a/script/[309]\346\234\200\344\275\263\344\271\260\345\215\226\350\202\241\347\245\250\346\227\266\346\234\272\345\220\253\345\206\267\345\206\273\346\234\237.py" "b/script/[309]\346\234\200\344\275\263\344\271\260\345\215\226\350\202\241\347\245\250\346\227\266\346\234\272\345\220\253\345\206\267\345\206\273\346\234\237.py" new file mode 100644 index 0000000..42aadf4 --- /dev/null +++ "b/script/[309]\346\234\200\344\275\263\344\271\260\345\215\226\350\202\241\347\245\250\346\227\266\346\234\272\345\220\253\345\206\267\345\206\273\346\234\237.py" @@ -0,0 +1,58 @@ +# 给定一个整数数组 prices,其中第 prices[i] 表示第 i 天的股票价格 。 +# +# 设计一个算法计算出最大利润。在满足以下约束条件下,你可以尽可能地完成更多的交易(多次买卖一支股票): +# +# +# 卖出股票后,你无法在第二天买入股票 (即冷冻期为 1 天)。 +# +# +# 注意:你不能同时参与多笔交易(你必须在再次购买前出售掉之前的股票)。 +# +# +# +# 示例 1: +# +# +# 输入: prices = [1,2,3,0,2] +# 输出: 3 +# 解释: 对应的交易状态为: [买入, 卖出, 冷冻期, 买入, 卖出] +# +# 示例 2: + +# +# +# 输入: prices = [1] +# 输出: 0 +# +# +# +# +# 提示: +# +# +# 1 <= prices.length <= 5000 +# 0 <= prices[i] <= 1000 +# +# Related Topics 数组 动态规划 +# 👍 1272 👎 0 + + +# leetcode submit region begin(Prohibit modification and deletion) +class Solution: + def maxProfit(self, prices: List[int]) -> int: + #状态买入,T卖出,T-1卖出,T-2卖出 + l = len(prices) + b = [0] * l + s1 = [0] * l # 当天卖出 + s2 = [0] * l # T-1卖出 + s3 = [0] * l # T-2之前卖出 + b[0] = -prices[0] + for i in range(1, l): + b[i] = max(b[i-1], s3[i-1]-prices[i], s2[i-1]-prices[i]) + s1[i] = b[i-1]+prices[i] + s2[i] = s1[i-1] + s3[i] = max(s3[i-1], s2[i-1]) + return max(s1[-1],s2[-1],s3[-1]) + + +# leetcode submit region end(Prohibit modification and deletion) diff --git "a/script/[316]\345\216\273\351\231\244\351\207\215\345\244\215\345\255\227\346\257\215.py" "b/script/[316]\345\216\273\351\231\244\351\207\215\345\244\215\345\255\227\346\257\215.py" new file mode 100644 index 0000000..c34012c --- /dev/null +++ "b/script/[316]\345\216\273\351\231\244\351\207\215\345\244\215\345\255\227\346\257\215.py" @@ -0,0 +1,52 @@ +# 给你一个字符串 s ,请你去除字符串中重复的字母,使得每个字母只出现一次。需保证 返回结果的字典序最小(要求不能打乱其他字符的相对位置)。 +# +# +# +# 示例 1: +# +# +# 输入:s = "bcabc" +# 输出:"abc" +# +# +# 示例 2: +# +# +# 输入:s = "cbacdcbc" +# 输出:"acdb" +# +# +# +# 提示: +# +# +# 1 <= s.length <= 104 +# s 由小写英文字母组成 +# +# +# +# +# 注意:该题与 1081 https://leetcode-cn.com/problems/smallest-subsequence-of-distinct +# -characters 相同 +# Related Topics 栈 贪心 字符串 单调栈 +# 👍 775 👎 0 + + +# leetcode submit region begin(Prohibit modification and deletion) +class Solution: + def removeDuplicateLetters(self, s: str) -> str: + from collections import Counter + hash = Counter(s) + stack = [] + seen = set() + # seen 判断是否入栈,hash判断是否出栈 + for i in s: + if i not in seen: + while stack and hash[stack[-1]]>0 and i int: + dp = [amount+1] * (amount+1) + dp[0]=0 + for c in coins: + for i in range(c, amount+1): + dp[i] = min(dp[i], dp[i-c]+1) + + if dp[-1]> amount: + return -1 + else: + return dp[-1] +# leetcode submit region end(Prohibit modification and deletion) diff --git "a/script/[328]\345\245\207\345\201\266\351\223\276\350\241\250.py" "b/script/[328]\345\245\207\345\201\266\351\223\276\350\241\250.py" new file mode 100644 index 0000000..9a5b89b --- /dev/null +++ "b/script/[328]\345\245\207\345\201\266\351\223\276\350\241\250.py" @@ -0,0 +1,62 @@ +# 给定单链表的头节点 head ,将所有索引为奇数的节点和索引为偶数的节点分别组合在一起,然后返回重新排序的列表。 +# +# 第一个节点的索引被认为是 奇数 , 第二个节点的索引为 偶数 ,以此类推。 +# +# 请注意,偶数组和奇数组内部的相对顺序应该与输入时保持一致。 +# +# 你必须在 O(1) 的额外空间复杂度和 O(n) 的时间复杂度下解决这个问题。 +# +# +# +# 示例 1: +# +# +# +# +# 输入: head = [1,2,3,4,5] +# 输出: [1,3,5,2,4] +# +# 示例 2: +# +# +# +# +# 输入: head = [2,1,3,5,6,4,7] +# 输出: [2,3,6,7,1,5,4] +# +# +# +# 提示: +# +# +# n == 链表中的节点数 +# 0 <= n <= 104 +# -106 <= Node.val <= 106 +# +# Related Topics 链表 +# 👍 619 👎 0 + + +# leetcode submit region begin(Prohibit modification and deletion) +# Definition for singly-linked list. +# class ListNode: +# def __init__(self, val=0, next=None): +# self.val = val +# self.next = next +class Solution: + def oddEvenList(self, head: Optional[ListNode]) -> Optional[ListNode]: + if not head: + return head + odd = head + even = head.next + # 注意这里因为偶数在前,用偶数作为停止条件的判断 + ptr1, ptr2 = odd,even + while even and even.next: + odd.next = even.next + odd = odd.next + even.next = odd.next + even = even.next + odd.next = ptr2 + return ptr1 + +# leetcode submit region end(Prohibit modification and deletion) diff --git "a/script/[32]\346\234\200\351\225\277\346\234\211\346\225\210\346\213\254\345\217\267.py" "b/script/[32]\346\234\200\351\225\277\346\234\211\346\225\210\346\213\254\345\217\267.py" new file mode 100644 index 0000000..8374a69 --- /dev/null +++ "b/script/[32]\346\234\200\351\225\277\346\234\211\346\225\210\346\213\254\345\217\267.py" @@ -0,0 +1,59 @@ +# 给你一个只包含 '(' 和 ')' 的字符串,找出最长有效(格式正确且连续)括号子串的长度。 +# +# +# +# +# +# 示例 1: +# +# +# 输入:s = "(()" +# 输出:2 +# 解释:最长有效括号子串是 "()" +# +# +# 示例 2: +# +# +# 输入:s = ")()())" +# 输出:4 +# 解释:最长有效括号子串是 "()()" +# +# +# 示例 3: +# +# +# 输入:s = "" +# 输出:0 +# +# +# +# +# 提示: +# +# +# 0 <= s.length <= 3 * 104 +# s[i] 为 '(' 或 ')' +# +# +# +# Related Topics 栈 字符串 动态规划 +# 👍 1922 👎 0 + + +# leetcode submit region begin(Prohibit modification and deletion) +class Solution: + def longestValidParentheses(self, s: str) -> int: + maxl = 0 + stack = [-1] + for i in range(len(s)): + if s[i]=='(': + stack.append(i) + else: + stack.pop() # + if not stack: + stack.append(i) # 右括号隔断情况 + else: + maxl = max(maxl, i-stack[-1]) + return maxl +# leetcode submit region end(Prohibit modification and deletion) diff --git "a/script/[337]\346\211\223\345\256\266\345\212\253\350\210\215 III.py" "b/script/[337]\346\211\223\345\256\266\345\212\253\350\210\215 III.py" new file mode 100644 index 0000000..5083441 --- /dev/null +++ "b/script/[337]\346\211\223\345\256\266\345\212\253\350\210\215 III.py" @@ -0,0 +1,62 @@ +# 小偷又发现了一个新的可行窃的地区。这个地区只有一个入口,我们称之为 root 。 +# +# 除了 root 之外,每栋房子有且只有一个“父“房子与之相连。一番侦察之后,聪明的小偷意识到“这个地方的所有房屋的排列类似于一棵二叉树”。 如果 两个直接 +# 相连的房子在同一天晚上被打劫 ,房屋将自动报警。 +# +# 给定二叉树的 root 。返回 在不触动警报的情况下 ,小偷能够盗取的最高金额 。 +# +# +# +# 示例 1: +# +# +# +# +# 输入: root = [3,2,3,null,3,null,1] +# 输出: 7 +# 解释: 小偷一晚能够盗取的最高金额 3 + 3 + 1 = 7 +# +# 示例 2: +# +# +# +# +# 输入: root = [3,4,5,1,3,null,1] +# 输出: 9 +# 解释: 小偷一晚能够盗取的最高金额 4 + 5 = 9 +# +# +# +# +# 提示: +# +# +# +# +# 树的节点数在 [1, 104] 范围内 +# 0 <= Node.val <= 104 +# +# Related Topics 树 深度优先搜索 动态规划 二叉树 +# 👍 1372 👎 0 + + +# leetcode submit region begin(Prohibit modification and deletion) +# Definition for a binary tree node. +# class TreeNode: +# def __init__(self, val=0, left=None, right=None): +# self.val = val +# self.left = left +# self.right = right +class Solution: + def rob(self, root: TreeNode) -> int: + def dfs(root): + if not root: + return 0,0 + left_y, left_n = dfs(root.left) + right_y, right_n = dfs(root.right) + mid_y = root.val + left_n + right_n + #不偷当前节点可以选择偷/或者不偷子节点 + mid_n = max(left_y,left_n) + max(right_y,right_n) + return mid_y, mid_n + return max(dfs(root)) +# leetcode submit region end(Prohibit modification and deletion) diff --git "a/script/[343]\346\225\264\346\225\260\346\213\206\345\210\206.py" "b/script/[343]\346\225\264\346\225\260\346\213\206\345\210\206.py" new file mode 100644 index 0000000..b9e37ad --- /dev/null +++ "b/script/[343]\346\225\264\346\225\260\346\213\206\345\210\206.py" @@ -0,0 +1,40 @@ +# 给定一个正整数 n ,将其拆分为 k 个 正整数 的和( k >= 2 ),并使这些整数的乘积最大化。 +# +# 返回 你可以获得的最大乘积 。 +# +# +# +# 示例 1: +# +# +# 输入: n = 2 +# 输出: 1 +# 解释: 2 = 1 + 1, 1 × 1 = 1。 +# +# 示例 2: +# +# +# 输入: n = 10 +# 输出: 36 +# 解释: 10 = 3 + 3 + 4, 3 × 3 × 4 = 36。 +# +# +# +# 提示: +# +# +# 2 <= n <= 58 +# +# Related Topics 数学 动态规划 +# 👍 873 👎 0 + +# leetcode submit region begin(Prohibit modification and deletion) +class Solution: + def integerBreak(self, n: int) -> int: + dp = [1] * (n+1) + for i in range(3, n+1): + for j in range(1, i-1): + dp[i] = max(dp[i], (i-j)*j, (i-j)*dp[j]) + return dp[-1] + +# leetcode submit region end(Prohibit modification and deletion) diff --git "a/script/[347]\345\211\215 K \344\270\252\351\253\230\351\242\221\345\205\203\347\264\240.py" "b/script/[347]\345\211\215 K \344\270\252\351\253\230\351\242\221\345\205\203\347\264\240.py" new file mode 100644 index 0000000..5395ac4 --- /dev/null +++ "b/script/[347]\345\211\215 K \344\270\252\351\253\230\351\242\221\345\205\203\347\264\240.py" @@ -0,0 +1,69 @@ +# 给你一个整数数组 nums 和一个整数 k ,请你返回其中出现频率前 k 高的元素。你可以按 任意顺序 返回答案。 +# +# +# +# 示例 1: +# +# +# 输入: nums = [1,1,1,2,2,3], k = 2 +# 输出: [1,2] +# +# +# 示例 2: +# +# +# 输入: nums = [1], k = 1 +# 输出: [1] +# +# +# +# 提示: +# +# +# 1 <= nums.length <= 105 +# k 的取值范围是 [1, 数组中不相同的元素的个数] +# 题目数据保证答案唯一,换句话说,数组中前 k 个高频元素的集合是唯一的 +# +# +# +# +# 进阶:你所设计算法的时间复杂度 必须 优于 O(n log n) ,其中 n 是数组大小。 +# Related Topics 数组 哈希表 分治 桶排序 计数 快速选择 排序 堆(优先队列) +# 👍 1275 👎 0 + + +# leetcode submit region begin(Prohibit modification and deletion) +class Solution: + def topKFrequent(self, nums: List[int], k: int) -> List[int]: + import collections + counter = collections.Counter(nums) + counter = list(counter.items()) + + def partition(nums, left, right): + key= left + while left=nums[left][1]: + left+=1 + nums[left], nums[right] = nums[right], nums[left] + nums[left], nums[key] =nums[key], nums[left] + return left + + def sort(nums, k, left, right): + if left>=right: + return + mid = partition(nums, left, right) + if mid == k: + return + elif mid >k: + sort(nums, k, left, mid - 1) + else: + sort(nums, k, mid+1, right) + + l = len(counter) + sort(counter, l-k, 0, l-1) + return [i[0] for i in counter[-k:]] + + +# leetcode submit region end(Prohibit modification and deletion) diff --git "a/script/[368]\346\234\200\345\244\247\346\225\264\351\231\244\345\255\220\351\233\206.py" "b/script/[368]\346\234\200\345\244\247\346\225\264\351\231\244\345\255\220\351\233\206.py" new file mode 100644 index 0000000..1d83716 --- /dev/null +++ "b/script/[368]\346\234\200\345\244\247\346\225\264\351\231\244\345\255\220\351\233\206.py" @@ -0,0 +1,66 @@ +# 给你一个由 无重复 正整数组成的集合 nums ,请你找出并返回其中最大的整除子集 answer ,子集中每一元素对 (answer[i], answer[ +# j]) 都应当满足: +# +# answer[i] % answer[j] == 0 ,或 +# answer[j] % answer[i] == 0 +# +# +# 如果存在多个有效解子集,返回其中任何一个均可。 +# +# +# +# 示例 1: +# +# +# 输入:nums = [1,2,3] +# 输出:[1,2] +# 解释:[1,3] 也会被视为正确答案。 +# +# +# 示例 2: +# +# +# 输入:nums = [1,2,4,8] +# 输出:[1,2,4,8] +# +# +# +# +# 提示: +# +# +# 1 <= nums.length <= 1000 +# 1 <= nums[i] <= 2 * 109 +# nums 中的所有整数 互不相同 +# +# Related Topics 数组 数学 动态规划 排序 +# 👍 459 👎 0 + + +# leetcode submit region begin(Prohibit modification and deletion) +class Solution: + def largestDivisibleSubset(self, nums: List[int]) -> List[int]: + l = len(nums) + dp = [1] * l + nums = sorted(nums) + maxl = 1 + maxval = nums[0] + + for i in range(l): + for j in range(i): + if nums[i]%nums[j]==0: + dp[i] = max(dp[i], dp[j]+1) + if dp[i]>maxl: + maxl = dp[i] + maxval = nums[i] + #反向遍历得到子集 + result = [] + for i in range(l-1,-1,-1): + if dp[i]==maxl and maxval%nums[i]==0: + result.append(nums[i]) + maxl-=1 + maxval = nums[i] + + return result + +# leetcode submit region end(Prohibit modification and deletion) diff --git "a/script/[36]\346\234\211\346\225\210\347\232\204\346\225\260\347\213\254.py" "b/script/[36]\346\234\211\346\225\210\347\232\204\346\225\260\347\213\254.py" new file mode 100644 index 0000000..a3ec479 --- /dev/null +++ "b/script/[36]\346\234\211\346\225\210\347\232\204\346\225\260\347\213\254.py" @@ -0,0 +1,91 @@ +# 请你判断一个 9 x 9 的数独是否有效。只需要 根据以下规则 ,验证已经填入的数字是否有效即可。 +# +# +# 数字 1-9 在每一行只能出现一次。 +# 数字 1-9 在每一列只能出现一次。 +# 数字 1-9 在每一个以粗实线分隔的 3x3 宫内只能出现一次。(请参考示例图) +# +# +# +# +# 注意: +# +# +# 一个有效的数独(部分已被填充)不一定是可解的。 +# 只需要根据以上规则,验证已经填入的数字是否有效即可。 +# 空白格用 '.' 表示。 +# +# +# +# +# 示例 1: +# +# +# 输入:board = +# [["5","3",".",".","7",".",".",".","."] +# ,["6",".",".","1","9","5",".",".","."] +# ,[".","9","8",".",".",".",".","6","."] +# ,["8",".",".",".","6",".",".",".","3"] +# ,["4",".",".","8",".","3",".",".","1"] +# ,["7",".",".",".","2",".",".",".","6"] +# ,[".","6",".",".",".",".","2","8","."] +# ,[".",".",".","4","1","9",".",".","5"] +# ,[".",".",".",".","8",".",".","7","9"]] +# 输出:true +# +# +# 示例 2: +# +# +# 输入:board = +# [["8","3",".",".","7",".",".",".","."] +# ,["6",".",".","1","9","5",".",".","."] +# ,[".","9","8",".",".",".",".","6","."] +# ,["8",".",".",".","6",".",".",".","3"] +# ,["4",".",".","8",".","3",".",".","1"] +# ,["7",".",".",".","2",".",".",".","6"] +# ,[".","6",".",".",".",".","2","8","."] +# ,[".",".",".","4","1","9",".",".","5"] +# ,[".",".",".",".","8",".",".","7","9"]] +# 输出:false +# 解释:除了第一行的第一个数字从 5 改为 8 以外,空格内其他数字均与 示例1 相同。 但由于位于左上角的 3x3 宫内有两个 8 存在, 因此这个数独是无 +# 效的。 +# +# +# +# 提示: +# +# +# board.length == 9 +# board[i].length == 9 +# board[i][j] 是一位数字(1-9)或者 '.' +# +# Related Topics 数组 哈希表 矩阵 +# 👍 923 👎 0 + + +# leetcode submit region begin(Prohibit modification and deletion) +class Solution: + def isValidSudoku(self, board: List[List[str]]) -> bool: + from collections import defaultdict + hash_row = defaultdict(set) + hash_col= defaultdict(set) + hash_mat = defaultdict(set) + nrow=len(board) + ncol=len(board[0]) + for i in range(nrow): + for j in range(ncol): + if board[i][j]=='.': + continue + if board[i][j] in hash_row[i]: + return False + if board[i][j] in hash_col[j]: + return False + if board[i][j] in hash_mat[(i//3)*3+j//3]: + return False + hash_row[i].add(board[i][j]) + hash_col[j].add(board[i][j]) + hash_mat[(i//3)*3+j//3].add(board[i][j]) + return True + +# leetcode submit region end(Prohibit modification and deletion) diff --git "a/script/[376]\346\221\206\345\212\250\345\272\217\345\210\227.py" "b/script/[376]\346\221\206\345\212\250\345\272\217\345\210\227.py" new file mode 100644 index 0000000..6765bc1 --- /dev/null +++ "b/script/[376]\346\221\206\345\212\250\345\272\217\345\210\227.py" @@ -0,0 +1,68 @@ +# 如果连续数字之间的差严格地在正数和负数之间交替,则数字序列称为 摆动序列 。第一个差(如果存在的话)可能是正数或负数。仅有一个元素或者含两个不等元素的序列也 +# 视作摆动序列。 +# +# +# +# 例如, [1, 7, 4, 9, 2, 5] 是一个 摆动序列 ,因为差值 (6, -3, 5, -7, 3) 是正负交替出现的。 +# +# 相反,[1, 4, 7, 2, 5] 和 [1, 7, 4, 5, 5] 不是摆动序列,第一个序列是因为它的前两个差值都是正数,第二个序列是因为它的最后一 +# 个差值为零。 +# +# +# 子序列 可以通过从原始序列中删除一些(也可以不删除)元素来获得,剩下的元素保持其原始顺序。 +# +# 给你一个整数数组 nums ,返回 nums 中作为 摆动序列 的 最长子序列的长度 。 +# +# +# +# 示例 1: +# +# +# 输入:nums = [1,7,4,9,2,5] +# 输出:6 +# 解释:整个序列均为摆动序列,各元素之间的差值为 (6, -3, 5, -7, 3) 。 +# +# +# 示例 2: +# +# +# 输入:nums = [1,17,5,10,13,15,10,5,16,8] +# 输出:7 +# 解释:这个序列包含几个长度为 7 摆动序列。 +# 其中一个是 [1, 17, 10, 13, 10, 16, 8] ,各元素之间的差值为 (16, -7, 3, -3, 6, -8) 。 +# +# +# 示例 3: +# +# +# 输入:nums = [1,2,3,4,5,6,7,8,9] +# 输出:2 +# +# +# +# +# 提示: +# +# +# 1 <= nums.length <= 1000 +# 0 <= nums[i] <= 1000 +# +# +# +# +# 进阶:你能否用 O(n) 时间复杂度完成此题? +# Related Topics 贪心 数组 动态规划 +# 👍 737 👎 0 + + +# leetcode submit region begin(Prohibit modification and deletion) +class Solution: + def wiggleMaxLength(self, nums: List[int]) -> int: + prediff, curdiff, counter =0,0,1 + for i in range(1, len(nums)): + curdiff = nums[i]-nums[i-1] + if (curdiff>0 and prediff<=0) or (curdiff<0 and prediff>=0): + prediff = curdiff + counter+=1 + return counter +# leetcode submit region end(Prohibit modification and deletion) diff --git "a/script/[377]\347\273\204\345\220\210\346\200\273\345\222\214 \342\205\243.py" "b/script/[377]\347\273\204\345\220\210\346\200\273\345\222\214 \342\205\243.py" new file mode 100644 index 0000000..7297d45 --- /dev/null +++ "b/script/[377]\347\273\204\345\220\210\346\200\273\345\222\214 \342\205\243.py" @@ -0,0 +1,60 @@ +# 给你一个由 不同 整数组成的数组 nums ,和一个目标整数 target 。请你从 nums 中找出并返回总和为 target 的元素组合的个数。 +# +# 题目数据保证答案符合 32 位整数范围。 +# +# +# +# 示例 1: +# +# +# 输入:nums = [1,2,3], target = 4 +# 输出:7 +# 解释: +# 所有可能的组合为: +# (1, 1, 1, 1) +# (1, 1, 2) +# (1, 2, 1) +# (1, 3) +# (2, 1, 1) +# (2, 2) +# (3, 1) +# 请注意,顺序不同的序列被视作不同的组合。 +# +# +# 示例 2: +# +# +# 输入:nums = [9], target = 3 +# 输出:0 +# +# +# +# +# 提示: +# +# +# 1 <= nums.length <= 200 +# 1 <= nums[i] <= 1000 +# nums 中的所有元素 互不相同 +# 1 <= target <= 1000 +# +# +# +# +# 进阶:如果给定的数组中含有负数会发生什么?问题会产生何种变化?如果允许负数出现,需要向题目中添加哪些限制条件? +# Related Topics 数组 动态规划 +# 👍 672 👎 0 + + +# leetcode submit region begin(Prohibit modification and deletion) +class Solution: + def combinationSum4(self, nums: List[int], target: int) -> int: + dp = [0] * (target+1) + dp[0]=1 + for i in range(1,target+1): + for n in nums: + if i>=n: + dp[i]+=dp[i-n] + return dp[-1] + +# leetcode submit region end(Prohibit modification and deletion) diff --git "a/script/[382]\351\223\276\350\241\250\351\232\217\346\234\272\350\212\202\347\202\271.py" "b/script/[382]\351\223\276\350\241\250\351\232\217\346\234\272\350\212\202\347\202\271.py" new file mode 100644 index 0000000..c8e7fa2 --- /dev/null +++ "b/script/[382]\351\223\276\350\241\250\351\232\217\346\234\272\350\212\202\347\202\271.py" @@ -0,0 +1,84 @@ +# 给你一个单链表,随机选择链表的一个节点,并返回相应的节点值。每个节点 被选中的概率一样 。 +# +# 实现 Solution 类: +# +# +# Solution(ListNode head) 使用整数数组初始化对象。 +# int getRandom() 从链表中随机选择一个节点并返回该节点的值。链表中所有节点被选中的概率相等。 +# +# +# +# +# 示例: +# +# +# 输入 +# ["Solution", "getRandom", "getRandom", "getRandom", "getRandom", "getRandom"] +# [[[1, 2, 3]], [], [], [], [], []] +# 输出 +# [null, 1, 3, 2, 2, 3] +# +# 解释 +# Solution solution = new Solution([1, 2, 3]); +# solution.getRandom(); // 返回 1 +# solution.getRandom(); // 返回 3 +# solution.getRandom(); // 返回 2 +# solution.getRandom(); // 返回 2 +# solution.getRandom(); // 返回 3 +# // getRandom() 方法应随机返回 1、2、3中的一个,每个元素被返回的概率相等。 +# +# +# +# 提示: +# +# +# 链表中的节点数在范围 [1, 104] 内 +# -104 <= Node.val <= 104 +# 至多调用 getRandom 方法 104 次 +# +# +# +# +# 进阶: +# +# +# 如果链表非常大且长度未知,该怎么处理? +# 你能否在不使用额外空间的情况下解决此问题? +# +# Related Topics 水塘抽样 链表 数学 随机化 +# 👍 300 👎 0 + + +# leetcode submit region begin(Prohibit modification and deletion) +# Definition for singly-linked list. +# class ListNode: +# def __init__(self, val=0, next=None): +# self.val = val +# self.next = next +class Solution: + + def __init__(self, head: Optional[ListNode]): + self.head = head + + def getRandom(self) -> int: + import random + l = 0 + reserve = None + cur = self.head + while cur: + l+=1 + rand= random.randint(1, l) + # 用最新的node更新随机数的概率是1/count,保留之前随机数的概率是1-1/count + if rand == l: + reserve = cur.val + cur = cur.next + return reserve + + + + + +# Your Solution object will be instantiated and called as such: +# obj = Solution(head) +# param_1 = obj.getRandom() +# leetcode submit region end(Prohibit modification and deletion) diff --git "a/script/[38]\345\244\226\350\247\202\346\225\260\345\210\227.py" "b/script/[38]\345\244\226\350\247\202\346\225\260\345\210\227.py" new file mode 100644 index 0000000..910bdcf --- /dev/null +++ "b/script/[38]\345\244\226\350\247\202\346\225\260\345\210\227.py" @@ -0,0 +1,91 @@ +# 给定一个正整数 n ,输出外观数列的第 n 项。 +# +# 「外观数列」是一个整数序列,从数字 1 开始,序列中的每一项都是对前一项的描述。 +# +# 你可以将其视作是由递归公式定义的数字字符串序列: +# +# +# countAndSay(1) = "1" +# countAndSay(n) 是对 countAndSay(n-1) 的描述,然后转换成另一个数字字符串。 +# +# +# 前五项如下: +# +# +# 1. 1 +# 2. 11 +# 3. 21 +# 4. 1211 +# 5. 111221 +# 第一项是数字 1 +# 描述前一项,这个数是 1 即 “ 一 个 1 ”,记作 "11" +# 描述前一项,这个数是 11 即 “ 二 个 1 ” ,记作 "21" +# 描述前一项,这个数是 21 即 “ 一 个 2 + 一 个 1 ” ,记作 "1211" +# 描述前一项,这个数是 1211 即 “ 一 个 1 + 一 个 2 + 二 个 1 ” ,记作 "111221" +# +# +# 要 描述 一个数字字符串,首先要将字符串分割为 最小 数量的组,每个组都由连续的最多 相同字符 组成。然后对于每个组,先描述字符的数量,然后描述字符,形成 +# 一个描述组。要将描述转换为数字字符串,先将每组中的字符数量用数字替换,再将所有描述组连接起来。 +# +# 例如,数字字符串 "3322251" 的描述如下图: +# +# +# +# +# +# +# 示例 1: +# +# +# 输入:n = 1 +# 输出:"1" +# 解释:这是一个基本样例。 +# +# +# 示例 2: +# +# +# 输入:n = 4 +# 输出:"1211" +# 解释: +# countAndSay(1) = "1" +# countAndSay(2) = 读 "1" = 一 个 1 = "11" +# countAndSay(3) = 读 "11" = 二 个 1 = "21" +# countAndSay(4) = 读 "21" = 一 个 2 + 一 个 1 = "12" + "11" = "1211" +# +# +# +# +# 提示: +# +# +# 1 <= n <= 30 +# +# Related Topics 字符串 +# 👍 924 👎 0 + + +# leetcode submit region begin(Prohibit modification and deletion) +class Solution: + def countAndSay(self, n: int) -> str: + def helper(s): + counter = 1 + val = s[0] + result='' + for i in range(1,len(s)): + if s[i]==val: + counter+=1 + else: + result+='{}{}'.format(counter,val) + counter=1 + val =s[i] + result+='{}{}'.format(counter,val) + return result + tmp = '1' + for i in range(n-1): + tmp = helper(tmp) + return tmp + + + +# leetcode submit region end(Prohibit modification and deletion) diff --git "a/script/[392]\345\210\244\346\226\255\345\255\220\345\272\217\345\210\227.py" "b/script/[392]\345\210\244\346\226\255\345\255\220\345\272\217\345\210\227.py" new file mode 100644 index 0000000..a4b92d7 --- /dev/null +++ "b/script/[392]\345\210\244\346\226\255\345\255\220\345\272\217\345\210\227.py" @@ -0,0 +1,59 @@ +# 给定字符串 s 和 t ,判断 s 是否为 t 的子序列。 +# +# 字符串的一个子序列是原始字符串删除一些(也可以不删除)字符而不改变剩余字符相对位置形成的新字符串。(例如,"ace"是"abcde"的一个子序列,而"ae +# c"不是)。 +# +# 进阶: +# +# 如果有大量输入的 S,称作 S1, S2, ... , Sk 其中 k >= 10亿,你需要依次检查它们是否为 T 的子序列。在这种情况下,你会怎样改变代 +# 码? +# +# 致谢: +# +# 特别感谢 @pbrother 添加此问题并且创建所有测试用例。 +# +# +# +# 示例 1: +# +# +# 输入:s = "abc", t = "ahbgdc" +# 输出:true +# +# +# 示例 2: +# +# +# 输入:s = "axc", t = "ahbgdc" +# 输出:false +# +# +# +# +# 提示: +# +# +# 0 <= s.length <= 100 +# 0 <= t.length <= 10^4 +# 两个字符串都只由小写字符组成。 +# +# Related Topics 双指针 字符串 动态规划 +# 👍 696 👎 0 + + +# leetcode submit region begin(Prohibit modification and deletion) +class Solution: + def isSubsequence(self, s: str, t: str) -> bool: + ls = len(s) + lt = len(t) + dp = [[0] * (lt+1)for i in range(ls+1)] + # dp[i][j]是s[i-1]和t[j-1]匹配上的字符数 + for i in range(1, ls+1): + for j in range(1, lt+1): + if s[i-1]==t[j-1]: + dp[i][j] = max(dp[i][j], dp[i-1][j-1]+1) + else: + dp[i][j] = dp[i][j-1] + return dp[-1][-1]==ls + +# leetcode submit region end(Prohibit modification and deletion) diff --git "a/script/[394]\345\255\227\347\254\246\344\270\262\350\247\243\347\240\201.py" "b/script/[394]\345\255\227\347\254\246\344\270\262\350\247\243\347\240\201.py" new file mode 100644 index 0000000..18fdd49 --- /dev/null +++ "b/script/[394]\345\255\227\347\254\246\344\270\262\350\247\243\347\240\201.py" @@ -0,0 +1,78 @@ +# 给定一个经过编码的字符串,返回它解码后的字符串。 +# +# 编码规则为: k[encoded_string],表示其中方括号内部的 encoded_string 正好重复 k 次。注意 k 保证为正整数。 +# +# 你可以认为输入字符串总是有效的;输入字符串中没有额外的空格,且输入的方括号总是符合格式要求的。 +# +# 此外,你可以认为原始数据不包含数字,所有的数字只表示重复的次数 k ,例如不会出现像 3a 或 2[4] 的输入。 +# +# +# +# 示例 1: +# +# +# 输入:s = "3[a]2[bc]" +# 输出:"aaabcbc" +# +# +# 示例 2: +# +# +# 输入:s = "3[a2[c]]" +# 输出:"accaccacc" +# +# +# 示例 3: +# +# +# 输入:s = "2[abc]3[cd]ef" +# 输出:"abcabccdcdcdef" +# +# +# 示例 4: +# +# +# 输入:s = "abc3[cd]xyz" +# 输出:"abccdcdcdxyz" +# +# +# +# +# 提示: +# +# +# 1 <= s.length <= 30 +# s 由小写英文字母、数字和方括号 '[]' 组成 +# s 保证是一个 有效 的输入。 +# s 中所有整数的取值范围为 [1, 300] +# +# Related Topics 栈 递归 字符串 +# 👍 1233 👎 0 + + +# leetcode submit region begin(Prohibit modification and deletion) +class Solution: + def decodeString(self, s: str) -> str: + stack = [] + for i in s: + if i!=']': + stack.append(i) + else: + val ='' + while stack: + a = stack.pop() + if a!='[': + val = a+val + else: + break + count = '' + while stack: + if stack[-1].isdigit(): + a = stack.pop() + count = a+count + else: + break + count = int(count) + stack.append(val * count) + return ''.join(stack) +# leetcode submit region end(Prohibit modification and deletion) diff --git "a/script/[395]\350\207\263\345\260\221\346\234\211 K \344\270\252\351\207\215\345\244\215\345\255\227\347\254\246\347\232\204\346\234\200\351\225\277\345\255\220\344\270\262.py" "b/script/[395]\350\207\263\345\260\221\346\234\211 K \344\270\252\351\207\215\345\244\215\345\255\227\347\254\246\347\232\204\346\234\200\351\225\277\345\255\220\344\270\262.py" new file mode 100644 index 0000000..640efa8 --- /dev/null +++ "b/script/[395]\350\207\263\345\260\221\346\234\211 K \344\270\252\351\207\215\345\244\215\345\255\227\347\254\246\347\232\204\346\234\200\351\225\277\345\255\220\344\270\262.py" @@ -0,0 +1,45 @@ +# 给你一个字符串 s 和一个整数 k ,请你找出 s 中的最长子串, 要求该子串中的每一字符出现次数都不少于 k 。返回这一子串的长度。 +# +# +# +# 示例 1: +# +# +# 输入:s = "aaabb", k = 3 +# 输出:3 +# 解释:最长子串为 "aaa" ,其中 'a' 重复了 3 次。 +# +# +# 示例 2: +# +# +# 输入:s = "ababbc", k = 2 +# 输出:5 +# 解释:最长子串为 "ababb" ,其中 'a' 重复了 2 次, 'b' 重复了 3 次。 +# +# +# +# 提示: +# +# +# 1 <= s.length <= 104 +# s 仅由小写英文字母组成 +# 1 <= k <= 105 +# +# Related Topics 哈希表 字符串 分治 滑动窗口 +# 👍 714 👎 0 + + +# leetcode submit region begin(Prohibit modification and deletion) +class Solution: + def longestSubstring(self, s: str, k: int) -> int: + def dfs(s): + if len(s) str: + stack = [] + for i in num: + while stack and k>0 and i List[List[int]]: + people = sorted(people,key=lambda x:(x[0],-x[1]), reverse=True) + ans = [] + for p in people: + ans.insert(p[1],p) + return ans + + +# leetcode submit region end(Prohibit modification and deletion) diff --git a/script/[412]Fizz Buzz.py b/script/[412]Fizz Buzz.py new file mode 100644 index 0000000..bef21eb --- /dev/null +++ b/script/[412]Fizz Buzz.py @@ -0,0 +1,61 @@ +# 给你一个整数 n ,找出从 1 到 n 各个整数的 Fizz Buzz 表示,并用字符串数组 answer(下标从 1 开始)返回结果,其中: +# +# +# answer[i] == "FizzBuzz" 如果 i 同时是 3 和 5 的倍数。 +# answer[i] == "Fizz" 如果 i 是 3 的倍数。 +# answer[i] == "Buzz" 如果 i 是 5 的倍数。 +# answer[i] == i (以字符串形式)如果上述条件全不满足。 +# +# +# +# +# 示例 1: +# +# +# 输入:n = 3 +# 输出:["1","2","Fizz"] +# +# +# 示例 2: +# +# +# 输入:n = 5 +# 输出:["1","2","Fizz","4","Buzz"] +# +# +# 示例 3: +# +# +# 输入:n = 15 +# 输出:["1","2","Fizz","4","Buzz","Fizz","7","8","Fizz","Buzz","11","Fizz","13","1 +# 4","FizzBuzz"] +# +# +# +# 提示: +# +# +# 1 <= n <= 104 +# +# Related Topics 数学 字符串 模拟 +# 👍 202 👎 0 + + +# leetcode submit region begin(Prohibit modification and deletion) +class Solution: + def fizzBuzz(self, n: int) -> List[str]: + def helper(s): + if s % 15 == 0: + return 'FizzBuzz' + elif s % 5 == 0: + return 'Buzz' + elif s % 3 == 0: + return 'Fizz' + else: + return str(s) + + ans = [] + for i in range(1, n + 1): + ans.append(helper(i)) + return ans + # leetcode submit region end(Prohibit modification and deletion) diff --git "a/script/[416]\345\210\206\345\211\262\347\255\211\345\222\214\345\255\220\351\233\206.py" "b/script/[416]\345\210\206\345\211\262\347\255\211\345\222\214\345\255\220\351\233\206.py" new file mode 100644 index 0000000..c99bc2a --- /dev/null +++ "b/script/[416]\345\210\206\345\211\262\347\255\211\345\222\214\345\255\220\351\233\206.py" @@ -0,0 +1,45 @@ +# 给你一个 只包含正整数 的 非空 数组 nums 。请你判断是否可以将这个数组分割成两个子集,使得两个子集的元素和相等。 +# +# +# +# 示例 1: +# +# +# 输入:nums = [1,5,11,5] +# 输出:true +# 解释:数组可以分割成 [1, 5, 5] 和 [11] 。 +# +# 示例 2: +# +# +# 输入:nums = [1,2,3,5] +# 输出:false +# 解释:数组不能分割成两个元素和相等的子集。 +# +# +# +# +# 提示: +# +# +# 1 <= nums.length <= 200 +# 1 <= nums[i] <= 100 +# +# Related Topics 数组 动态规划 +# 👍 1404 👎 0 + + +# leetcode submit region begin(Prohibit modification and deletion) +class Solution: + def canPartition(self, nums: List[int]) -> bool: + total = sum(nums) + if total%2==1: + return False + total = int(total//2) + dp = [0] *(total+1) + for n in nums: + for i in range(total,n-1,-1): + dp[i] = max(dp[i], dp[i-n]+n) + return dp[-1]==total + +# leetcode submit region end(Prohibit modification and deletion) diff --git "a/script/[42]\346\216\245\351\233\250\346\260\264.py" "b/script/[42]\346\216\245\351\233\250\346\260\264.py" new file mode 100644 index 0000000..130fd32 --- /dev/null +++ "b/script/[42]\346\216\245\351\233\250\346\260\264.py" @@ -0,0 +1,53 @@ +# 给定 n 个非负整数表示每个宽度为 1 的柱子的高度图,计算按此排列的柱子,下雨之后能接多少雨水。 +# +# +# +# 示例 1: +# +# +# +# +# 输入:height = [0,1,0,2,1,0,1,3,2,1,2,1] +# 输出:6 +# 解释:上面是由数组 [0,1,0,2,1,0,1,3,2,1,2,1] 表示的高度图,在这种情况下,可以接 6 个单位的雨水(蓝色部分表示雨水)。 +# +# +# 示例 2: +# +# +# 输入:height = [4,2,0,3,2,5] +# 输出:9 +# +# +# +# +# 提示: +# +# +# n == height.length +# 1 <= n <= 2 * 104 +# 0 <= height[i] <= 105 +# +# Related Topics 栈 数组 双指针 动态规划 单调栈 +# 👍 3637 👎 0 + + +# leetcode submit region begin(Prohibit modification and deletion) +class Solution: + def trap(self, height: List[int]) -> int: + total = 0 + stack = [0] + for i in range(1, len(height)): + if height[i]< height[stack[-1]]: + stack.append(i) + else: + while stack and height[i] > height[stack[-1]]: + mid = stack.pop() + if stack: + total += (min(height[i], height[stack[-1]]) - height[mid]) * (i-stack[-1]-1) + stack.append(i) + return total + + + +# leetcode submit region end(Prohibit modification and deletion) diff --git "a/script/[435]\346\227\240\351\207\215\345\217\240\345\214\272\351\227\264.py" "b/script/[435]\346\227\240\351\207\215\345\217\240\345\214\272\351\227\264.py" new file mode 100644 index 0000000..4c4daaa --- /dev/null +++ "b/script/[435]\346\227\240\351\207\215\345\217\240\345\214\272\351\227\264.py" @@ -0,0 +1,58 @@ +# 给定一个区间的集合 intervals ,其中 intervals[i] = [starti, endi] 。返回 需要移除区间的最小数量,使剩余区间互不重 +# 叠 。 +# +# +# +# 示例 1: +# +# +# 输入: intervals = [[1,2],[2,3],[3,4],[1,3]] +# 输出: 1 +# 解释: 移除 [1,3] 后,剩下的区间没有重叠。 +# +# +# 示例 2: +# +# +# 输入: intervals = [ [1,2], [1,2], [1,2] ] +# 输出: 2 +# 解释: 你需要移除两个 [1,2] 来使剩下的区间没有重叠。 +# +# +# 示例 3: +# +# +# 输入: intervals = [ [1,2], [2,3] ] +# 输出: 0 +# 解释: 你不需要移除任何区间,因为它们已经是无重叠的了。 +# +# +# +# +# 提示: +# +# +# 1 <= intervals.length <= 105 +# intervals[i].length == 2 +# -5 * 104 <= starti < endi <= 5 * 104 +# +# Related Topics 贪心 数组 动态规划 排序 +# 👍 751 👎 0 + + +# leetcode submit region begin(Prohibit modification and deletion) +class Solution: + def eraseOverlapIntervals(self, intervals: List[List[int]]) -> int: + intervals = sorted(intervals, key = lambda x:x[1]) + right = intervals[0][1] + tmp = intervals[0] + counter = 0 + for i in range(1, len(intervals)): + if intervals[i][0] int: + def helper(root, targetSum): + if not root: + return 0 + # 注意这里不要返回因为在node.val可能<0 + if targetSum==root.val: + mid =1 + else: + mid=0 + left = helper(root.left, targetSum-root.val) + right = helper(root.right, targetSum-root.val) + return left + right+mid + + def dfs(root, target): + if not root: + return 0 + left = dfs(root.left, target) + right = dfs(root.right, target) + mid = helper(root, target) + return left+right+mid + return dfs(root, targetSum) + + +# leetcode submit region end(Prohibit modification and deletion) diff --git "a/script/[448]\346\211\276\345\210\260\346\211\200\346\234\211\346\225\260\347\273\204\344\270\255\346\266\210\345\244\261\347\232\204\346\225\260\345\255\227.py" "b/script/[448]\346\211\276\345\210\260\346\211\200\346\234\211\346\225\260\347\273\204\344\270\255\346\266\210\345\244\261\347\232\204\346\225\260\345\255\227.py" new file mode 100644 index 0000000..490220a --- /dev/null +++ "b/script/[448]\346\211\276\345\210\260\346\211\200\346\234\211\346\225\260\347\273\204\344\270\255\346\266\210\345\244\261\347\232\204\346\225\260\345\255\227.py" @@ -0,0 +1,46 @@ +# 给你一个含 n 个整数的数组 nums ,其中 nums[i] 在区间 [1, n] 内。请你找出所有在 [1, n] 范围内但没有出现在 nums 中的数 +# 字,并以数组的形式返回结果。 +# +# +# +# 示例 1: +# +# +# 输入:nums = [4,3,2,7,8,2,3,1] +# 输出:[5,6] +# +# +# 示例 2: +# +# +# 输入:nums = [1,1] +# 输出:[2] +# +# +# +# +# 提示: +# +# +# n == nums.length +# 1 <= n <= 105 +# 1 <= nums[i] <= n +# +# +# 进阶:你能在不使用额外空间且时间复杂度为 O(n) 的情况下解决这个问题吗? 你可以假定返回的数组不算在额外空间内。 +# Related Topics 数组 哈希表 +# 👍 1033 👎 0 + + +# leetcode submit region begin(Prohibit modification and deletion) +class Solution: + def findDisappearedNumbers(self, nums: List[int]) -> List[int]: + for n in nums: + n = abs(n)-1 + nums[n] = -abs(nums[n]) + result = [] + for i in range(len(nums)): + if nums[i] >0: + result.append(i+1) + return result +# leetcode submit region end(Prohibit modification and deletion) diff --git "a/script/[452]\347\224\250\346\234\200\345\260\221\346\225\260\351\207\217\347\232\204\347\256\255\345\274\225\347\210\206\346\260\224\347\220\203.py" "b/script/[452]\347\224\250\346\234\200\345\260\221\346\225\260\351\207\217\347\232\204\347\256\255\345\274\225\347\210\206\346\260\224\347\220\203.py" new file mode 100644 index 0000000..9a63e4e --- /dev/null +++ "b/script/[452]\347\224\250\346\234\200\345\260\221\346\225\260\351\207\217\347\232\204\347\256\255\345\274\225\347\210\206\346\260\224\347\220\203.py" @@ -0,0 +1,64 @@ +# 有一些球形气球贴在一堵用 XY 平面表示的墙面上。墙面上的气球记录在整数数组 points ,其中points[i] = [xstart, xend] 表示 +# 水平直径在 xstart 和 xend之间的气球。你不知道气球的确切 y 坐标。 +# +# 一支弓箭可以沿着 x 轴从不同点 完全垂直 地射出。在坐标 x 处射出一支箭,若有一个气球的直径的开始和结束坐标为 xstart,xend, 且满足 xs +# tart ≤ x ≤ xend,则该气球会被 引爆 。可以射出的弓箭的数量 没有限制 。 弓箭一旦被射出之后,可以无限地前进。 +# +# 给你一个数组 points ,返回引爆所有气球所必须射出的 最小 弓箭数 。 +# +# +# 示例 1: +# +# +# 输入:points = [[10,16],[2,8],[1,6],[7,12]] +# 输出:2 +# 解释:气球可以用2支箭来爆破: +# -在x = 6处射出箭,击破气球[2,8]和[1,6]。 +# -在x = 11处发射箭,击破气球[10,16]和[7,12]。 +# +# 示例 2: +# +# +# 输入:points = [[1,2],[3,4],[5,6],[7,8]] +# 输出:4 +# 解释:每个气球需要射出一支箭,总共需要4支箭。 +# +# 示例 3: +# +# +# 输入:points = [[1,2],[2,3],[3,4],[4,5]] +# 输出:2 +# 解释:气球可以用2支箭来爆破: +# - 在x = 2处发射箭,击破气球[1,2]和[2,3]。 +# - 在x = 4处射出箭,击破气球[3,4]和[4,5]。 +# +# +# +# +# +# 提示: +# +# +# 1 <= points.length <= 105 +# points[i].length == 2 +# -231 <= xstart < xend <= 231 - 1 +# +# Related Topics 贪心 数组 排序 +# 👍 637 👎 0 + + +# leetcode submit region begin(Prohibit modification and deletion) +class Solution: + def findMinArrowShots(self, points: List[List[int]]) -> int: + counter = 1 + # sort了左边界,所以只用判断右边界 + points = sorted(points, key=lambda x: x[0]) + right = points[0][1] + for i in range(1, len(points)): + if points[i][0]<=right: + right = min(right, points[i][1]) + else: + counter +=1 + right = points[i][1] + return counter +# leetcode submit region end(Prohibit modification and deletion) diff --git "a/script/[455]\345\210\206\345\217\221\351\245\274\345\271\262.py" "b/script/[455]\345\210\206\345\217\221\351\245\274\345\271\262.py" new file mode 100644 index 0000000..4aa5b33 --- /dev/null +++ "b/script/[455]\345\210\206\345\217\221\351\245\274\345\271\262.py" @@ -0,0 +1,60 @@ +# 假设你是一位很棒的家长,想要给你的孩子们一些小饼干。但是,每个孩子最多只能给一块饼干。 +# +# 对每个孩子 i,都有一个胃口值 g[i],这是能让孩子们满足胃口的饼干的最小尺寸;并且每块饼干 j,都有一个尺寸 s[j] 。如果 s[j] >= g[i +# ],我们可以将这个饼干 j 分配给孩子 i ,这个孩子会得到满足。你的目标是尽可能满足越多数量的孩子,并输出这个最大数值。 +# +# +# 示例 1: +# +# +# 输入: g = [1,2,3], s = [1,1] +# 输出: 1 +# 解释: +# 你有三个孩子和两块小饼干,3个孩子的胃口值分别是:1,2,3。 +# 虽然你有两块小饼干,由于他们的尺寸都是1,你只能让胃口值是1的孩子满足。 +# 所以你应该输出1。 +# +# +# 示例 2: +# +# +# 输入: g = [1,2], s = [1,2,3] +# 输出: 2 +# 解释: +# 你有两个孩子和三块小饼干,2个孩子的胃口值分别是1,2。 +# 你拥有的饼干数量和尺寸都足以让所有孩子满足。 +# 所以你应该输出2. +# +# +# +# +# 提示: +# +# +# 1 <= g.length <= 3 * 104 +# 0 <= s.length <= 3 * 104 +# 1 <= g[i], s[j] <= 231 - 1 +# +# Related Topics 贪心 数组 排序 +# 👍 547 👎 0 + + +# leetcode submit region begin(Prohibit modification and deletion) +class Solution: + def findContentChildren(self, g: List[int], s: List[int]) -> int: + g.sort() + s.sort() + counter = 0 + i =0 + j = 0 + ng = len(g) + ns = len(s) + while i int: + reach = 0 + farest = 0 + counter =0 + for i in range(len(nums)): + if i > reach: + counter +=1 + reach = farest + farest = max(farest, nums[i] + i) + return counter + +# leetcode submit region end(Prohibit modification and deletion) diff --git "a/script/[463]\345\262\233\345\261\277\347\232\204\345\221\250\351\225\277.py" "b/script/[463]\345\262\233\345\261\277\347\232\204\345\221\250\351\225\277.py" new file mode 100644 index 0000000..e6055cd --- /dev/null +++ "b/script/[463]\345\262\233\345\261\277\347\232\204\345\221\250\351\225\277.py" @@ -0,0 +1,67 @@ +# 给定一个 row x col 的二维网格地图 grid ,其中:grid[i][j] = 1 表示陆地, grid[i][j] = 0 表示水域。 +# +# 网格中的格子 水平和垂直 方向相连(对角线方向不相连)。整个网格被水完全包围,但其中恰好有一个岛屿(或者说,一个或多个表示陆地的格子相连组成的岛屿)。 +# +# 岛屿中没有“湖”(“湖” 指水域在岛屿内部且不和岛屿周围的水相连)。格子是边长为 1 的正方形。网格为长方形,且宽度和高度均不超过 100 。计算这个岛屿 +# 的周长。 +# +# +# +# 示例 1: +# +# +# +# +# 输入:grid = [[0,1,0,0],[1,1,1,0],[0,1,0,0],[1,1,0,0]] +# 输出:16 +# 解释:它的周长是上面图片中的 16 个黄色的边 +# +# 示例 2: +# +# +# 输入:grid = [[1]] +# 输出:4 +# +# +# 示例 3: +# +# +# 输入:grid = [[1,0]] +# 输出:4 +# +# +# +# +# 提示: +# +# +# row == grid.length +# col == grid[i].length +# 1 <= row, col <= 100 +# grid[i][j] 为 0 或 1 +# +# Related Topics 深度优先搜索 广度优先搜索 数组 矩阵 +# 👍 567 👎 0 + + +# leetcode submit region begin(Prohibit modification and deletion) +class Solution: + def islandPerimeter(self, grid: List[List[int]]) -> int: + count = 0 + nrow = len(grid) + ncol = len(grid[0]) + for i in range(nrow): + for j in range(ncol): + if grid[i][j] == 1: + count += 4 + + if (i - 1 >= 0) and grid[i - 1][j] == 1: + count -= 1 + if (i + 1 < nrow) and grid[i + 1][j] == 1: + count -= 1 + if (j - 1 >= 0) and grid[i][j - 1] == 1: + count -= 1 + if (j + 1 < ncol) and grid[i][j + 1] == 1: + count -= 1 + return count +# leetcode submit region end(Prohibit modification and deletion) diff --git "a/script/[474]\344\270\200\345\222\214\351\233\266.py" "b/script/[474]\344\270\200\345\222\214\351\233\266.py" new file mode 100644 index 0000000..5a94f1a --- /dev/null +++ "b/script/[474]\344\270\200\345\222\214\351\233\266.py" @@ -0,0 +1,53 @@ +# 给你一个二进制字符串数组 strs 和两个整数 m 和 n 。 +# +# +# 请你找出并返回 strs 的最大子集的长度,该子集中 最多 有 m 个 0 和 n 个 1 。 +# +# 如果 x 的所有元素也是 y 的元素,集合 x 是集合 y 的 子集 。 +# +# +# +# +# 示例 1: +# +# +# 输入:strs = ["10", "0001", "111001", "1", "0"], m = 5, n = 3 +# 输出:4 +# 解释:最多有 5 个 0 和 3 个 1 的最大子集是 {"10","0001","1","0"} ,因此答案是 4 。 +# 其他满足题意但较小的子集包括 {"0001","1"} 和 {"10","1","0"} 。{"111001"} 不满足题意,因为它含 4 个 1 ,大于 +# n 的值 3 。 +# +# +# 示例 2: +# +# +# 输入:strs = ["10", "0", "1"], m = 1, n = 1 +# 输出:2 +# 解释:最大的子集是 {"0", "1"} ,所以答案是 2 。 +# +# +# +# +# 提示: +# +# +# 1 <= strs.length <= 600 +# 1 <= strs[i].length <= 100 +# strs[i] 仅由 '0' 和 '1' 组成 +# 1 <= m, n <= 100 +# +# Related Topics 数组 字符串 动态规划 +# 👍 766 👎 0 + + +# leetcode submit region begin(Prohibit modification and deletion) +class Solution: + def findMaxForm(self, strs: List[str], m: int, n: int) -> int: + dp = [[0] * (n+1) for i in range(m+1)] + for s in strs: + count0, count1 = s.count('0'),s.count('1') + for i in range(m, count0-1, -1): + for j in range(n, count1-1,-1): + dp[i][j] = max(dp[i][j], dp[i-count0][j-count1]+1) + return dp[-1][-1] +# leetcode submit region end(Prohibit modification and deletion) diff --git "a/script/[482]\345\257\206\351\222\245\346\240\274\345\274\217\345\214\226.py" "b/script/[482]\345\257\206\351\222\245\346\240\274\345\274\217\345\214\226.py" new file mode 100644 index 0000000..c225c24 --- /dev/null +++ "b/script/[482]\345\257\206\351\222\245\346\240\274\345\274\217\345\214\226.py" @@ -0,0 +1,59 @@ +# 给定一个许可密钥字符串 s,仅由字母、数字字符和破折号组成。字符串由 n 个破折号分成 n + 1 组。你也会得到一个整数 k 。 +# +# 我们想要重新格式化字符串 s,使每一组包含 k 个字符,除了第一组,它可以比 k 短,但仍然必须包含至少一个字符。此外,两组之间必须插入破折号,并且应该将 +# 所有小写字母转换为大写字母。 +# +# 返回 重新格式化的许可密钥 。 +# +# +# +# 示例 1: +# +# +# 输入:S = "5F3Z-2e-9-w", k = 4 +# 输出:"5F3Z-2E9W" +# 解释:字符串 S 被分成了两个部分,每部分 4 个字符; +#   注意,两个额外的破折号需要删掉。 +# +# +# 示例 2: +# +# +# 输入:S = "2-5g-3-J", k = 2 +# 输出:"2-5G-3J" +# 解释:字符串 S 被分成了 3 个部分,按照前面的规则描述,第一部分的字符可以少于给定的数量,其余部分皆为 2 个字符。 +# +# +# +# +# 提示: +# +# +# 1 <= s.length <= 105 +# s 只包含字母、数字和破折号 '-'. +# 1 <= k <= 104 +# +# Related Topics 字符串 +# 👍 144 👎 0 + + +# leetcode submit region begin(Prohibit modification and deletion) +class Solution: + def licenseKeyFormatting(self, s: str, k: int) -> str: + result = [] + counter =0 + tmp = '' + for i in range(len(s)-1, -1,-1): + if s[i]=='-': + continue + tmp =s[i].upper()+tmp + counter+=1 + if counter%k==0: + result.append(tmp) + tmp ='' + if tmp: + result.append(tmp) + return '-'.join(result[::-1]) + + +# leetcode submit region end(Prohibit modification and deletion) diff --git "a/script/[485]\346\234\200\345\244\247\350\277\236\347\273\255 1 \347\232\204\344\270\252\346\225\260.py" "b/script/[485]\346\234\200\345\244\247\350\277\236\347\273\255 1 \347\232\204\344\270\252\346\225\260.py" new file mode 100644 index 0000000..7175528 --- /dev/null +++ "b/script/[485]\346\234\200\345\244\247\350\277\236\347\273\255 1 \347\232\204\344\270\252\346\225\260.py" @@ -0,0 +1,45 @@ +# 给定一个二进制数组 nums , 计算其中最大连续 1 的个数。 +# +# +# +# 示例 1: +# +# +# 输入:nums = [1,1,0,1,1,1] +# 输出:3 +# 解释:开头的两位和最后的三位都是连续 1 ,所以最大连续 1 的个数是 3. +# +# +# 示例 2: +# +# +# 输入:nums = [1,0,1,1,0,1] +# 输出:2 +# +# +# +# +# 提示: +# +# +# 1 <= nums.length <= 105 +# nums[i] 不是 0 就是 1. +# +# Related Topics 数组 +# 👍 327 👎 0 + + +# leetcode submit region begin(Prohibit modification and deletion) +class Solution: + def findMaxConsecutiveOnes(self, nums: List[int]) -> int: + counter = 0 + maxcount =0 + for i,n in enumerate(nums): + if n==1: + counter+=1 + else: + maxcount = max(maxcount, counter) + counter =0 + maxcount = max(maxcount, counter) + return maxcount +# leetcode submit region end(Prohibit modification and deletion) diff --git "a/script/[48]\346\227\213\350\275\254\345\233\276\345\203\217.py" "b/script/[48]\346\227\213\350\275\254\345\233\276\345\203\217.py" new file mode 100644 index 0000000..2ca2073 --- /dev/null +++ "b/script/[48]\346\227\213\350\275\254\345\233\276\345\203\217.py" @@ -0,0 +1,50 @@ +# 给定一个 n × n 的二维矩阵 matrix 表示一个图像。请你将图像顺时针旋转 90 度。 +# +# 你必须在 原地 旋转图像,这意味着你需要直接修改输入的二维矩阵。请不要 使用另一个矩阵来旋转图像。 +# +# +# +# 示例 1: +# +# +# 输入:matrix = [[1,2,3],[4,5,6],[7,8,9]] +# 输出:[[7,4,1],[8,5,2],[9,6,3]] +# +# +# 示例 2: +# +# +# 输入:matrix = [[5,1,9,11],[2,4,8,10],[13,3,6,7],[15,14,12,16]] +# 输出:[[15,13,2,5],[14,3,4,1],[12,6,8,9],[16,7,10,11]] +# +# +# +# +# 提示: +# +# +# n == matrix.length == matrix[i].length +# 1 <= n <= 20 +# -1000 <= matrix[i][j] <= 1000 +# +# +# +# Related Topics 数组 数学 矩阵 +# 👍 1370 👎 0 + + +# leetcode submit region begin(Prohibit modification and deletion) +class Solution: + def rotate(self, matrix: List[List[int]]) -> None: + """ + Do not return anything, modify matrix in-place instead. + """ + nrow = len(matrix) + for i in range(nrow//2): + matrix[i][:],matrix[nrow-1-i][:] = matrix[nrow-1-i][:], matrix[i][:] + for i in range(nrow): + for j in range(i): + matrix[i][j], matrix[j][i] = matrix[j][i], matrix[i][j] + return matrix + +# leetcode submit region end(Prohibit modification and deletion) diff --git "a/script/[494]\347\233\256\346\240\207\345\222\214.py" "b/script/[494]\347\233\256\346\240\207\345\222\214.py" new file mode 100644 index 0000000..1fd9729 --- /dev/null +++ "b/script/[494]\347\233\256\346\240\207\345\222\214.py" @@ -0,0 +1,64 @@ +# 给你一个整数数组 nums 和一个整数 target 。 +# +# 向数组中的每个整数前添加 '+' 或 '-' ,然后串联起所有整数,可以构造一个 表达式 : +# +# +# 例如,nums = [2, 1] ,可以在 2 之前添加 '+' ,在 1 之前添加 '-' ,然后串联起来得到表达式 "+2-1" 。 +# +# +# 返回可以通过上述方法构造的、运算结果等于 target 的不同 表达式 的数目。 +# +# +# +# 示例 1: +# +# +# 输入:nums = [1,1,1,1,1], target = 3 +# 输出:5 +# 解释:一共有 5 种方法让最终目标和为 3 。 +# -1 + 1 + 1 + 1 + 1 = 3 +# +1 - 1 + 1 + 1 + 1 = 3 +# +1 + 1 - 1 + 1 + 1 = 3 +# +1 + 1 + 1 - 1 + 1 = 3 +# +1 + 1 + 1 + 1 - 1 = 3 +# +# +# 示例 2: +# +# +# 输入:nums = [1], target = 1 +# 输出:1 +# +# +# +# +# 提示: +# +# +# 1 <= nums.length <= 20 +# 0 <= nums[i] <= 1000 +# 0 <= sum(nums[i]) <= 1000 +# -1000 <= target <= 1000 +# +# Related Topics 数组 动态规划 回溯 +# 👍 1310 👎 0 + + +# leetcode submit region begin(Prohibit modification and deletion) +class Solution: + def findTargetSumWays(self, nums: List[int], target: int) -> int: + # a+b=total, a-b=target + a = (sum(nums)-target) + if a%2==1: + return 0 + if a<0: + return 0 + l = a//2 + dp = [0] * (l+1) + dp[0] = 1 + for n in nums: + for i in range(l, n-1,-1): + dp[i]+=dp[i-n] + return dp[-1] + +# leetcode submit region end(Prohibit modification and deletion) diff --git "a/script/[495]\346\217\220\350\216\253\346\224\273\345\207\273.py" "b/script/[495]\346\217\220\350\216\253\346\224\273\345\207\273.py" new file mode 100644 index 0000000..24f0892 --- /dev/null +++ "b/script/[495]\346\217\220\350\216\253\346\224\273\345\207\273.py" @@ -0,0 +1,57 @@ +# 在《英雄联盟》的世界中,有一个叫 “提莫” 的英雄。他的攻击可以让敌方英雄艾希(编者注:寒冰射手)进入中毒状态。 +# +# 当提莫攻击艾希,艾希的中毒状态正好持续 duration 秒。 +# +# 正式地讲,提莫在 t 发起发起攻击意味着艾希在时间区间 [t, t + duration - 1](含 t 和 t + duration - 1)处于中毒 +# 状态。如果提莫在中毒影响结束 前 再次攻击,中毒状态计时器将会 重置 ,在新的攻击之后,中毒影响将会在 duration 秒后结束。 +# +# 给你一个 非递减 的整数数组 timeSeries ,其中 timeSeries[i] 表示提莫在 timeSeries[i] 秒时对艾希发起攻击,以及一 +# 个表示中毒持续时间的整数 duration 。 +# +# 返回艾希处于中毒状态的 总 秒数。 +# +# +# 示例 1: +# +# +# 输入:timeSeries = [1,4], duration = 2 +# 输出:4 +# 解释:提莫攻击对艾希的影响如下: +# - 第 1 秒,提莫攻击艾希并使其立即中毒。中毒状态会维持 2 秒,即第 1 秒和第 2 秒。 +# - 第 4 秒,提莫再次攻击艾希,艾希中毒状态又持续 2 秒,即第 4 秒和第 5 秒。 +# 艾希在第 1、2、4、5 秒处于中毒状态,所以总中毒秒数是 4 。 +# +# 示例 2: +# +# +# 输入:timeSeries = [1,2], duration = 2 +# 输出:3 +# 解释:提莫攻击对艾希的影响如下: +# - 第 1 秒,提莫攻击艾希并使其立即中毒。中毒状态会维持 2 秒,即第 1 秒和第 2 秒。 +# - 第 2 秒,提莫再次攻击艾希,并重置中毒计时器,艾希中毒状态需要持续 2 秒,即第 2 秒和第 3 秒。 +# 艾希在第 1、2、3 秒处于中毒状态,所以总中毒秒数是 3 。 +# +# +# +# +# 提示: +# +# +# 1 <= timeSeries.length <= 104 +# 0 <= timeSeries[i], duration <= 107 +# timeSeries 按 非递减 顺序排列 +# +# Related Topics 数组 模拟 +# 👍 315 👎 0 + + +# leetcode submit region begin(Prohibit modification and deletion) +class Solution: + def findPoisonedDuration(self, timeSeries: List[int], duration: int) -> int: + total = 0 + pre = 0 + for i in range(len(timeSeries)): + total += max(duration - max(pre-timeSeries[i],0),0) + pre = timeSeries[i]+duration + return total +# leetcode submit region end(Prohibit modification and deletion) diff --git "a/script/[496]\344\270\213\344\270\200\344\270\252\346\233\264\345\244\247\345\205\203\347\264\240 I.py" "b/script/[496]\344\270\213\344\270\200\344\270\252\346\233\264\345\244\247\345\205\203\347\264\240 I.py" new file mode 100644 index 0000000..232d8a9 --- /dev/null +++ "b/script/[496]\344\270\213\344\270\200\344\270\252\346\233\264\345\244\247\345\205\203\347\264\240 I.py" @@ -0,0 +1,61 @@ +# nums1 中数字 x 的 下一个更大元素 是指 x 在 nums2 中对应位置 右侧 的 第一个 比 x 大的元素。 +# +# 给你两个 没有重复元素 的数组 nums1 和 nums2 ,下标从 0 开始计数,其中nums1 是 nums2 的子集。 +# +# 对于每个 0 <= i < nums1.length ,找出满足 nums1[i] == nums2[j] 的下标 j ,并且在 nums2 确定 num +# s2[j] 的 下一个更大元素 。如果不存在下一个更大元素,那么本次查询的答案是 -1 。 +# +# 返回一个长度为 nums1.length 的数组 ans 作为答案,满足 ans[i] 是如上所述的 下一个更大元素 。 +# +# +# +# 示例 1: +# +# +# 输入:nums1 = [4,1,2], nums2 = [1,3,4,2]. +# 输出:[-1,3,-1] +# 解释:nums1 中每个值的下一个更大元素如下所述: +# - 4 ,用加粗斜体标识,nums2 = [1,3,4,2]。不存在下一个更大元素,所以答案是 -1 。 +# - 1 ,用加粗斜体标识,nums2 = [1,3,4,2]。下一个更大元素是 3 。 +# - 2 ,用加粗斜体标识,nums2 = [1,3,4,2]。不存在下一个更大元素,所以答案是 -1 。 +# +# 示例 2: +# +# +# 输入:nums1 = [2,4], nums2 = [1,2,3,4]. +# 输出:[3,-1] +# 解释:nums1 中每个值的下一个更大元素如下所述: +# - 2 ,用加粗斜体标识,nums2 = [1,2,3,4]。下一个更大元素是 3 。 +# - 4 ,用加粗斜体标识,nums2 = [1,2,3,4]。不存在下一个更大元素,所以答案是 -1 。 +# +# +# +# +# 提示: +# +# +# 1 <= nums1.length <= nums2.length <= 1000 +# 0 <= nums1[i], nums2[i] <= 104 +# nums1和nums2中所有整数 互不相同 +# nums1 中的所有整数同样出现在 nums2 中 +# +# +# +# +# 进阶:你可以设计一个时间复杂度为 O(nums1.length + nums2.length) 的解决方案吗? +# Related Topics 栈 数组 哈希表 单调栈 +# 👍 776 👎 0 + + +# leetcode submit region begin(Prohibit modification and deletion) +class Solution: + def nextGreaterElement(self, nums1: List[int], nums2: List[int]) -> List[int]: + hash = dict() + stack = [nums2[0]] + for i in range(1, len(nums2)): + while stack and nums2[i]>stack[-1]: + hash[stack.pop()] = nums2[i] + stack.append(nums2[i]) + return [hash.get(i,-1) for i in nums1] + +# leetcode submit region end(Prohibit modification and deletion) diff --git "a/script/[503]\344\270\213\344\270\200\344\270\252\346\233\264\345\244\247\345\205\203\347\264\240 II.py" "b/script/[503]\344\270\213\344\270\200\344\270\252\346\233\264\345\244\247\345\205\203\347\264\240 II.py" new file mode 100644 index 0000000..754e044 --- /dev/null +++ "b/script/[503]\344\270\213\344\270\200\344\270\252\346\233\264\345\244\247\345\205\203\347\264\240 II.py" @@ -0,0 +1,51 @@ +# 给定一个循环数组 nums ( nums[nums.length - 1] 的下一个元素是 nums[0] ),返回 nums 中每个元素的 下一个更大元素 +# 。 +# +# 数字 x 的 下一个更大的元素 是按数组遍历顺序,这个数字之后的第一个比它更大的数,这意味着你应该循环地搜索它的下一个更大的数。如果不存在,则输出 -1 +# 。 +# +# +# +# 示例 1: +# +# +# 输入: nums = [1,2,1] +# 输出: [2,-1,2] +# 解释: 第一个 1 的下一个更大的数是 2; +# 数字 2 找不到下一个更大的数; +# 第二个 1 的下一个最大的数需要循环搜索,结果也是 2。 +# +# +# 示例 2: +# +# +# 输入: nums = [1,2,3,4,3] +# 输出: [2,3,4,-1,4] +# +# +# +# +# 提示: +# +# +# 1 <= nums.length <= 104 +# -109 <= nums[i] <= 109 +# +# Related Topics 栈 数组 单调栈 +# 👍 664 👎 0 + + +# leetcode submit region begin(Prohibit modification and deletion) +class Solution: + def nextGreaterElements(self, nums: List[int]) -> List[int]: + l = len(nums) + result = [-1] * l + stack = [] + + for i in range(2*l-1): + while stack and nums[i%l] > nums[stack[-1]]: + result[stack.pop()] = nums[i%l] + stack.append(i%l) + return result + +# leetcode submit region end(Prohibit modification and deletion) diff --git "a/script/[509]\346\226\220\346\263\242\351\202\243\345\245\221\346\225\260.py" "b/script/[509]\346\226\220\346\263\242\351\202\243\345\245\221\346\225\260.py" new file mode 100644 index 0000000..deb49c5 --- /dev/null +++ "b/script/[509]\346\226\220\346\263\242\351\202\243\345\245\221\346\225\260.py" @@ -0,0 +1,56 @@ +# 斐波那契数 (通常用 F(n) 表示)形成的序列称为 斐波那契数列 。该数列由 0 和 1 开始,后面的每一项数字都是前面两项数字的和。也就是: +# +# +# F(0) = 0,F(1) = 1 +# F(n) = F(n - 1) + F(n - 2),其中 n > 1 +# +# +# 给定 n ,请计算 F(n) 。 +# +# +# +# 示例 1: +# +# +# 输入:n = 2 +# 输出:1 +# 解释:F(2) = F(1) + F(0) = 1 + 0 = 1 +# +# +# 示例 2: +# +# +# 输入:n = 3 +# 输出:2 +# 解释:F(3) = F(2) + F(1) = 1 + 1 = 2 +# +# +# 示例 3: +# +# +# 输入:n = 4 +# 输出:3 +# 解释:F(4) = F(3) + F(2) = 2 + 1 = 3 +# +# +# +# +# 提示: +# +# +# 0 <= n <= 30 +# +# Related Topics 递归 记忆化搜索 数学 动态规划 +# 👍 501 👎 0 + + +# leetcode submit region begin(Prohibit modification and deletion) +class Solution: + def fib(self, n: int) -> int: + dp = [0,1] + if n<2: + return dp[n] + for i in range(1,n): + dp[0],dp[1] = dp[1],dp[0]+dp[1] + return dp[1] +# leetcode submit region end(Prohibit modification and deletion) diff --git "a/script/[516]\346\234\200\351\225\277\345\233\236\346\226\207\345\255\220\345\272\217\345\210\227.py" "b/script/[516]\346\234\200\351\225\277\345\233\236\346\226\207\345\255\220\345\272\217\345\210\227.py" new file mode 100644 index 0000000..ee86087 --- /dev/null +++ "b/script/[516]\346\234\200\351\225\277\345\233\236\346\226\207\345\255\220\345\272\217\345\210\227.py" @@ -0,0 +1,38 @@ +# 给你一个字符串 s ,找出其中最长的回文子序列,并返回该序列的长度。 +# +# 子序列定义为:不改变剩余字符顺序的情况下,删除某些字符或者不删除任何字符形成的一个序列。 +# +# +# +# 示例 1: +# +# +# 输入:s = "bbbab" +# 输出:4 +# 解释:一个可能的最长回文子序列为 "bbbb" 。 +# +# +# 示例 2: +# +# +# 输入:s = "cbbd" +# 输出:2 +# 解释:一个可能的最长回文子序列为 "bb" 。 +# +# +# +# +# 提示: +# +# +# 1 <= s.length <= 1000 +# s 仅由小写英文字母组成 +# +# Related Topics 字符串 动态规划 +# 👍 850 👎 0 + + +# leetcode submit region begin(Prohibit modification and deletion) +class Solution: + def longestPalindromeSubseq(self, s: str) -> int: +# leetcode submit region end(Prohibit modification and deletion) diff --git "a/script/[518]\351\233\266\351\222\261\345\205\221\346\215\242 II.py" "b/script/[518]\351\233\266\351\222\261\345\205\221\346\215\242 II.py" new file mode 100644 index 0000000..fdb32d6 --- /dev/null +++ "b/script/[518]\351\233\266\351\222\261\345\205\221\346\215\242 II.py" @@ -0,0 +1,64 @@ +# 给你一个整数数组 coins 表示不同面额的硬币,另给一个整数 amount 表示总金额。 +# +# 请你计算并返回可以凑成总金额的硬币组合数。如果任何硬币组合都无法凑出总金额,返回 0 。 +# +# 假设每一种面额的硬币有无限个。 +# +# 题目数据保证结果符合 32 位带符号整数。 +# +# +# +# +# +# +# 示例 1: +# +# +# 输入:amount = 5, coins = [1, 2, 5] +# 输出:4 +# 解释:有四种方式可以凑成总金额: +# 5=5 +# 5=2+2+1 +# 5=2+1+1+1 +# 5=1+1+1+1+1 +# +# +# 示例 2: +# +# +# 输入:amount = 3, coins = [2] +# 输出:0 +# 解释:只用面额 2 的硬币不能凑成总金额 3 。 +# +# +# 示例 3: +# +# +# 输入:amount = 10, coins = [10] +# 输出:1 +# +# +# +# +# 提示: +# +# +# 1 <= coins.length <= 300 +# 1 <= coins[i] <= 5000 +# coins 中的所有值 互不相同 +# 0 <= amount <= 5000 +# +# Related Topics 数组 动态规划 +# 👍 879 👎 0 + + +# leetcode submit region begin(Prohibit modification and deletion) +class Solution: + def change(self, amount: int, coins: List[int]) -> int: + dp = [0] * (amount+1) + dp[0] =1 + for c in coins: + for i in range(c, amount+1): + dp[i]+=dp[i-c] + return dp[-1] +# leetcode submit region end(Prohibit modification and deletion) diff --git "a/script/[53]\346\234\200\345\244\247\345\255\220\346\225\260\347\273\204\345\222\214.py" "b/script/[53]\346\234\200\345\244\247\345\255\220\346\225\260\347\273\204\345\222\214.py" new file mode 100644 index 0000000..397fdb9 --- /dev/null +++ "b/script/[53]\346\234\200\345\244\247\345\255\220\346\225\260\347\273\204\345\222\214.py" @@ -0,0 +1,55 @@ +# 给你一个整数数组 nums ,请你找出一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和。 +# +# 子数组 是数组中的一个连续部分。 +# +# +# +# 示例 1: +# +# +# 输入:nums = [-2,1,-3,4,-1,2,1,-5,4] +# 输出:6 +# 解释:连续子数组 [4,-1,2,1] 的和最大,为 6 。 +# +# +# 示例 2: +# +# +# 输入:nums = [1] +# 输出:1 +# +# +# 示例 3: +# +# +# 输入:nums = [5,4,-1,7,8] +# 输出:23 +# +# +# +# +# 提示: +# +# +# 1 <= nums.length <= 105 +# -104 <= nums[i] <= 104 +# +# +# +# +# 进阶:如果你已经实现复杂度为 O(n) 的解法,尝试使用更为精妙的 分治法 求解。 +# Related Topics 数组 分治 动态规划 +# 👍 5154 👎 0 + + +# leetcode submit region begin(Prohibit modification and deletion) +class Solution: + def maxSubArray(self, nums: List[int]) -> int: + tmp = nums[0] + maxsum = nums[0] + for i in nums[1:]: + tmp = max(tmp,0) + i + maxsum = max(maxsum, tmp) + return maxsum + +# leetcode submit region end(Prohibit modification and deletion) diff --git "a/script/[54]\350\236\272\346\227\213\347\237\251\351\230\265.py" "b/script/[54]\350\236\272\346\227\213\347\237\251\351\230\265.py" new file mode 100644 index 0000000..86b53b6 --- /dev/null +++ "b/script/[54]\350\236\272\346\227\213\347\237\251\351\230\265.py" @@ -0,0 +1,64 @@ +# 给你一个 m 行 n 列的矩阵 matrix ,请按照 顺时针螺旋顺序 ,返回矩阵中的所有元素。 +# +# +# +# 示例 1: +# +# +# 输入:matrix = [[1,2,3],[4,5,6],[7,8,9]] +# 输出:[1,2,3,6,9,8,7,4,5] +# +# +# 示例 2: +# +# +# 输入:matrix = [[1,2,3,4],[5,6,7,8],[9,10,11,12]] +# 输出:[1,2,3,4,8,12,11,10,9,5,6,7] +# +# +# +# +# 提示: +# +# +# m == matrix.length +# n == matrix[i].length +# 1 <= m, n <= 10 +# -100 <= matrix[i][j] <= 100 +# +# Related Topics 数组 矩阵 模拟 +# 👍 1152 👎 0 + + +# leetcode submit region begin(Prohibit modification and deletion) +class Solution: + def spiralOrder(self, matrix: List[List[int]]) -> List[int]: + result = [] + top = 0 + bottom = len(matrix)-1 + left = 0 + right = len(matrix[0])-1 + while left < right and top < bottom: + for i in range(left, right): + result.append(matrix[top][i]) + for i in range(top, bottom): + result.append(matrix[i][right]) + for i in range(right, left, -1): + result.append(matrix[bottom][i]) + for i in range(bottom, top, -1): + result.append(matrix[i][left]) + + left +=1 + right-=1 + bottom-=1 + top+=1 + if top==bottom and left==right: + result.append(matrix[top][left]) + elif top==bottom: + for i in range(left, right+1): + result.append(matrix[top][i]) + elif left ==right: + for i in range(top, bottom+1): + result.append(matrix[i][left]) + return result +# leetcode submit region end(Prohibit modification and deletion) diff --git "a/script/[55]\350\267\263\350\267\203\346\270\270\346\210\217.py" "b/script/[55]\350\267\263\350\267\203\346\270\270\346\210\217.py" new file mode 100644 index 0000000..2608d9e --- /dev/null +++ "b/script/[55]\350\267\263\350\267\203\346\270\270\346\210\217.py" @@ -0,0 +1,46 @@ +# 给定一个非负整数数组 nums ,你最初位于数组的 第一个下标 。 +# +# 数组中的每个元素代表你在该位置可以跳跃的最大长度。 +# +# 判断你是否能够到达最后一个下标。 +# +# +# +# 示例 1: +# +# +# 输入:nums = [2,3,1,1,4] +# 输出:true +# 解释:可以先跳 1 步,从下标 0 到达下标 1, 然后再从下标 1 跳 3 步到达最后一个下标。 +# +# +# 示例 2: +# +# +# 输入:nums = [3,2,1,0,4] +# 输出:false +# 解释:无论怎样,总会到达下标为 3 的位置。但该下标的最大跳跃长度是 0 , 所以永远不可能到达最后一个下标。 +# +# +# +# +# 提示: +# +# +# 1 <= nums.length <= 3 * 104 +# 0 <= nums[i] <= 105 +# +# Related Topics 贪心 数组 动态规划 +# 👍 1933 👎 0 + + +# leetcode submit region begin(Prohibit modification and deletion) +class Solution: + def canJump(self, nums: List[int]) -> bool: + reach = 0 + for i in range(len(nums)): + if i > reach: + return False + reach = max(reach, i+nums[i]) + return True +# leetcode submit region end(Prohibit modification and deletion) diff --git "a/script/[561]\346\225\260\347\273\204\346\213\206\345\210\206.py" "b/script/[561]\346\225\260\347\273\204\346\213\206\345\210\206.py" new file mode 100644 index 0000000..e897e01 --- /dev/null +++ "b/script/[561]\346\225\260\347\273\204\346\213\206\345\210\206.py" @@ -0,0 +1,45 @@ +# 给定长度为 2n 的整数数组 nums ,你的任务是将这些数分成 n 对, 例如 (a1, b1), (a2, b2), ..., (an, bn) ,使得 +# 从 1 到 n 的 min(ai, bi) 总和最大。 +# +# 返回该 最大总和 。 +# +# +# +# 示例 1: +# +# +# 输入:nums = [1,4,3,2] +# 输出:4 +# 解释:所有可能的分法(忽略元素顺序)为: +# 1. (1, 4), (2, 3) -> min(1, 4) + min(2, 3) = 1 + 2 = 3 +# 2. (1, 3), (2, 4) -> min(1, 3) + min(2, 4) = 1 + 2 = 3 +# 3. (1, 2), (3, 4) -> min(1, 2) + min(3, 4) = 1 + 3 = 4 +# 所以最大总和为 4 +# +# 示例 2: +# +# +# 输入:nums = [6,2,6,5,1,2] +# 输出:9 +# 解释:最优的分法为 (2, 1), (2, 5), (6, 6). min(2, 1) + min(2, 5) + min(6, 6) = 1 + 2 + +# 6 = 9 +# +# +# +# +# 提示: +# +# +# 1 <= n <= 104 +# nums.length == 2 * n +# -104 <= nums[i] <= 104 +# +# Related Topics 贪心 数组 计数排序 排序 +# 👍 305 👎 0 + + +# leetcode submit region begin(Prohibit modification and deletion) +class Solution: + def arrayPairSum(self, nums: List[int]) -> int: + return sum(sorted(nums)[::2]) +# leetcode submit region end(Prohibit modification and deletion) diff --git "a/script/[566]\351\207\215\345\241\221\347\237\251\351\230\265.py" "b/script/[566]\351\207\215\345\241\221\347\237\251\351\230\265.py" new file mode 100644 index 0000000..4e1b26a --- /dev/null +++ "b/script/[566]\351\207\215\345\241\221\347\237\251\351\230\265.py" @@ -0,0 +1,52 @@ +# 在 MATLAB 中,有一个非常有用的函数 reshape ,它可以将一个 m x n 矩阵重塑为另一个大小不同(r x c)的新矩阵,但保留其原始数据。 +# +# +# 给你一个由二维数组 mat 表示的 m x n 矩阵,以及两个正整数 r 和 c ,分别表示想要的重构的矩阵的行数和列数。 +# +# 重构后的矩阵需要将原始矩阵的所有元素以相同的 行遍历顺序 填充。 +# +# 如果具有给定参数的 reshape 操作是可行且合理的,则输出新的重塑矩阵;否则,输出原始矩阵。 +# +# +# +# 示例 1: +# +# +# 输入:mat = [[1,2],[3,4]], r = 1, c = 4 +# 输出:[[1,2,3,4]] +# +# +# 示例 2: +# +# +# 输入:mat = [[1,2],[3,4]], r = 2, c = 4 +# 输出:[[1,2],[3,4]] +# +# +# +# +# 提示: +# +# +# m == mat.length +# n == mat[i].length +# 1 <= m, n <= 100 +# -1000 <= mat[i][j] <= 1000 +# 1 <= r, c <= 300 +# +# Related Topics 数组 矩阵 模拟 +# 👍 320 👎 0 + + +# leetcode submit region begin(Prohibit modification and deletion) +class Solution: + def matrixReshape(self, mat: List[List[int]], r: int, c: int) -> List[List[int]]: + nrow=len(mat) + ncol=len(mat[0]) + if nrow*ncol!=r*c: + return mat + nmat = [[0] * c for i in range(r)] + for i in range(nrow*ncol): + nmat[i//c][i%c] = mat[i//ncol][i%ncol] + return nmat +# leetcode submit region end(Prohibit modification and deletion) diff --git "a/script/[56]\345\220\210\345\271\266\345\214\272\351\227\264.py" "b/script/[56]\345\220\210\345\271\266\345\214\272\351\227\264.py" new file mode 100644 index 0000000..1792028 --- /dev/null +++ "b/script/[56]\345\220\210\345\271\266\345\214\272\351\227\264.py" @@ -0,0 +1,48 @@ +# 以数组 intervals 表示若干个区间的集合,其中单个区间为 intervals[i] = [starti, endi] 。请你合并所有重叠的区间,并返 +# 回 一个不重叠的区间数组,该数组需恰好覆盖输入中的所有区间 。 +# +# +# +# 示例 1: +# +# +# 输入:intervals = [[1,3],[2,6],[8,10],[15,18]] +# 输出:[[1,6],[8,10],[15,18]] +# 解释:区间 [1,3] 和 [2,6] 重叠, 将它们合并为 [1,6]. +# +# +# 示例 2: +# +# +# 输入:intervals = [[1,4],[4,5]] +# 输出:[[1,5]] +# 解释:区间 [1,4] 和 [4,5] 可被视为重叠区间。 +# +# +# +# 提示: +# +# +# 1 <= intervals.length <= 104 +# intervals[i].length == 2 +# 0 <= starti <= endi <= 104 +# +# Related Topics 数组 排序 +# 👍 1572 👎 0 + + +# leetcode submit region begin(Prohibit modification and deletion) +class Solution: + def merge(self, intervals: List[List[int]]) -> List[List[int]]: + result = [] + intervals = sorted(intervals, key=lambda x:x[0]) + tmp = intervals[0] + for i in range(1, len(intervals)): + if intervals[i][0] <= tmp[1]: + tmp[1] = max(intervals[i][1],tmp[1]) + else: + result.append(tmp) + tmp = intervals[i] + result.append(tmp) + return result +# leetcode submit region end(Prohibit modification and deletion) diff --git "a/script/[57]\346\217\222\345\205\245\345\214\272\351\227\264.py" "b/script/[57]\346\217\222\345\205\245\345\214\272\351\227\264.py" new file mode 100644 index 0000000..93a1659 --- /dev/null +++ "b/script/[57]\346\217\222\345\205\245\345\214\272\351\227\264.py" @@ -0,0 +1,80 @@ +# 给你一个 无重叠的 ,按照区间起始端点排序的区间列表。 +# +# 在列表中插入一个新的区间,你需要确保列表中的区间仍然有序且不重叠(如果有必要的话,可以合并区间)。 +# +# +# +# 示例 1: +# +# +# 输入:intervals = [[1,3],[6,9]], newInterval = [2,5] +# 输出:[[1,5],[6,9]] +# +# +# 示例 2: +# +# +# 输入:intervals = [[1,2],[3,5],[6,7],[8,10],[12,16]], newInterval = [4,8] +# 输出:[[1,2],[3,10],[12,16]] +# 解释:这是因为新的区间 [4,8] 与 [3,5],[6,7],[8,10] 重叠。 +# +# 示例 3: +# +# +# 输入:intervals = [], newInterval = [5,7] +# 输出:[[5,7]] +# +# +# 示例 4: +# +# +# 输入:intervals = [[1,5]], newInterval = [2,3] +# 输出:[[1,5]] +# +# +# 示例 5: +# +# +# 输入:intervals = [[1,5]], newInterval = [2,7] +# 输出:[[1,7]] +# +# +# +# +# 提示: +# +# +# 0 <= intervals.length <= 104 +# intervals[i].length == 2 +# 0 <= intervals[i][0] <= intervals[i][1] <= 105 +# intervals 根据 intervals[i][0] 按 升序 排列 +# newInterval.length == 2 +# 0 <= newInterval[0] <= newInterval[1] <= 105 +# +# Related Topics 数组 +# 👍 610 👎 0 + + +# leetcode submit region begin(Prohibit modification and deletion) +class Solution: + def insert(self, intervals: List[List[int]], newInterval: List[int]) -> List[List[int]]: + result = [] + flag = False + for i in range(len(intervals)): + if not flag: + if newInterval[1]< intervals[i][0]: + result.append(newInterval) + result.append(intervals[i]) + flag=True + elif newInterval[0] > intervals[i][1]: + result.append(intervals[i]) + else: + newInterval[0] = min(intervals[i][0], newInterval[0]) + newInterval[1] = max(intervals[i][1], newInterval[1]) + else: + result.append(intervals[i]) + if not flag: + result.append(newInterval) + return result + +# leetcode submit region end(Prohibit modification and deletion) diff --git "a/script/[583]\344\270\244\344\270\252\345\255\227\347\254\246\344\270\262\347\232\204\345\210\240\351\231\244\346\223\215\344\275\234.py" "b/script/[583]\344\270\244\344\270\252\345\255\227\347\254\246\344\270\262\347\232\204\345\210\240\351\231\244\346\223\215\344\275\234.py" new file mode 100644 index 0000000..3aba2ef --- /dev/null +++ "b/script/[583]\344\270\244\344\270\252\345\255\227\347\254\246\344\270\262\347\232\204\345\210\240\351\231\244\346\223\215\344\275\234.py" @@ -0,0 +1,54 @@ +# 给定两个单词 word1 和 word2 ,返回使得 word1 和 word2 相同所需的最小步数。 +# +# 每步 可以删除任意一个字符串中的一个字符。 +# +# +# +# 示例 1: +# +# +# 输入: word1 = "sea", word2 = "eat" +# 输出: 2 +# 解释: 第一步将 "sea" 变为 "ea" ,第二步将 "eat "变为 "ea" +# +# +# 示例 2: +# +# +# 输入:word1 = "leetcode", word2 = "etco" +# 输出:4 +# +# +# +# +# 提示: +# +# +# +# 1 <= word1.length, word2.length <= 500 +# word1 和 word2 只包含小写英文字母 +# +# Related Topics 字符串 动态规划 +# 👍 465 👎 0 + + +# leetcode submit region begin(Prohibit modification and deletion) +class Solution: + def minDistance(self, word1: str, word2: str) -> int: + l1 = len(word1) + l2 = len(word2) + dp = [[0] * (l2+1) for i in range(l1+1)] + for i in range(1, l1+1): + dp[i][0] = i + for i in range(1, l2+1): + dp[0][i] = i + + for i in range(1, l1+1): + for j in range(1,l2+1): + if word1[i-1]==word2[j-1]: + dp[i][j] = dp[i-1][j-1] + else: + dp[i][j] = min(dp[i-1][j-1]+2, dp[i-1][j]+1, dp[i][j-1]+1) + return dp[-1][-1] + +# leetcode submit region end(Prohibit modification and deletion) diff --git "a/script/[58]\346\234\200\345\220\216\344\270\200\344\270\252\345\215\225\350\257\215\347\232\204\351\225\277\345\272\246.py" "b/script/[58]\346\234\200\345\220\216\344\270\200\344\270\252\345\215\225\350\257\215\347\232\204\351\225\277\345\272\246.py" new file mode 100644 index 0000000..11e95e1 --- /dev/null +++ "b/script/[58]\346\234\200\345\220\216\344\270\200\344\270\252\345\215\225\350\257\215\347\232\204\351\225\277\345\272\246.py" @@ -0,0 +1,47 @@ +# 给你一个字符串 s,由若干单词组成,单词前后用一些空格字符隔开。返回字符串中 最后一个 单词的长度。 +# +# 单词 是指仅由字母组成、不包含任何空格字符的最大子字符串。 +# +# +# +# 示例 1: +# +# +# 输入:s = "Hello World" +# 输出:5 +# 解释:最后一个单词是“World”,长度为5。 +# +# +# 示例 2: +# +# +# 输入:s = " fly me to the moon " +# 输出:4 +# 解释:最后一个单词是“moon”,长度为4。 +# +# +# 示例 3: +# +# +# 输入:s = "luffy is still joyboy" +# 输出:6 +# 解释:最后一个单词是长度为6的“joyboy”。 +# +# +# +# +# 提示: +# +# +# 1 <= s.length <= 104 +# s 仅有英文字母和空格 ' ' 组成 +# s 中至少存在一个单词 +# +# Related Topics 字符串 +# 👍 478 👎 0 + + +# leetcode submit region begin(Prohibit modification and deletion) +class Solution: + def lengthOfLastWord(self, s: str) -> int: +# leetcode submit region end(Prohibit modification and deletion) diff --git "a/script/[598]\350\214\203\345\233\264\346\261\202\345\222\214 II.py" "b/script/[598]\350\214\203\345\233\264\346\261\202\345\222\214 II.py" new file mode 100644 index 0000000..99976d0 --- /dev/null +++ "b/script/[598]\350\214\203\345\233\264\346\261\202\345\222\214 II.py" @@ -0,0 +1,58 @@ +# 给你一个 m x n 的矩阵 M ,初始化时所有的 0 和一个操作数组 op ,其中 ops[i] = [ai, bi] 意味着当所有的 0 <= x < +# ai 和 0 <= y < bi 时, M[x][y] 应该加 1。 +# +# 在 执行完所有操作后 ,计算并返回 矩阵中最大整数的个数 。 +# +# +# +# 示例 1: +# +# +# +# +# 输入: m = 3, n = 3,ops = [[2,2],[3,3]] +# 输出: 4 +# 解释: M 中最大的整数是 2, 而且 M 中有4个值为2的元素。因此返回 4。 +# +# +# 示例 2: +# +# +# 输入: m = 3, n = 3, ops = [[2,2],[3,3],[3,3],[3,3],[2,2],[3,3],[3,3],[3,3],[2,2] +# ,[3,3],[3,3],[3,3]] +# 输出: 4 +# +# +# 示例 3: +# +# +# 输入: m = 3, n = 3, ops = [] +# 输出: 9 +# +# +# +# +# 提示: +# +# +# +# +# 1 <= m, n <= 4 * 104 +# 0 <= ops.length <= 104 +# ops[i].length == 2 +# 1 <= ai <= m +# 1 <= bi <= n +# +# Related Topics 数组 数学 +# 👍 167 👎 0 + + +# leetcode submit region begin(Prohibit modification and deletion) +class Solution: + def maxCount(self, m: int, n: int, ops: List[List[int]]) -> int: + if not ops: + return m*n + min_row = min([i[0] for i in ops ]) + min_col = min([i[1] for i in ops ]) + return min_row * min_col +# leetcode submit region end(Prohibit modification and deletion) diff --git "a/script/[599]\344\270\244\344\270\252\345\210\227\350\241\250\347\232\204\346\234\200\345\260\217\347\264\242\345\274\225\346\200\273\345\222\214.py" "b/script/[599]\344\270\244\344\270\252\345\210\227\350\241\250\347\232\204\346\234\200\345\260\217\347\264\242\345\274\225\346\200\273\345\222\214.py" new file mode 100644 index 0000000..d8d99ff --- /dev/null +++ "b/script/[599]\344\270\244\344\270\252\345\210\227\350\241\250\347\232\204\346\234\200\345\260\217\347\264\242\345\274\225\346\200\273\345\222\214.py" @@ -0,0 +1,55 @@ +# 假设 Andy 和 Doris 想在晚餐时选择一家餐厅,并且他们都有一个表示最喜爱餐厅的列表,每个餐厅的名字用字符串表示。 +# +# 你需要帮助他们用最少的索引和找出他们共同喜爱的餐厅。 如果答案不止一个,则输出所有答案并且不考虑顺序。 你可以假设答案总是存在。 +# +# +# +# 示例 1: +# +# +# 输入: list1 = ["Shogun", "Tapioca Express", "Burger King", "KFC"],list2 = ["Piat +# ti", "The Grill at Torrey Pines", "Hungry Hunter Steakhouse", "Shogun"] +# 输出: ["Shogun"] +# 解释: 他们唯一共同喜爱的餐厅是“Shogun”。 +# +# +# 示例 2: +# +# +# 输入:list1 = ["Shogun", "Tapioca Express", "Burger King", "KFC"],list2 = ["KFC", +# "Shogun", "Burger King"] +# 输出: ["Shogun"] +# 解释: 他们共同喜爱且具有最小索引和的餐厅是“Shogun”,它有最小的索引和1(0+1)。 +# +# +# +# +# 提示: +# +# # +# # 1 <= list1.length, list2.length <= 1000 +# # 1 <= list1[i].length, list2[i].length <= 30 +# # list1[i] 和 list2[i] 由空格 ' ' 和英文字母组成。 +# # list1 的所有字符串都是 唯一 的。 +# # list2 中的所有字符串都是 唯一 的。 +# # +# # Related Topics 数组 哈希表 字符串 +# 👍 223 👎 0 + + +# leetcode submit region begin(Prohibit modification and deletion) +class Solution: + def findRestaurant(self, list1: List[str], list2: List[str]) -> List[str]: + hash = {} + for i,n in enumerate(list1): + hash[n]=i + minindex = 2000 + result = [] + for i,n in enumerate(list2): + if hash.get(n,2000) +i < minindex: + result = [n] + minindex = hash.get(n,2000) +i + elif hash.get(n,2000) +i == minindex: + result.append(n) + return result +# leetcode submit region end(Prohibit modification and deletion) diff --git "a/script/[59]\350\236\272\346\227\213\347\237\251\351\230\265 II.py" "b/script/[59]\350\236\272\346\227\213\347\237\251\351\230\265 II.py" new file mode 100644 index 0000000..084fa25 --- /dev/null +++ "b/script/[59]\350\236\272\346\227\213\347\237\251\351\230\265 II.py" @@ -0,0 +1,69 @@ +# 给你一个正整数 n ,生成一个包含 1 到 n2 所有元素,且元素按顺时针顺序螺旋排列的 n x n 正方形矩阵 matrix 。 +# +# +# +# 示例 1: +# +# +# 输入:n = 3 +# 输出:[[1,2,3],[8,9,4],[7,6,5]] +# +# +# 示例 2: +# +# +# 输入:n = 1 +# 输出:[[1]] +# +# +# +# +# 提示: +# +# +# 1 <= n <= 20 +# +# Related Topics 数组 矩阵 模拟 +# 👍 768 👎 0 + + +# leetcode submit region begin(Prohibit modification and deletion) +class Solution: + def generateMatrix(self, n: int) -> List[List[int]]: + num = 1 + mat = [[0] * n for i in range(n)] + left = 0 + right = n - 1 + top = 0 + bottom = n - 1 + while left < right and top < bottom: + for c in range(left, right): + mat[top][c] = num + num += 1 + for r in range(top, bottom): + mat[r][right] = num + num += 1 + for c in range(right, left, -1): + mat[bottom][c] = num + num += 1 + for r in range(bottom, top, -1): + mat[r][left] = num + num += 1 + + left += 1 + right -= 1 + bottom -= 1 + top += 1 + + if left == right and top == bottom: + mat[left][top] = num + elif left == right: + for r in range(top, bottom + 1): + mat[r][left] = num + num += 1 + else: + for c in range(left, right + 1): + mat[top][c] = num + num += 1 + return mat + # leetcode submit region end(Prohibit modification and deletion) diff --git "a/script/[605]\347\247\215\350\212\261\351\227\256\351\242\230.py" "b/script/[605]\347\247\215\350\212\261\351\227\256\351\242\230.py" new file mode 100644 index 0000000..e6fb41b --- /dev/null +++ "b/script/[605]\347\247\215\350\212\261\351\227\256\351\242\230.py" @@ -0,0 +1,60 @@ +# 假设有一个很长的花坛,一部分地块种植了花,另一部分却没有。可是,花不能种植在相邻的地块上,它们会争夺水源,两者都会死去。 +# +# 给你一个整数数组 flowerbed 表示花坛,由若干 0 和 1 组成,其中 0 表示没种植花,1 表示种植了花。另有一个数 n ,能否在不打破种植规则 +# 的情况下种入 n 朵花?能则返回 true ,不能则返回 false。 +# +# +# +# 示例 1: +# +# +# 输入:flowerbed = [1,0,0,0,1], n = 1 +# 输出:true +# +# +# 示例 2: +# +# +# 输入:flowerbed = [1,0,0,0,1], n = 2 +# 输出:false +# +# +# +# +# 提示: +# +# +# 1 <= flowerbed.length <= 2 * 104 +# flowerbed[i] 为 0 或 1 +# flowerbed 中不存在相邻的两朵花 +# 0 <= n <= flowerbed.length +# +# Related Topics 贪心 数组 +# 👍 467 👎 0 + + +# leetcode submit region begin(Prohibit modification and deletion) +class Solution: + def canPlaceFlowers(self, flowerbed: List[int], n: int) -> bool: + prepos = -1 + counter = 0 + l = len(flowerbed) + for i in range(l): + if flowerbed[i]==1: + if prepos<0: + counter += (i-prepos-1)//2 + else: + counter += (i-prepos-2)//2 + prepos = i + if prepos<0: + counter+=(l-prepos)//2 + else: + counter+=(l-prepos-1)//2 + print(counter) + if counter>=n: + return True + else: + return False + + +# leetcode submit region end(Prohibit modification and deletion) diff --git "a/script/[61]\346\227\213\350\275\254\351\223\276\350\241\250.py" "b/script/[61]\346\227\213\350\275\254\351\223\276\350\241\250.py" new file mode 100644 index 0000000..a4fd688 --- /dev/null +++ "b/script/[61]\346\227\213\350\275\254\351\223\276\350\241\250.py" @@ -0,0 +1,59 @@ +# 给你一个链表的头节点 head ,旋转链表,将链表每个节点向右移动 k 个位置。 +# +# +# +# 示例 1: +# +# +# 输入:head = [1,2,3,4,5], k = 2 +# 输出:[4,5,1,2,3] +# +# +# 示例 2: +# +# +# 输入:head = [0,1,2], k = 4 +# 输出:[2,0,1] +# +# +# +# +# 提示: +# +# +# 链表中节点的数目在范围 [0, 500] 内 +# -100 <= Node.val <= 100 +# 0 <= k <= 2 * 109 +# +# Related Topics 链表 双指针 +# 👍 801 👎 0 + + +# leetcode submit region begin(Prohibit modification and deletion) +# Definition for singly-linked list. +# class ListNode: +# def __init__(self, val=0, next=None): +# self.val = val +# self.next = next +class Solution: + def rotateRight(self, head: Optional[ListNode], k: int) -> Optional[ListNode]: + if not head: + return head + l = 1 + ptr = head + while head.next: + head = head.next + l+=1 + if k%l==0: + return ptr + #首位相连 + head.next = ptr + k = l-k%l + for i in range(k-1): + ptr = ptr.next + + newhead = ptr.next + ptr.next = None + return newhead + +# leetcode submit region end(Prohibit modification and deletion) diff --git "a/script/[623]\345\234\250\344\272\214\345\217\211\346\240\221\344\270\255\345\242\236\345\212\240\344\270\200\350\241\214.py" "b/script/[623]\345\234\250\344\272\214\345\217\211\346\240\221\344\270\255\345\242\236\345\212\240\344\270\200\350\241\214.py" new file mode 100644 index 0000000..edf69af --- /dev/null +++ "b/script/[623]\345\234\250\344\272\214\345\217\211\346\240\221\344\270\255\345\242\236\345\212\240\344\270\200\350\241\214.py" @@ -0,0 +1,79 @@ +# 给定一个二叉树的根 root 和两个整数 val 和 depth ,在给定的深度 depth 处添加一个值为 val 的节点行。 +# +# 注意,根节点 root 位于深度 1 。 +# +# 加法规则如下: +# +# +# 给定整数 depth,对于深度为 depth - 1 的每个非空树节点 cur ,创建两个值为 val 的树节点作为 cur 的左子树根和右子树根。 +# cur 原来的左子树应该是新的左子树根的左子树。 +# cur 原来的右子树应该是新的右子树根的右子树。 +# 如果 depth == 1 意味着 depth - 1 根本没有深度,那么创建一个树节点,值 val 作为整个原始树的新根,而原始树就是新根的左子树。 +# +# +# +# +# 示例 1: +# +# +# +# +# 输入: root = [4,2,6,3,1,5], val = 1, +# +# depth = 2 +# 输出: [4,1,1,2,null,null,6,3,1,5] +# +# 示例 2: +# +# +# +# +# 输入: root = [4,2,null,3,1], val = 1, depth = 3 +# 输出: [4,2,null,1,1,3,null,null,1] +# +# +# +# +# 提示: +# +# +# 节点数在 [1, 104] 范围内 +# 树的深度在 [1, 104]范围内 +# -100 <= Node.val <= 100 +# -105 <= val <= 105 +# 1 <= depth <= the depth of tree + 1 +# +# Related Topics 树 深度优先搜索 广度优先搜索 二叉树 +# 👍 122 👎 0 + + +# leetcode submit region begin(Prohibit modification and deletion) +# Definition for a binary tree node. +# class TreeNode: +# def __init__(self, val=0, left=None, right=None): +# self.val = val +# self.left = left +# self.right = right +class Solution: + def addOneRow(self, root: TreeNode, val: int, depth: int) -> TreeNode: + def dfs(root, depth): + if not root: + return None + if depth ==1: + node = TreeNode(val) + node.left =root + return node + if depth==2: + left =TreeNode(val) + right = TreeNode(val) + left.left = root.left + right.right = root.right + root.left = left + root.right = right + return root + root.left = dfs(root.left, depth-1) + root.right = dfs(root.right, depth-1) + return root + return dfs(root, depth ) + +# leetcode submit region end(Prohibit modification and deletion) diff --git "a/script/[62]\344\270\215\345\220\214\350\267\257\345\276\204.py" "b/script/[62]\344\270\215\345\220\214\350\267\257\345\276\204.py" new file mode 100644 index 0000000..e8b64ff --- /dev/null +++ "b/script/[62]\344\270\215\345\220\214\350\267\257\345\276\204.py" @@ -0,0 +1,64 @@ +# 一个机器人位于一个 m x n 网格的左上角 (起始点在下图中标记为 “Start” )。 +# +# 机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角(在下图中标记为 “Finish” )。 +# +# 问总共有多少条不同的路径? +# +# +# +# 示例 1: +# +# +# 输入:m = 3, n = 7 +# 输出:28 +# +# 示例 2: +# +# +# 输入:m = 3, n = 2 +# 输出:3 +# 解释: +# 从左上角开始,总共有 3 条路径可以到达右下角。 +# 1. 向右 -> 向下 -> 向下 +# 2. 向下 -> 向下 -> 向右 +# 3. 向下 -> 向右 -> 向下 +# +# +# 示例 3: +# +# +# 输入:m = 7, n = 3 +# 输出:28 +# +# +# 示例 4: +# +# +# 输入:m = 3, n = 3 +# 输出:6 +# +# +# +# 提示: +# +# +# 1 <= m, n <= 100 +# 题目数据保证答案小于等于 2 * 109 +# +# Related Topics 数学 动态规划 组合数学 +# 👍 1468 👎 0 + + +# leetcode submit region begin(Prohibit modification and deletion) +class Solution: + def uniquePaths(self, m: int, n: int) -> int: + dp = [[0] *n for i in range(m)] + for i in range(n): + dp[0][i] =1 + for i in range(m): + dp[i][0] =1 + for i in range(1,m): + for j in range(1,n): + dp[i][j] = dp[i-1][j] + dp[i][j-1] + return dp[-1][-1] +# leetcode submit region end(Prohibit modification and deletion) diff --git "a/script/[63]\344\270\215\345\220\214\350\267\257\345\276\204 II.py" "b/script/[63]\344\270\215\345\220\214\350\267\257\345\276\204 II.py" new file mode 100644 index 0000000..31b7cbf --- /dev/null +++ "b/script/[63]\344\270\215\345\220\214\350\267\257\345\276\204 II.py" @@ -0,0 +1,63 @@ +# 一个机器人位于一个 m x n 网格的左上角 (起始点在下图中标记为 “Start” )。 +# +# 机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角(在下图中标记为 “Finish”)。 +# +# 现在考虑网格中有障碍物。那么从左上角到右下角将会有多少条不同的路径? +# +# 网格中的障碍物和空位置分别用 1 和 0 来表示。 +# +# +# +# 示例 1: +# +# +# 输入:obstacleGrid = [[0,0,0],[0,1,0],[0,0,0]] +# 输出:2 +# 解释:3x3 网格的正中间有一个障碍物。 +# 从左上角到右下角一共有 2 条不同的路径: +# 1. 向右 -> 向右 -> 向下 -> 向下 +# 2. 向下 -> 向下 -> 向右 -> 向右 +# +# +# 示例 2: +# +# +# 输入:obstacleGrid = [[0,1],[0,0]] +# 输出:1 +# +# +# +# +# 提示: +# +# +# m == obstacleGrid.length +# n == obstacleGrid[i].length +# 1 <= m, n <= 100 +# obstacleGrid[i][j] 为 0 或 1 +# +# Related Topics 数组 动态规划 矩阵 +# 👍 838 👎 0 + + +# leetcode submit region begin(Prohibit modification and deletion) +class Solution: + def uniquePathsWithObstacles(self, obstacleGrid: List[List[int]]) -> int: + m = len(obstacleGrid) + n = len(obstacleGrid[0]) + dp = [[0] *n for i in range(m)] + for i in range(n): + if obstacleGrid[0][i]==1: + break + dp[0][i] =1 + for i in range(m): + if obstacleGrid[i][0]==1: + break + dp[i][0] =1 + for i in range(1,m): + for j in range(1,n): + if obstacleGrid[i][j]==1: + continue + dp[i][j] = dp[i-1][j] + dp[i][j-1] + return dp[-1][-1] +# leetcode submit region end(Prohibit modification and deletion) diff --git "a/script/[643]\345\255\220\346\225\260\347\273\204\346\234\200\345\244\247\345\271\263\345\235\207\346\225\260 I.py" "b/script/[643]\345\255\220\346\225\260\347\273\204\346\234\200\345\244\247\345\271\263\345\235\207\346\225\260 I.py" new file mode 100644 index 0000000..649177d --- /dev/null +++ "b/script/[643]\345\255\220\346\225\260\347\273\204\346\234\200\345\244\247\345\271\263\345\235\207\346\225\260 I.py" @@ -0,0 +1,46 @@ +# 给你一个由 n 个元素组成的整数数组 nums 和一个整数 k 。 +# +# 请你找出平均数最大且 长度为 k 的连续子数组,并输出该最大平均数。 +# +# 任何误差小于 10-5 的答案都将被视为正确答案。 +# +# +# +# 示例 1: +# +# +# 输入:nums = [1,12,-5,-6,50,3], k = 4 +# 输出:12.75 +# 解释:最大平均数 (12-5-6+50)/4 = 51/4 = 12.75 +# +# +# 示例 2: +# +# +# 输入:nums = [5], k = 1 +# 输出:5.00000 +# +# +# +# +# 提示: +# +# +# n == nums.length +# 1 <= k <= n <= 105 +# -104 <= nums[i] <= 104 +# +# Related Topics 数组 滑动窗口 +# 👍 257 👎 0 + + +# leetcode submit region begin(Prohibit modification and deletion) +class Solution: + def findMaxAverage(self, nums: List[int], k: int) -> float: + ans = sum(nums[:k]) + cur = sum(nums[:k]) + for i in range(1, len(nums) - k + 1): + cur = cur - nums[i - 1] + nums[i + k - 1] + ans = max(ans, cur) + return ans / k +# leetcode submit region end(Prohibit modification and deletion) diff --git "a/script/[64]\346\234\200\345\260\217\350\267\257\345\276\204\345\222\214.py" "b/script/[64]\346\234\200\345\260\217\350\267\257\345\276\204\345\222\214.py" new file mode 100644 index 0000000..c5e0c84 --- /dev/null +++ "b/script/[64]\346\234\200\345\260\217\350\267\257\345\276\204\345\222\214.py" @@ -0,0 +1,51 @@ +# 给定一个包含非负整数的 m x n 网格 grid ,请找出一条从左上角到右下角的路径,使得路径上的数字总和为最小。 +# +# 说明:每次只能向下或者向右移动一步。 +# +# +# +# 示例 1: +# +# +# 输入:grid = [[1,3,1],[1,5,1],[4,2,1]] +# 输出:7 +# 解释:因为路径 1→3→1→1→1 的总和最小。 +# +# +# 示例 2: +# +# +# 输入:grid = [[1,2,3],[4,5,6]] +# 输出:12 +# +# +# +# +# 提示: +# +# +# m == grid.length +# n == grid[i].length +# 1 <= m, n <= 200 +# 0 <= grid[i][j] <= 100 +# +# Related Topics 数组 动态规划 矩阵 +# 👍 1298 👎 0 + + +# leetcode submit region begin(Prohibit modification and deletion) +class Solution: + def minPathSum(self, grid: List[List[int]]) -> int: + nrow = len(grid) + ncol = len(grid[-0]) + dp = [[0] *ncol for i in range(nrow)] + dp[0][0] = grid[0][0] + for i in range(1,nrow): + dp[i][0] = dp[i-1][0] + grid[i][0] + for i in range(1, ncol): + dp[0][i] = dp[0][i-1] + grid[0][i] + for i in range(1,nrow): + for j in range(1,ncol): + dp[i][j] = min(dp[i-1][j], dp[i][j-1])+ grid[i][j] + return dp[-1][-1] +# leetcode submit region end(Prohibit modification and deletion) diff --git "a/script/[652]\345\257\273\346\211\276\351\207\215\345\244\215\347\232\204\345\255\220\346\240\221.py" "b/script/[652]\345\257\273\346\211\276\351\207\215\345\244\215\347\232\204\345\255\220\346\240\221.py" new file mode 100644 index 0000000..2b13949 --- /dev/null +++ "b/script/[652]\345\257\273\346\211\276\351\207\215\345\244\215\347\232\204\345\255\220\346\240\221.py" @@ -0,0 +1,73 @@ +# 给定一棵二叉树 root,返回所有重复的子树。 +# +# 对于同一类的重复子树,你只需要返回其中任意一棵的根结点即可。 +# +# 如果两棵树具有相同的结构和相同的结点值,则它们是重复的。 +# +# +# +# 示例 1: +# +# +# +# +# 输入:root = [1,2,3,4,null,2,4,null,null,4] +# 输出:[[2,4],[4]] +# +# 示例 2: +# +# +# +# +# 输入:root = [2,1,1] +# 输出:[[1]] +# +# 示例 3: +# +# +# +# +# 输入:root = [2,2,2,3,null,3,null] +# 输出:[[2,3],[3]] +# +# +# +# 提示: +# +# +# 树中的结点数在[1,10^4]范围内。 +# -200 <= Node.val <= 200 +# +# Related Topics 树 深度优先搜索 哈希表 二叉树 +# 👍 443 👎 0 + + +# leetcode submit region begin(Prohibit modification and deletion) +# Definition for a binary tree node. +# class TreeNode: +# def __init__(self, val=0, left=None, right=None): +# self.val = val +# self.left = left +# self.right = right +class Solution: + def findDuplicateSubtrees(self, root: Optional[TreeNode]) -> List[Optional[TreeNode]]: + from collections import defaultdict + hash = defaultdict(int) + result = [] + def dfs(root): + nonlocal hash, result + if not root: + return '' + mid = root.val + left\ + = dfs(root.left) + right =dfs(root.right) + seralize = '{}.{}.{}'.format(mid,left,right) + hash[seralize]+=1 + if hash[seralize]==2: + result.append(root) + return seralize + dfs(root) + return result + +# leetcode submit region end(Prohibit modification and deletion) diff --git "a/script/[674]\346\234\200\351\225\277\350\277\236\347\273\255\351\200\222\345\242\236\345\272\217\345\210\227.py" "b/script/[674]\346\234\200\351\225\277\350\277\236\347\273\255\351\200\222\345\242\236\345\272\217\345\210\227.py" new file mode 100644 index 0000000..71fb446 --- /dev/null +++ "b/script/[674]\346\234\200\351\225\277\350\277\236\347\273\255\351\200\222\345\242\236\345\272\217\345\210\227.py" @@ -0,0 +1,51 @@ +# 给定一个未经排序的整数数组,找到最长且 连续递增的子序列,并返回该序列的长度。 +# +# 连续递增的子序列 可以由两个下标 l 和 r(l < r)确定,如果对于每个 l <= i < r,都有 nums[i] < nums[i + 1] ,那 +# 么子序列 [nums[l], nums[l + 1], ..., nums[r - 1], nums[r]] 就是连续递增子序列。 +# +# +# +# 示例 1: +# +# +# 输入:nums = [1,3,5,4,7] +# 输出:3 +# 解释:最长连续递增序列是 [1,3,5], 长度为3。 +# 尽管 [1,3,5,7] 也是升序的子序列, 但它不是连续的,因为 5 和 7 在原数组里被 4 隔开。 +# +# +# 示例 2: +# +# +# 输入:nums = [2,2,2,2,2] +# 输出:1 +# 解释:最长连续递增序列是 [2], 长度为1。 +# +# +# +# +# 提示: +# +# +# 1 <= nums.length <= 104 +# -109 <= nums[i] <= 109 +# +# Related Topics 数组 +# 👍 316 👎 0 + + +# leetcode submit region begin(Prohibit modification and deletion) +class Solution: + def findLengthOfLCIS(self, nums: List[int]) -> int: + maxl=1 + count=1 + for i in range(1,len(nums)): + if nums[i]> nums[i-1]: + count+=1 + else: + count=1 + maxl = max(maxl, count) + + + return maxl +# leetcode submit region end(Prohibit modification and deletion) diff --git "a/script/[678]\346\234\211\346\225\210\347\232\204\346\213\254\345\217\267\345\255\227\347\254\246\344\270\262.py" "b/script/[678]\346\234\211\346\225\210\347\232\204\346\213\254\345\217\267\345\255\227\347\254\246\344\270\262.py" new file mode 100644 index 0000000..b743e2b --- /dev/null +++ "b/script/[678]\346\234\211\346\225\210\347\232\204\346\213\254\345\217\267\345\255\227\347\254\246\344\270\262.py" @@ -0,0 +1,66 @@ +# 给定一个只包含三种字符的字符串:( ,) 和 *,写一个函数来检验这个字符串是否为有效字符串。有效字符串具有如下规则: +# +# +# 任何左括号 ( 必须有相应的右括号 )。 +# 任何右括号 ) 必须有相应的左括号 ( 。 +# 左括号 ( 必须在对应的右括号之前 )。 +# * 可以被视为单个右括号 ) ,或单个左括号 ( ,或一个空字符串。 +# 一个空字符串也被视为有效字符串。 +# +# +# 示例 1: +# +# +# 输入: "()" +# 输出: True +# +# +# 示例 2: +# +# +# 输入: "(*)" +# 输出: True +# +# +# 示例 3: +# +# +# 输入: "(*))" +# 输出: True +# +# +# 注意: +# +# +# 字符串大小将在 [1,100] 范围内。 +# +# Related Topics 栈 贪心 字符串 动态规划 +# 👍 508 👎 0 + + +# leetcode submit region begin(Prohibit modification and deletion) +class Solution: + def checkValidString(self, s: str) -> bool: + # 从左到右 + cnt =0 + for i in s: + if i=='(': + cnt+=1 + elif i==')': + cnt-=1 + else: + cnt+=1 + if cnt<0: + return False + cnt = 0 + for i in s[::-1]: + if i==')': + cnt+=1 + elif i=='(': + cnt-=1 + else: + cnt+=1 + if cnt<0: + return False + return True +# leetcode submit region end(Prohibit modification and deletion) diff --git "a/script/[696]\350\256\241\346\225\260\344\272\214\350\277\233\345\210\266\345\255\220\344\270\262.py" "b/script/[696]\350\256\241\346\225\260\344\272\214\350\277\233\345\210\266\345\255\220\344\270\262.py" new file mode 100644 index 0000000..59a91b0 --- /dev/null +++ "b/script/[696]\350\256\241\346\225\260\344\272\214\350\277\233\345\210\266\345\255\220\344\270\262.py" @@ -0,0 +1,51 @@ +# 给定一个字符串 s,统计并返回具有相同数量 0 和 1 的非空(连续)子字符串的数量,并且这些子字符串中的所有 0 和所有 1 都是成组连续的。 +# +# 重复出现(不同位置)的子串也要统计它们出现的次数。 +# +# +# 示例 1: +# +# +# 输入:s = "00110011" +# 输出:6 +# 解释:6 个子串满足具有相同数量的连续 1 和 0 :"0011"、"01"、"1100"、"10"、"0011" 和 "01" 。 +# 注意,一些重复出现的子串(不同位置)要统计它们出现的次数。 +# 另外,"00110011" 不是有效的子串,因为所有的 0(还有 1 )没有组合在一起。 +# +# 示例 2: +# +# +# 输入:s = "10101" +# 输出:4 +# 解释:有 4 个子串:"10"、"01"、"10"、"01" ,具有相同数量的连续 1 和 0 。 +# +# +# +# +# 提示: +# +# +# 1 <= s.length <= 105 +# s[i] 为 '0' 或 '1' +# +# Related Topics 双指针 字符串 +# 👍 468 👎 0 + + +# leetcode submit region begin(Prohibit modification and deletion) +class Solution: + def countBinarySubstrings(self, s: str) -> int: + count_list= [] + counter=1 + for i in range(1, len(s)): + if s[i]==s[i-1]: + counter+=1 + else: + count_list.append(counter) + counter=1 + count_list.append(counter) + total = 0 + for i in range(1, len(count_list)): + total+=min(count_list[i],count_list[i-1]) + return total +# leetcode submit region end(Prohibit modification and deletion) diff --git "a/script/[707]\350\256\276\350\256\241\351\223\276\350\241\250.py" "b/script/[707]\350\256\276\350\256\241\351\223\276\350\241\250.py" new file mode 100644 index 0000000..296cdfe --- /dev/null +++ "b/script/[707]\350\256\276\350\256\241\351\223\276\350\241\250.py" @@ -0,0 +1,96 @@ +# 设计链表的实现。您可以选择使用单链表或双链表。单链表中的节点应该具有两个属性:val 和 next。val 是当前节点的值,next 是指向下一个节点的指针 +# /引用。如果要使用双向链表,则还需要一个属性 prev 以指示链表中的上一个节点。假设链表中的所有节点都是 0-index 的。 +# +# 在链表类中实现这些功能: +# +# +# get(index):获取链表中第 index 个节点的值。如果索引无效,则返回-1。 +# addAtHead(val):在链表的第一个元素之前添加一个值为 val 的节点。插入后,新节点将成为链表的第一个节点。 +# addAtTail(val):将值为 val 的节点追加到链表的最后一个元素。 +# addAtIndex(index,val):在链表中的第 index 个节点之前添加值为 val 的节点。如果 index 等于链表的长度,则该节点将附加 +# 到链表的末尾。如果 index 大于链表长度,则不会插入节点。如果index小于0,则在头部插入节点。 +# deleteAtIndex(index):如果索引 index 有效,则删除链表中的第 index 个节点。 +# +# +# +# +# 示例: +# +# MyLinkedList linkedList = new MyLinkedList(); +# linkedList.addAtHead(1); +# linkedList.addAtTail(3); +# linkedList.addAtIndex(1,2); //链表变为1-> 2-> 3 +# linkedList.get(1); //返回2 +# linkedList.deleteAtIndex(1); //现在链表是1-> 3 +# linkedList.get(1); //返回3 +# +# +# +# +# 提示: +# +# +# 所有val值都在 [1, 1000] 之内。 +# 操作次数将在 [1, 1000] 之内。 +# 请不要使用内置的 LinkedList 库。 +# +# Related Topics 设计 链表 +# 👍 510 👎 0 + + +# leetcode submit region begin(Prohibit modification and deletion) +class MyLinkedList: + + def __init__(self): + self.head = ListNode(0) # dummy head + self.count =0 + + def get(self, index: int) -> int: + if 0<=index < self.count: + cur = self.head + for i in range(index+1): + cur = cur.next + return cur.val + else: + return -1 + + def addAtHead(self, val: int) -> None: + self.addAtIndex(0,val) + + def addAtTail(self, val: int) -> None: + self.addAtIndex(self.count, val) + + def addAtIndex(self, index: int, val: int) -> None: + #print(self.head) + if index> self.count: + return + elif index<0: + index =0 + cur = self.head + for _ in range(index): + cur = cur.next + add_node = ListNode(val) + tmp = cur.next + add_node.next = tmp + cur.next = add_node + self.count+=1 + + def deleteAtIndex(self, index: int) -> None: + if 0<=index < self.count: + cur = self.head + for i in range(index): + cur = cur.next + cur.next = cur.next.next + self.count-=1 + else: + return + + +# Your MyLinkedList object will be instantiated and called as such: +# obj = MyLinkedList() +# param_1 = obj.get(index) +# obj.addAtHead(val) +# obj.addAtTail(val) +# obj.addAtIndex(index,val) +# obj.deleteAtIndex(index) +# leetcode submit region end(Prohibit modification and deletion) diff --git "a/script/[70]\347\210\254\346\245\274\346\242\257.py" "b/script/[70]\347\210\254\346\245\274\346\242\257.py" new file mode 100644 index 0000000..981d76f --- /dev/null +++ "b/script/[70]\347\210\254\346\245\274\346\242\257.py" @@ -0,0 +1,47 @@ +# 假设你正在爬楼梯。需要 n 阶你才能到达楼顶。 +# +# 每次你可以爬 1 或 2 个台阶。你有多少种不同的方法可以爬到楼顶呢? +# +# +# +# 示例 1: +# +# +# 输入:n = 2 +# 输出:2 +# 解释:有两种方法可以爬到楼顶。 +# 1. 1 阶 + 1 阶 +# 2. 2 阶 +# +# 示例 2: +# +# +# 输入:n = 3 +# 输出:3 +# 解释:有三种方法可以爬到楼顶。 +# 1. 1 阶 + 1 阶 + 1 阶 +# 2. 1 阶 + 2 阶 +# 3. 2 阶 + 1 阶 +# +# +# +# +# 提示: +# +# +# 1 <= n <= 45 +# +# Related Topics 记忆化搜索 数学 动态规划 +# 👍 2541 👎 0 + + +# leetcode submit region begin(Prohibit modification and deletion) +class Solution: + def climbStairs(self, n: int) -> int: + if n<=2: + return n + dp = [1,1] + for i in range(1, n): + dp[1], dp[0] = dp[1]+dp[0], dp[1] + return dp[1] +# leetcode submit region end(Prohibit modification and deletion) diff --git "a/script/[714]\344\271\260\345\215\226\350\202\241\347\245\250\347\232\204\346\234\200\344\275\263\346\227\266\346\234\272\345\220\253\346\211\213\347\273\255\350\264\271.py" "b/script/[714]\344\271\260\345\215\226\350\202\241\347\245\250\347\232\204\346\234\200\344\275\263\346\227\266\346\234\272\345\220\253\346\211\213\347\273\255\350\264\271.py" new file mode 100644 index 0000000..33e6575 --- /dev/null +++ "b/script/[714]\344\271\260\345\215\226\350\202\241\347\245\250\347\232\204\346\234\200\344\275\263\346\227\266\346\234\272\345\220\253\346\211\213\347\273\255\350\264\271.py" @@ -0,0 +1,54 @@ +# 给定一个整数数组 prices,其中 prices[i]表示第 i 天的股票价格 ;整数 fee 代表了交易股票的手续费用。 +# +# 你可以无限次地完成交易,但是你每笔交易都需要付手续费。如果你已经购买了一个股票,在卖出它之前你就不能再继续购买股票了。 +# +# 返回获得利润的最大值。 +# +# 注意:这里的一笔交易指买入持有并卖出股票的整个过程,每笔交易你只需要为支付一次手续费。 +# +# +# +# 示例 1: +# +# +# 输入:prices = [1, 3, 2, 8, 4, 9], fee = 2 +# 输出:8 +# 解释:能够达到的最大利润: +# 在此处买入 prices[0] = 1 +# 在此处卖出 prices[3] = 8 +# 在此处买入 prices[4] = 4 +# 在此处卖出 prices[5] = 9 +# 总利润: ((8 - 1) - 2) + ((9 - 4) - 2) = 8 +# +# 示例 2: +# +# +# 输入:prices = [1,3,7,5,10,3], fee = 3 +# 输出:6 +# +# +# +# +# 提示: +# +# +# 1 <= prices.length <= 5 * 104 +# 1 <= prices[i] < 5 * 104 +# 0 <= fee < 5 * 104 +# +# Related Topics 贪心 数组 动态规划 +# 👍 756 👎 0 + + +# leetcode submit region begin(Prohibit modification and deletion) +class Solution: + def maxProfit(self, prices: List[int], fee: int) -> int: + l = len(prices) + dp1= [0] * l + dp2 = [0]*l + dp1[0] = -prices[0] + for i in range(1,l): + dp1[i] = max(dp1[i-1], -prices[i],dp2[i-1]-prices[i]) + dp2[i] = max(dp2[i-1], prices[i]+dp1[i-1]- fee) + return dp2[-1] +# leetcode submit region end(Prohibit modification and deletion) diff --git "a/script/[718]\346\234\200\351\225\277\351\207\215\345\244\215\345\255\220\346\225\260\347\273\204.py" "b/script/[718]\346\234\200\351\225\277\351\207\215\345\244\215\345\255\220\346\225\260\347\273\204.py" new file mode 100644 index 0000000..e69760a --- /dev/null +++ "b/script/[718]\346\234\200\351\225\277\351\207\215\345\244\215\345\255\220\346\225\260\347\273\204.py" @@ -0,0 +1,45 @@ +# 给两个整数数组 nums1 和 nums2 ,返回 两个数组中 公共的 、长度最长的子数组的长度 。 +# +# +# +# 示例 1: +# +# +# 输入:nums1 = [1,2,3,2,1], nums2 = [3,2,1,4,7] +# 输出:3 +# 解释:长度最长的公共子数组是 [3,2,1] 。 +# +# +# 示例 2: +# +# +# 输入:nums1 = [0,0,0,0,0], nums2 = [0,0,0,0,0] +# 输出:5 +# +# +# +# +# 提示: +# +# +# 1 <= nums1.length, nums2.length <= 1000 +# 0 <= nums1[i], nums2[i] <= 100 +# +# Related Topics 数组 二分查找 动态规划 滑动窗口 哈希函数 滚动哈希 +# 👍 756 👎 0 + + +# leetcode submit region begin(Prohibit modification and deletion) +class Solution: + def findLength(self, nums1: List[int], nums2: List[int]) -> int: + l1 = len(nums1) + l2 = len(nums2) + dp = [[0] * (l2+1)for i in range(l1+1)] + maxl = 0 + for i in range(1,l1+1): + for j in range(1, l2+1): + if nums1[i-1]==nums2[j-1]: + dp[i][j] = dp[i-1][j-1]+1 + maxl = max(maxl, dp[i][j]) + return maxl +# leetcode submit region end(Prohibit modification and deletion) diff --git "a/script/[724]\345\257\273\346\211\276\346\225\260\347\273\204\347\232\204\344\270\255\345\277\203\344\270\213\346\240\207.py" "b/script/[724]\345\257\273\346\211\276\346\225\260\347\273\204\347\232\204\344\270\255\345\277\203\344\270\213\346\240\207.py" new file mode 100644 index 0000000..56668da --- /dev/null +++ "b/script/[724]\345\257\273\346\211\276\346\225\260\347\273\204\347\232\204\344\270\255\345\277\203\344\270\213\346\240\207.py" @@ -0,0 +1,68 @@ +# 给你一个整数数组 nums ,请计算数组的 中心下标 。 +# +# 数组 中心下标 是数组的一个下标,其左侧所有元素相加的和等于右侧所有元素相加的和。 +# +# 如果中心下标位于数组最左端,那么左侧数之和视为 0 ,因为在下标的左侧不存在元素。这一点对于中心下标位于数组最右端同样适用。 +# +# 如果数组有多个中心下标,应该返回 最靠近左边 的那一个。如果数组不存在中心下标,返回 -1 。 +# +# +# +# 示例 1: +# +# +# 输入:nums = [1, 7, 3, 6, 5, 6] +# 输出:3 +# 解释: +# 中心下标是 3 。 +# 左侧数之和 sum = nums[0] + nums[1] + nums[2] = 1 + 7 + 3 = 11 , +# 右侧数之和 sum = nums[4] + nums[5] = 5 + 6 = 11 ,二者相等。 +# +# +# 示例 2: +# +# +# 输入:nums = [1, 2, 3] +# 输出:-1 +# 解释: +# 数组中不存在满足此条件的中心下标。 +# +# 示例 3: +# +# +# 输入:nums = [2, 1, -1] +# 输出:0 +# 解释: +# 中心下标是 0 。 +# 左侧数之和 sum = 0 ,(下标 0 左侧不存在元素), +# 右侧数之和 sum = nums[1] + nums[2] = 1 + -1 = 0 。 +# +# +# +# 提示: +# +# +# 1 <= nums.length <= 104 +# -1000 <= nums[i] <= 1000 +# +# +# +# +# 注意:本题与主站 1991 题相同:https://leetcode-cn.com/problems/find-the-middle-index-in-a +# rray/ +# Related Topics 数组 前缀和 +# 👍 439 👎 0 + + +# leetcode submit region begin(Prohibit modification and deletion) +class Solution: + def pivotIndex(self, nums: List[int]) -> int: + total =sum(nums) + left = 0 + for i in range(len(nums)): + if left == total-left - nums[i]: + return i + left +=nums[i] + return -1 + +# leetcode submit region end(Prohibit modification and deletion) diff --git "a/script/[725]\345\210\206\351\232\224\351\223\276\350\241\250.py" "b/script/[725]\345\210\206\351\232\224\351\223\276\350\241\250.py" new file mode 100644 index 0000000..291b9d6 --- /dev/null +++ "b/script/[725]\345\210\206\351\232\224\351\223\276\350\241\250.py" @@ -0,0 +1,74 @@ +# 给你一个头结点为 head 的单链表和一个整数 k ,请你设计一个算法将链表分隔为 k 个连续的部分。 +# +# 每部分的长度应该尽可能的相等:任意两部分的长度差距不能超过 1 。这可能会导致有些部分为 null 。 +# +# 这 k 个部分应该按照在链表中出现的顺序排列,并且排在前面的部分的长度应该大于或等于排在后面的长度。 +# +# 返回一个由上述 k 部分组成的数组。 +# +# +# 示例 1: +# +# +# 输入:head = [1,2,3], k = 5 +# 输出:[[1],[2],[3],[],[]] +# 解释: +# 第一个元素 output[0] 为 output[0].val = 1 ,output[0].next = null 。 +# 最后一个元素 output[4] 为 null ,但它作为 ListNode 的字符串表示是 [] 。 +# +# +# 示例 2: +# +# +# 输入:head = [1,2,3,4,5,6,7,8,9,10], k = 3 +# 输出:[[1,2,3,4],[5,6,7],[8,9,10]] +# 解释: +# 输入被分成了几个连续的部分,并且每部分的长度相差不超过 1 。前面部分的长度大于等于后面部分的长度。 +# +# +# +# +# 提示: +# +# +# 链表中节点的数目在范围 [0, 1000] +# 0 <= Node.val <= 1000 +# 1 <= k <= 50 +# +# Related Topics 链表 +# 👍 269 👎 0 + + +# leetcode submit region begin(Prohibit modification and deletion) +# Definition for singly-linked list. +# class ListNode: +# def __init__(self, val=0, next=None): +# self.val = val +# self.next = next +class Solution: + def splitListToParts(self, head: ListNode, k: int) -> List[ListNode]: + l = 0 + ptr = head + while ptr: + ptr = ptr.next + l+=1 + l_chunk, remainder = l//k, l%k + result = [None for _ in range(k)] + i =0 + while head and i rorse (将 'h' 替换为 'r') +# rorse -> rose (删除 'r') +# rose -> ros (删除 'e') +# +# +# 示例 2: +# +# +# 输入:word1 = "intention", word2 = "execution" +# 输出:5 +# 解释: +# intention -> inention (删除 't') +# inention -> enention (将 'i' 替换为 'e') +# enention -> exention (将 'n' 替换为 'x') +# exention -> exection (将 'n' 替换为 'c') +# exection -> execution (插入 'u') +# +# +# +# +# 提示: +# +# +# 0 <= word1.length, word2.length <= 500 +# word1 和 word2 由小写英文字母组成 +# +# Related Topics 字符串 动态规划 +# 👍 2497 👎 0 + + +# leetcode submit region begin(Prohibit modification and deletion) +class Solution: + def minDistance(self, word1: str, word2: str) -> int: + l1 = len(word1) + l2 = len(word2) + dp = [[0] * (l2+1) for i in range(l1+1)] + for i in range(1, l1+1): + dp[i][0] = i + for i in range(1, l2+1): + dp[0][i] = i + + for i in range(1, l1+1): + for j in range(1,l2+1): + if word1[i-1]==word2[j-1]: + dp[i][j] = dp[i-1][j-1] + else: + dp[i][j] = min(dp[i-1][j-1]+1, dp[i-1][j]+1, dp[i][j-1]+1) + return dp[-1][-1] +# leetcode submit region end(Prohibit modification and deletion) diff --git "a/script/[733]\345\233\276\345\203\217\346\270\262\346\237\223.py" "b/script/[733]\345\233\276\345\203\217\346\270\262\346\237\223.py" new file mode 100644 index 0000000..48405c7 --- /dev/null +++ "b/script/[733]\345\233\276\345\203\217\346\270\262\346\237\223.py" @@ -0,0 +1,67 @@ +# 有一幅以 m x n 的二维整数数组表示的图画 image ,其中 image[i][j] 表示该图画的像素值大小。 +# +# 你也被给予三个整数 sr , sc 和 newColor 。你应该从像素 image[sr][sc] 开始对图像进行 上色填充 。 +# +# 为了完成 上色工作 ,从初始像素开始,记录初始坐标的 上下左右四个方向上 像素值与初始坐标相同的相连像素点,接着再记录这四个方向上符合条件的像素点与他们对 +# 应 四个方向上 像素值与初始坐标相同的相连像素点,……,重复该过程。将所有有记录的像素点的颜色值改为 newColor 。 +# +# 最后返回 经过上色渲染后的图像 。 +# +# +# +# 示例 1: +# +# +# +# +# 输入: image = [[1,1,1],[1,1,0],[1,0,1]],sr = 1, sc = 1, newColor = 2 +# 输出: [[2,2,2],[2,2,0],[2,0,1]] +# 解析: 在图像的正中间,(坐标(sr,sc)=(1,1)),在路径上所有符合条件的像素点的颜色都被更改成2。 +# 注意,右下角的像素没有更改为2,因为它不是在上下左右四个方向上与初始点相连的像素点。 +# +# +# 示例 2: +# +# +# 输入: image = [[0,0,0],[0,0,0]], sr = 0, sc = 0, newColor = 2 +# 输出: [[2,2,2],[2,2,2]] +# +# +# +# +# 提示: +# +# +# m == image.length +# n == image[i].length +# 1 <= m, n <= 50 +# 0 <= image[i][j], newColor < 216 +# 0 <= sr < m +# 0 <= sc < n +# +# Related Topics 深度优先搜索 广度优先搜索 数组 矩阵 +# 👍 351 👎 0 + + +# leetcode submit region begin(Prohibit modification and deletion) +class Solution: + def floodFill(self, image: List[List[int]], sr: int, sc: int, color: int) -> List[List[int]]: + curval = image[sr][sc] + if curval == color: + return image + stack = [(sr,sc)] + image[sr][sc]=color + + nrow = len(image) + ncol = len(image[0]) + while stack: + pos = stack.pop() + r = pos[0] + c = pos[1] + for row, col in [(r-1,c),(r,c-1), (r+1,c), (r,c+1)]: + if row >=0 and row =0 and col < ncol and image[row][col]==curval: + stack.append((row,col)) + image[row][col] = color + return image + +# leetcode submit region end(Prohibit modification and deletion) diff --git "a/script/[738]\345\215\225\350\260\203\351\200\222\345\242\236\347\232\204\346\225\260\345\255\227.py" "b/script/[738]\345\215\225\350\260\203\351\200\222\345\242\236\347\232\204\346\225\260\345\255\227.py" new file mode 100644 index 0000000..598b452 --- /dev/null +++ "b/script/[738]\345\215\225\350\260\203\351\200\222\345\242\236\347\232\204\346\225\260\345\255\227.py" @@ -0,0 +1,49 @@ +# 当且仅当每个相邻位数上的数字 x 和 y 满足 x <= y 时,我们称这个整数是单调递增的。 +# +# 给定一个整数 n ,返回 小于或等于 n 的最大数字,且数字呈 单调递增 。 +# +# +# +# 示例 1: +# +# +# 输入: n = 10 +# 输出: 9 +# +# +# 示例 2: +# +# +# 输入: n = 1234 +# 输出: 1234 +# +# +# 示例 3: +# +# +# 输入: n = 332 +# 输出: 299 +# +# +# +# +# 提示: +# +# +# 0 <= n <= 109 +# +# Related Topics 贪心 数学 +# 👍 274 👎 0 + + +# leetcode submit region begin(Prohibit modification and deletion) +class Solution: + def monotoneIncreasingDigits(self, n: int) -> int: + s=list(str(n)) + l = len(s) + for i in range(l-1, 0, -1): + if s[i-1]>s[i]: + s[i-1] = str(int(s[i-1])-1) + s[i:] = ['9'] * (l-i) + return int(''.join(s)) +# leetcode submit region end(Prohibit modification and deletion) diff --git "a/script/[746]\344\275\277\347\224\250\346\234\200\345\260\217\350\212\261\350\264\271\347\210\254\346\245\274\346\242\257.py" "b/script/[746]\344\275\277\347\224\250\346\234\200\345\260\217\350\212\261\350\264\271\347\210\254\346\245\274\346\242\257.py" new file mode 100644 index 0000000..e548a40 --- /dev/null +++ "b/script/[746]\344\275\277\347\224\250\346\234\200\345\260\217\350\212\261\350\264\271\347\210\254\346\245\274\346\242\257.py" @@ -0,0 +1,56 @@ +# 给你一个整数数组 cost ,其中 cost[i] 是从楼梯第 i 个台阶向上爬需要支付的费用。一旦你支付此费用,即可选择向上爬一个或者两个台阶。 +# +# 你可以选择从下标为 0 或下标为 1 的台阶开始爬楼梯。 +# +# 请你计算并返回达到楼梯顶部的最低花费。 +# +# +# +# 示例 1: +# +# +# 输入:cost = [10,15,20] +# 输出:15 +# 解释:你将从下标为 1 的台阶开始。 +# - 支付 15 ,向上爬两个台阶,到达楼梯顶部。 +# 总花费为 15 。 +# +# +# 示例 2: +# +# +# 输入:cost = [1,100,1,1,1,100,1,1,100,1] +# 输出:6 +# 解释:你将从下标为 0 的台阶开始。 +# - 支付 1 ,向上爬两个台阶,到达下标为 2 的台阶。 +# - 支付 1 ,向上爬两个台阶,到达下标为 4 的台阶。 +# - 支付 1 ,向上爬两个台阶,到达下标为 6 的台阶。 +# - 支付 1 ,向上爬一个台阶,到达下标为 7 的台阶。 +# - 支付 1 ,向上爬两个台阶,到达下标为 9 的台阶。 +# - 支付 1 ,向上爬一个台阶,到达楼梯顶部。 +# 总花费为 6 。 +# +# +# +# +# 提示: +# +# +# 2 <= cost.length <= 1000 +# 0 <= cost[i] <= 999 +# +# Related Topics 数组 动态规划 +# 👍 963 👎 0 + + +# leetcode submit region begin(Prohibit modification and deletion) +class Solution: + def minCostClimbingStairs(self, cost: List[int]) -> int: + l = len(cost) + dp = [0] * l + dp[0] = cost[0] + dp[1] = cost[1] + for i in range(2,l): + dp[i] = min(dp[i-1],dp[i-2])+cost[i] + return min(dp[-1],dp[-2]) +# leetcode submit region end(Prohibit modification and deletion) diff --git "a/script/[747]\350\207\263\345\260\221\346\230\257\345\205\266\344\273\226\346\225\260\345\255\227\344\270\244\345\200\215\347\232\204\346\234\200\345\244\247\346\225\260.py" "b/script/[747]\350\207\263\345\260\221\346\230\257\345\205\266\344\273\226\346\225\260\345\255\227\344\270\244\345\200\215\347\232\204\346\234\200\345\244\247\346\225\260.py" new file mode 100644 index 0000000..ae8840b --- /dev/null +++ "b/script/[747]\350\207\263\345\260\221\346\230\257\345\205\266\344\273\226\346\225\260\345\255\227\344\270\244\345\200\215\347\232\204\346\234\200\345\244\247\346\225\260.py" @@ -0,0 +1,63 @@ +# 给你一个整数数组 nums ,其中总是存在 唯一的 一个最大整数 。 +# +# 请你找出数组中的最大元素并检查它是否 至少是数组中每个其他数字的两倍 。如果是,则返回 最大元素的下标 ,否则返回 -1 。 +# +# +# +# 示例 1: +# +# +# 输入:nums = [3,6,1,0] +# 输出:1 +# 解释:6 是最大的整数,对于数组中的其他整数,6 至少是数组中其他元素的两倍。6 的下标是 1 ,所以返回 1 。 +# +# +# 示例 2: +# +# +# 输入:nums = [1,2,3,4] +# 输出:-1 +# 解释:4 没有超过 3 的两倍大,所以返回 -1 。 +# +# 示例 3: +# +# +# 输入:nums = [1] +# 输出:0 +# 解释:因为不存在其他数字,所以认为现有数字 1 至少是其他数字的两倍。 +# +# +# +# +# 提示: +# +# +# 1 <= nums.length <= 50 +# 0 <= nums[i] <= 100 +# nums 中的最大元素是唯一的 +# +# Related Topics 数组 排序 +# 👍 171 👎 0 + + +# leetcode submit region begin(Prohibit modification and deletion) +class Solution: + def dominantIndex(self, nums: List[int]) -> int: + if len(nums)==1: + return 0 + #这里可以简单用相同的数值赋值 + first = nums[0] + second = 0 #这里是因为nums本身有界 + index =0 + for i in range(1, len(nums)): + if nums[i]> first: + first,second = nums[i],first + index = i + elif nums[i]<=first and nums[i]>second: + second = nums[i] + if first >= 2*second: + return index + else: + return -1 + +# leetcode submit region end(Prohibit modification and deletion) diff --git "a/script/[79]\345\215\225\350\257\215\346\220\234\347\264\242.py" "b/script/[79]\345\215\225\350\257\215\346\220\234\347\264\242.py" new file mode 100644 index 0000000..a29a65b --- /dev/null +++ "b/script/[79]\345\215\225\350\257\215\346\220\234\347\264\242.py" @@ -0,0 +1,77 @@ +# 给定一个 m x n 二维字符网格 board 和一个字符串单词 word 。如果 word 存在于网格中,返回 true ;否则,返回 false 。 +# +# 单词必须按照字母顺序,通过相邻的单元格内的字母构成,其中“相邻”单元格是那些水平相邻或垂直相邻的单元格。同一个单元格内的字母不允许被重复使用。 +# +# +# +# 示例 1: +# +# +# 输入:board = [["A","B","C","E"],["S","F","C","S"],["A","D","E","E"]], word = "AB +# CCED" +# 输出:true +# +# +# 示例 2: +# +# +# 输入:board = [["A","B","C","E"],["S","F","C","S"],["A","D","E","E"]], word = "SE +# E" +# 输出:true +# +# +# 示例 3: +# +# +# 输入:board = [["A","B","C","E"],["S","F","C","S"],["A","D","E","E"]], word = "AB +# CB" +# 输出:false +# +# +# +# +# 提示: +# +# +# m == board.length +# n = board[i].length +# 1 <= m, n <= 6 +# 1 <= word.length <= 15 +# board 和 word 仅由大小写英文字母组成 +# +# +# +# +# 进阶:你可以使用搜索剪枝的技术来优化解决方案,使其在 board 更大的情况下可以更快解决问题? +# Related Topics 数组 回溯 矩阵 +# 👍 1378 👎 0 + + +# leetcode submit region begin(Prohibit modification and deletion) +class Solution: + def exist(self, board: List[List[str]], word: str) -> bool: + nrow = len(board) + ncol = len(board[0]) + visited = set() + + def dfs(r,c, word): + if board[r][c]!=word[0]: + return False + elif len(word)==1: + return True + visited.add((r,c)) + for i,j in [(r+1,c),(r,c+1),(r-1,c),(r,c-1)]: + if 0<=i List[int]: + l = len(s) + answer = [l+1] * l + index = -(l+1) + for i in range(l): + if s[i]==c: + index=i + answer[i] = min(answer[i], i-index) + index = 2*l + for i in range(l-1, -1,-1): + if s[i]==c: + index=i + answer[i] = min(answer[i], index-i) + return answer +# leetcode submit region end(Prohibit modification and deletion) diff --git "a/script/[82]\345\210\240\351\231\244\346\216\222\345\272\217\351\223\276\350\241\250\344\270\255\347\232\204\351\207\215\345\244\215\345\205\203\347\264\240 II.py" "b/script/[82]\345\210\240\351\231\244\346\216\222\345\272\217\351\223\276\350\241\250\344\270\255\347\232\204\351\207\215\345\244\215\345\205\203\347\264\240 II.py" new file mode 100644 index 0000000..4d7776a --- /dev/null +++ "b/script/[82]\345\210\240\351\231\244\346\216\222\345\272\217\351\223\276\350\241\250\344\270\255\347\232\204\351\207\215\345\244\215\345\205\203\347\264\240 II.py" @@ -0,0 +1,52 @@ +# 给定一个已排序的链表的头 head , 删除原始链表中所有重复数字的节点,只留下不同的数字 。返回 已排序的链表 。 +# +# +# +# 示例 1: +# +# +# 输入:head = [1,2,3,3,4,4,5] +# 输出:[1,2,5] +# +# +# 示例 2: +# +# +# 输入:head = [1,1,1,2,3] +# 输出:[2,3] +# +# +# +# +# 提示: +# +# +# 链表中节点数目在范围 [0, 300] 内 +# -100 <= Node.val <= 100 +# 题目数据保证链表已经按升序 排列 +# +# Related Topics 链表 双指针 +# 👍 952 👎 0 + + +# leetcode submit region begin(Prohibit modification and deletion) +# Definition for singly-linked list. +# class ListNode: +# def __init__(self, val=0, next=None): +# self.val = val +# self.next = next +class Solution: + def deleteDuplicates(self, head: ListNode) -> ListNode: + dummy = ListNode() + dummy.next = head + ptr = dummy + while ptr.next and ptr.next.next: + val = ptr.next.val + if val == ptr.next.next.val: + while ptr.next and ptr.next.val==val: + ptr.next = ptr.next.next + else: + ptr = ptr.next + return dummy.next + +# leetcode submit region end(Prohibit modification and deletion) diff --git "a/script/[830]\350\276\203\345\244\247\345\210\206\347\273\204\347\232\204\344\275\215\347\275\256.py" "b/script/[830]\350\276\203\345\244\247\345\210\206\347\273\204\347\232\204\344\275\215\347\275\256.py" new file mode 100644 index 0000000..9da793a --- /dev/null +++ "b/script/[830]\350\276\203\345\244\247\345\210\206\347\273\204\347\232\204\344\275\215\347\275\256.py" @@ -0,0 +1,73 @@ +# 在一个由小写字母构成的字符串 s 中,包含由一些连续的相同字符所构成的分组。 +# +# 例如,在字符串 s = "abbxxxxzyy" 中,就含有 "a", "bb", "xxxx", "z" 和 "yy" 这样的一些分组。 +# +# 分组可以用区间 [start, end] 表示,其中 start 和 end 分别表示该分组的起始和终止位置的下标。上例中的 "xxxx" 分组用区间表示 +# 为 [3,6] 。 +# +# 我们称所有包含大于或等于三个连续字符的分组为 较大分组 。 +# +# 找到每一个 较大分组 的区间,按起始位置下标递增顺序排序后,返回结果。 +# +# +# +# 示例 1: +# +# +# 输入:s = "abbxxxxzzy" +# 输出:[[3,6]] +# 解释:"xxxx" 是一个起始于 3 且终止于 6 的较大分组。 +# +# +# 示例 2: +# +# +# 输入:s = "abc" +# 输出:[] +# 解释:"a","b" 和 "c" 均不是符合要求的较大分组。 +# +# +# 示例 3: +# +# +# 输入:s = "abcdddeeeeaabbbcd" +# 输出:[[3,5],[6,9],[12,14]] +# 解释:较大分组为 "ddd", "eeee" 和 "bbb" +# +# 示例 4: +# +# +# 输入:s = "aba" +# 输出:[] +# +# +# +# 提示: +# +# +# 1 <= s.length <= 1000 +# s 仅含小写英文字母 +# +# Related Topics 字符串 +# 👍 132 👎 0 + + +# leetcode submit region begin(Prohibit modification and deletion) +class Solution: + def largeGroupPositions(self, s: str) -> List[List[int]]: + left=0 + right=0 + result = [] + for i in range(1,len(s)): + if s[i]==s[i-1]: + right=i + else: + if right-left>=2: + result.append([left,right]) + left=i + right=i + if right - left >= 2: + result.append([left, right]) + return result + +# leetcode submit region end(Prohibit modification and deletion) diff --git "a/script/[832]\347\277\273\350\275\254\345\233\276\345\203\217.py" "b/script/[832]\347\277\273\350\275\254\345\233\276\345\203\217.py" new file mode 100644 index 0000000..686da3d --- /dev/null +++ "b/script/[832]\347\277\273\350\275\254\345\233\276\345\203\217.py" @@ -0,0 +1,61 @@ +# 给定一个 n x n 的二进制矩阵 image ,先 水平 翻转图像,然后 反转 图像并返回 结果 。 +# +# 水平翻转图片就是将图片的每一行都进行翻转,即逆序。 +# +# +# 例如,水平翻转 [1,1,0] 的结果是 [0,1,1]。 +# +# +# 反转图片的意思是图片中的 0 全部被 1 替换, 1 全部被 0 替换。 +# +# +# 例如,反转 [0,1,1] 的结果是 [1,0,0]。 +# +# +# +# +# 示例 1: +# +# +# 输入:image = [[1,1,0],[1,0,1],[0,0,0]] +# 输出:[[1,0,0],[0,1,0],[1,1,1]] +# 解释:首先翻转每一行: [[0,1,1],[1,0,1],[0,0,0]]; +# 然后反转图片: [[1,0,0],[0,1,0],[1,1,1]] +# +# +# 示例 2: +# +# +# 输入:image = [[1,1,0,0],[1,0,0,1],[0,1,1,1],[1,0,1,0]] +# 输出:[[1,1,0,0],[0,1,1,0],[0,0,0,1],[1,0,1,0]] +# 解释:首先翻转每一行: [[0,0,1,1],[1,0,0,1],[1,1,1,0],[0,1,0,1]]; +# 然后反转图片: [[1,1,0,0],[0,1,1,0],[0,0,0,1],[1,0,1,0]] +# +# +# +# +# 提示: +# +# +# +# +# n == image.length +# n == image[i].length +# 1 <= n <= 20 +# images[i][j] == 0 或 1. +# +# Related Topics 数组 双指针 矩阵 模拟 +# 👍 282 👎 0 + + +# leetcode submit region begin(Prohibit modification and deletion) +class Solution: + def flipAndInvertImage(self, image: List[List[int]]) -> List[List[int]]: + n = len(image) + for i in range(n): + image[i][:] = image[i][::-1] + for i in range(n): + image[i][:] = [1-i for i in image[i][:]] + return image + +# leetcode submit region end(Prohibit modification and deletion) diff --git "a/script/[83]\345\210\240\351\231\244\346\216\222\345\272\217\351\223\276\350\241\250\344\270\255\347\232\204\351\207\215\345\244\215\345\205\203\347\264\240.py" "b/script/[83]\345\210\240\351\231\244\346\216\222\345\272\217\351\223\276\350\241\250\344\270\255\347\232\204\351\207\215\345\244\215\345\205\203\347\264\240.py" new file mode 100644 index 0000000..626a835 --- /dev/null +++ "b/script/[83]\345\210\240\351\231\244\346\216\222\345\272\217\351\223\276\350\241\250\344\270\255\347\232\204\351\207\215\345\244\215\345\205\203\347\264\240.py" @@ -0,0 +1,47 @@ +# 给定一个已排序的链表的头 head , 删除所有重复的元素,使每个元素只出现一次 。返回 已排序的链表 。 +# +# +# +# 示例 1: +# +# +# 输入:head = [1,1,2] +# 输出:[1,2] +# +# +# 示例 2: +# +# +# 输入:head = [1,1,2,3,3] +# 输出:[1,2,3] +# +# +# +# +# 提示: +# +# +# 链表中节点数目在范围 [0, 300] 内 +# -100 <= Node.val <= 100 +# 题目数据保证链表已经按升序 排列 +# +# Related Topics 链表 +# 👍 827 👎 0 + + +# leetcode submit region begin(Prohibit modification and deletion) +# Definition for singly-linked list. +# class ListNode: +# def __init__(self, val=0, next=None): +# self.val = val +# self.next = next +class Solution: + def deleteDuplicates(self, head: ListNode) -> ListNode: + ptr =head + while ptr and ptr.next: + if ptr.val == ptr.next.val: + ptr.next = ptr.next.next + else: + ptr = ptr.next + return head +# leetcode submit region end(Prohibit modification and deletion) diff --git "a/script/[860]\346\237\240\346\252\254\346\260\264\346\211\276\351\233\266.py" "b/script/[860]\346\237\240\346\252\254\346\260\264\346\211\276\351\233\266.py" new file mode 100644 index 0000000..bfb2670 --- /dev/null +++ "b/script/[860]\346\237\240\346\252\254\346\260\264\346\211\276\351\233\266.py" @@ -0,0 +1,72 @@ +# 在柠檬水摊上,每一杯柠檬水的售价为 5 美元。顾客排队购买你的产品,(按账单 bills 支付的顺序)一次购买一杯。 +# +# 每位顾客只买一杯柠檬水,然后向你付 5 美元、10 美元或 20 美元。你必须给每个顾客正确找零,也就是说净交易是每位顾客向你支付 5 美元。 +# +# 注意,一开始你手头没有任何零钱。 +# +# 给你一个整数数组 bills ,其中 bills[i] 是第 i 位顾客付的账。如果你能给每位顾客正确找零,返回 true ,否则返回 false 。 +# +# +# +# 示例 1: +# +# +# 输入:bills = [5,5,5,10,20] +# 输出:true +# 解释: +# 前 3 位顾客那里,我们按顺序收取 3 张 5 美元的钞票。 +# 第 4 位顾客那里,我们收取一张 10 美元的钞票,并返还 5 美元。 +# 第 5 位顾客那里,我们找还一张 10 美元的钞票和一张 5 美元的钞票。 +# 由于所有客户都得到了正确的找零,所以我们输出 true。 +# +# +# 示例 2: +# +# +# 输入:bills = [5,5,10,10,20] +# 输出:false +# 解释: +# 前 2 位顾客那里,我们按顺序收取 2 张 5 美元的钞票。 +# 对于接下来的 2 位顾客,我们收取一张 10 美元的钞票,然后返还 5 美元。 +# 对于最后一位顾客,我们无法退回 15 美元,因为我们现在只有两张 10 美元的钞票。 +# 由于不是每位顾客都得到了正确的找零,所以答案是 false。 +# +# +# +# +# 提示: +# +# +# 1 <= bills.length <= 105 +# bills[i] 不是 5 就是 10 或是 20 +# +# Related Topics 贪心 数组 +# 👍 352 👎 0 + + +# leetcode submit region begin(Prohibit modification and deletion) +class Solution: + def lemonadeChange(self, bills: List[int]) -> bool: + dic = defaultdict(int) + for i in bills: + if i == 5: + dic[5] += 1 + elif i == 10: + if dic[5] < 1: + return False + else: + dic[10] += 1 + dic[5] -= 1 + else: + if dic[10] >= 1 and dic[5] >= 1: + dic[10] -= 1 + dic[5] -= 1 + dic[20] += 1 + elif dic[5] >= 3: + dic[20] += 1 + dic[5] -= 3 + else: + return False + + return True + # leetcode submit region end(Prohibit modification and deletion) diff --git "a/script/[86]\345\210\206\351\232\224\351\223\276\350\241\250.py" "b/script/[86]\345\210\206\351\232\224\351\223\276\350\241\250.py" new file mode 100644 index 0000000..0f4a215 --- /dev/null +++ "b/script/[86]\345\210\206\351\232\224\351\223\276\350\241\250.py" @@ -0,0 +1,57 @@ +# 给你一个链表的头节点 head 和一个特定值 x ,请你对链表进行分隔,使得所有 小于 x 的节点都出现在 大于或等于 x 的节点之前。 +# +# 你应当 保留 两个分区中每个节点的初始相对位置。 +# +# +# +# 示例 1: +# +# +# 输入:head = [1,4,3,2,5,2], x = 3 +# 输出:[1,2,2,4,3,5] +# +# +# 示例 2: +# +# +# 输入:head = [2,1], x = 2 +# 输出:[1,2] +# +# +# +# +# 提示: +# +# +# 链表中节点的数目在范围 [0, 200] 内 +# -100 <= Node.val <= 100 +# -200 <= x <= 200 +# +# Related Topics 链表 双指针 +# 👍 595 👎 0 + + +# leetcode submit region begin(Prohibit modification and deletion) +# Definition for singly-linked list. +# class ListNode: +# def __init__(self, val=0, next=None): +# self.val = val +# self.next = next +class Solution: + def partition(self, head: ListNode, x: int) -> ListNode: + small = ListNode() + big = ListNode() + ptr_small = small + ptr_big = big + while head: + if head.val >= x: + ptr_big.next= head + ptr_big = ptr_big.next + else: + ptr_small.next=head + ptr_small = ptr_small.next + head = head.next + ptr_small.next= big.next + ptr_big.next =None + return small.next +# leetcode submit region end(Prohibit modification and deletion) diff --git "a/script/[872]\345\217\266\345\255\220\347\233\270\344\274\274\347\232\204\346\240\221.py" "b/script/[872]\345\217\266\345\255\220\347\233\270\344\274\274\347\232\204\346\240\221.py" index 92d10de..f6d953d 100644 --- "a/script/[872]\345\217\266\345\255\220\347\233\270\344\274\274\347\232\204\346\240\221.py" +++ "b/script/[872]\345\217\266\345\255\220\347\233\270\344\274\274\347\232\204\346\240\221.py" @@ -55,7 +55,7 @@ def seralize(root, ans): return if not root.left and not root.right: ans.append(root.val) - return ans + return seralize(root.left, ans) seralize(root.right, ans) return ans diff --git "a/script/[876]\351\223\276\350\241\250\347\232\204\344\270\255\351\227\264\347\273\223\347\202\271.py" "b/script/[876]\351\223\276\350\241\250\347\232\204\344\270\255\351\227\264\347\273\223\347\202\271.py" new file mode 100644 index 0000000..8f9ff4a --- /dev/null +++ "b/script/[876]\351\223\276\350\241\250\347\232\204\344\270\255\351\227\264\347\273\223\347\202\271.py" @@ -0,0 +1,50 @@ +# 给定一个头结点为 head 的非空单链表,返回链表的中间结点。 +# +# 如果有两个中间结点,则返回第二个中间结点。 +# +# +# +# 示例 1: +# +# +# 输入:[1,2,3,4,5] +# 输出:此列表中的结点 3 (序列化形式:[3,4,5]) +# 返回的结点值为 3 。 (测评系统对该结点序列化表述是 [3,4,5])。 +# 注意,我们返回了一个 ListNode 类型的对象 ans,这样: +# ans.val = 3, ans.next.val = 4, ans.next.next.val = 5, 以及 ans.next.next.next = +# NULL. +# +# +# 示例 2: +# +# +# 输入:[1,2,3,4,5,6] +# 输出:此列表中的结点 4 (序列化形式:[4,5,6]) +# 由于该列表有两个中间结点,值分别为 3 和 4,我们返回第二个结点。 +# +# +# +# +# 提示: +# +# +# 给定链表的结点数介于 1 和 100 之间。 +# +# Related Topics 链表 双指针 +# 👍 636 👎 0 + + +# leetcode submit region begin(Prohibit modification and deletion) +# Definition for singly-linked list. +# class ListNode: +# def __init__(self, val=0, next=None): +# self.val = val +# self.next = next +class Solution: + def middleNode(self, head: ListNode) -> ListNode: + slow, fast = head,head + while fast and fast.next: + fast = fast.next.next + slow = slow.next + return slow +# leetcode submit region end(Prohibit modification and deletion) diff --git "a/script/[92]\345\217\215\350\275\254\351\223\276\350\241\250 II.py" "b/script/[92]\345\217\215\350\275\254\351\223\276\350\241\250 II.py" new file mode 100644 index 0000000..931fc1f --- /dev/null +++ "b/script/[92]\345\217\215\350\275\254\351\223\276\350\241\250 II.py" @@ -0,0 +1,74 @@ +# 给你单链表的头指针 head 和两个整数 left 和 right ,其中 left <= right 。请你反转从位置 left 到位置 right 的链 +# 表节点,返回 反转后的链表 。 +# +# +# 示例 1: +# +# +# 输入:head = [1,2,3,4,5], left = 2, right = 4 +# 输出:[1,4,3,2,5] +# +# +# 示例 2: +# +# +# 输入:head = [5], left = 1, right = 1 +# 输出:[5] +# +# +# +# +# 提示: +# +# +# 链表中节点数目为 n +# 1 <= n <= 500 +# -500 <= Node.val <= 500 +# 1 <= left <= right <= n +# +# +# +# +# 进阶: 你可以使用一趟扫描完成反转吗? +# Related Topics 链表 +# 👍 1356 👎 0 + + +# leetcode submit region begin(Prohibit modification and deletion) +# Definition for singly-linked list. +# class ListNode: +# def __init__(self, val=0, next=None): +# self.val = val +# self.next = next +class Solution: + def reverseBetween(self, head: ListNode, left: int, right: int) -> ListNode: + dummy = ListNode() + dummy.next = head + + ptrl,ptrr = dummy,dummy + for i in range(left-1): + ptrl = ptrl.next + for i in range(right): + ptrr = ptrr.next + + left = ptrl.next + # 断开右边 + right = ptrr + right_next = right.next + right.next = None + + def reverse(head): + newnode = None + cur = head + while cur: + nextnode = cur.next + cur.next=newnode + newnode = cur + cur = nextnode + return newnode + + mid = reverse(left) #翻转 + ptrl.next = mid #左边接入 + left.next = right_next # 右边接入 + return dummy.next +# leetcode submit region end(Prohibit modification and deletion) diff --git "a/script/[95]\344\270\215\345\220\214\347\232\204\344\272\214\345\217\211\346\220\234\347\264\242\346\240\221 II.py" "b/script/[95]\344\270\215\345\220\214\347\232\204\344\272\214\345\217\211\346\220\234\347\264\242\346\240\221 II.py" index c4cb5ef..e3ade58 100644 --- "a/script/[95]\344\270\215\345\220\214\347\232\204\344\272\214\345\217\211\346\220\234\347\264\242\346\240\221 II.py" +++ "b/script/[95]\344\270\215\345\220\214\347\232\204\344\272\214\345\217\211\346\220\234\347\264\242\346\240\221 II.py" @@ -27,7 +27,8 @@ # # # -# Related Topics 树 二叉搜索树 动态规划 回溯 二叉树 👍 1259 👎 0 +# Related Topics 树 二叉搜索树 动态规划 回溯 二叉树 +# 👍 1262 👎 0 # leetcode submit region begin(Prohibit modification and deletion) @@ -39,5 +40,29 @@ # self.right = right class Solution: def generateTrees(self, n: int) -> List[TreeNode]: - def helper() + if n<0: + return [] + hash = dict() + + def inorder(start,end): + nonlocal hash + if (start,end) in hash: + return hash[(start,end)] + if start>end: + return [None] + sub = [] + for i in range(start, end+1): + for left in inorder(start, i-1): + for right in inorder(i+1, end): + root = TreeNode(i) + root.left = left + root.right = right + sub.append(root) + hash[(start,end)] = sub + return sub + return inorder(1, n) + + + + # leetcode submit region end(Prohibit modification and deletion) diff --git "a/script/[96]\344\270\215\345\220\214\347\232\204\344\272\214\345\217\211\346\220\234\347\264\242\346\240\221.py" "b/script/[96]\344\270\215\345\220\214\347\232\204\344\272\214\345\217\211\346\220\234\347\264\242\346\240\221.py" new file mode 100644 index 0000000..d6b9db6 --- /dev/null +++ "b/script/[96]\344\270\215\345\220\214\347\232\204\344\272\214\345\217\211\346\220\234\347\264\242\346\240\221.py" @@ -0,0 +1,41 @@ +# 给你一个整数 n ,求恰由 n 个节点组成且节点值从 1 到 n 互不相同的 二叉搜索树 有多少种?返回满足题意的二叉搜索树的种数。 +# +# +# +# 示例 1: +# +# +# 输入:n = 3 +# 输出:5 +# +# +# 示例 2: +# +# +# 输入:n = 1 +# 输出:1 +# +# +# +# +# 提示: +# +# +# 1 <= n <= 19 +# +# Related Topics 树 二叉搜索树 数学 动态规划 二叉树 +# 👍 1855 👎 0 + +# leetcode submit region begin(Prohibit modification and deletion) +class Solution: + def numTrees(self, n: int) -> int: + #长度为n的二叉搜索树个数 + dp = [1] *2+ [0] * (n-1) + # i是节点数 + for i in range(2,n+1): + for j in range(i): + # J是root节点的位置 + dp[i] += dp[j] * dp[i-j-1] + return dp[-1] + +# leetcode submit region end(Prohibit modification and deletion) diff --git "a/script/[97]\344\272\244\351\224\231\345\255\227\347\254\246\344\270\262.py" "b/script/[97]\344\272\244\351\224\231\345\255\227\347\254\246\344\270\262.py" new file mode 100644 index 0000000..c248288 --- /dev/null +++ "b/script/[97]\344\272\244\351\224\231\345\255\227\347\254\246\344\270\262.py" @@ -0,0 +1,74 @@ +# 给定三个字符串 s1、s2、s3,请你帮忙验证 s3 是否是由 s1 和 s2 交错 组成的。 +# +# 两个字符串 s 和 t 交错 的定义与过程如下,其中每个字符串都会被分割成若干 非空 子字符串: +# +# +# s = s1 + s2 + ... + sn +# t = t1 + t2 + ... + tm +# |n - m| <= 1 +# 交错 是 s1 + t1 + s2 + t2 + s3 + t3 + ... 或者 t1 + s1 + t2 + s2 + t3 + s3 + ... +# +# +# 注意:a + b 意味着字符串 a 和 b 连接。 +# +# +# +# 示例 1: +# +# +# 输入:s1 = "aabcc", s2 = "dbbca", s3 = "aadbbcbcac" +# 输出:true +# +# +# 示例 2: +# +# +# 输入:s1 = "aabcc", s2 = "dbbca", s3 = "aadbbbaccc" +# 输出:false +# +# +# 示例 3: +# +# +# 输入:s1 = "", s2 = "", s3 = "" +# 输出:true +# +# +# +# +# 提示: +# +# +# 0 <= s1.length, s2.length <= 100 +# 0 <= s3.length <= 200 +# s1、s2、和 s3 都由小写英文字母组成 +# +# +# +# +# 进阶:您能否仅使用 O(s2.length) 额外的内存空间来解决它? +# Related Topics 字符串 动态规划 +# 👍 737 👎 0 + + +# leetcode submit region begin(Prohibit modification and deletion) +class Solution: + def isInterleave(self, s1: str, s2: str, s3: str) -> bool: + l1 = len(s1) + l2 = len(s2) + l3 = len(s3) + if l1+l2!=l3: + return False + dp = [[False] * (l2+1) for i in range(1+l1)] + dp[0][0]=True + for i in range(1, l1+1): + dp[i][0] = dp[i-1][0] and s1[i-1]==s3[i-1] + for i in range(1, l2+1): + dp[0][i] = dp[0][i-1] and s2[i-1]==s3[i-1] + print(dp) + for i in range(1, l1+1): + for j in range(1,l2+1): + pos = i+j-1 + dp[i][j] = (dp[i-1][j] and s1[i-1]==s3[pos]) or (dp[i][j-1] and s2[j-1]==s3[pos]) + return dp[-1][-1] +# leetcode submit region end(Prohibit modification and deletion) diff --git "a/\345\212\250\346\200\201\350\247\204\345\210\222/0.\345\212\250\346\200\201\350\247\204\345\210\222\346\200\273\347\273\223.md" "b/\345\212\250\346\200\201\350\247\204\345\210\222/0.\345\212\250\346\200\201\350\247\204\345\210\222\346\200\273\347\273\223.md" index bdad806..873c42d 100644 --- "a/\345\212\250\346\200\201\350\247\204\345\210\222/0.\345\212\250\346\200\201\350\247\204\345\210\222\346\200\273\347\273\223.md" +++ "b/\345\212\250\346\200\201\350\247\204\345\210\222/0.\345\212\250\346\200\201\350\247\204\345\210\222\346\200\273\347\273\223.md" @@ -12,7 +12,7 @@ - [ ] 213 打家劫舍 II: 首尾相连,去除首/尾做两次计算 - [ ] 337 打家劫舍 III:dfs返回打劫/不打劫当前节点的两个rob数值 -- 0/1背包:不能重复使用元素倒序背包 +- 0/1背包:不能重复使用物品-->倒序背包 - [ ] 416 分割等和子集:求和,全0初始化,内外皆可,$dp[j] = max(dp[j], dp[j-n]+n)$ @@ -22,14 +22,14 @@ - [ ] 1049 最后一块石头的重量 II:求和,全0初始化,内外皆可,$dp[i] = max(dp[i], dp[i-s]+s)$ - - [ ] 1115 掷骰子的N种方法:组合数=traget, $dp[0][0]=1$,背包内物品外,$dp[i][j] = dp[i][j-k] + 1$ + - [ ] 1155 掷骰子的N种方法:组合数=traget, $dp[0][0]=1$,背包内物品外,$dp[i][j] = dp[i][j-k] + 1$ -- 完全背包:可以重复使用元素正序背包 +- 完全背包:可以重复使用物品——>正序背包 - [ ] 139 单词拆分:是否存在排列,dp[0]=True,背包外物品内,value=True, cost=单词匹配 dp[i]=dp[i] or (dp[i-cost] & is_s) - - [ ] 279 完全平方数:最小组合数,dp[0]=0(剩余位置最大化),物品外背包内, $dp[i] = min(dp[i], dp[i-num**2]+1)$ - - [ ] 322 零钱兑换:最小组合数,dp[0]=0(剩余位置最大化),物品外背包内,$dp[i] = min(dp[i-coin]+1, dp[i])$ + - [ ] 279 完全平方数:最小物品数,dp[0]=0(剩余位置最大化),物品外背包内, $dp[i] = min(dp[i], dp[i-num**2]+1)$ + - [ ] 322 零钱兑换:最小物品数,dp[0]=0(剩余位置最大化),物品外背包内,$dp[i] = min(dp[i-coin]+1, dp[i])$ - [ ] 377 组合总和 Ⅳ:组合数=target,dp[0]=1,物品外背包内,$ dp[i] +=dp[i-n]$ - [ ] 518 零钱兑换 II:组合数=target,dp[0]=1,物品外背包内,$dp[i] +=dp[i-c]$ @@ -43,8 +43,9 @@ - 编辑距离 - - [ ] 72 编辑距离: 和583相比增加替换操作,相同$dp[i][j]=dp[i-1][j-1]$, 不同$dp[i][j] = min(dp[i][j-1],dp[i-1][j],dp[i-1][j-1])+1$ - - [ ] 583 两个字符串的删除操作:和392相比是双向删除,注意初始化是序列长度,相同$dp[i][j]=dp[i-1][j-1]$, 不同$dp[i][j] = min(dp[i][j-1],dp[i-1][j])+1$ + - [ ] 72 编辑距离: 和583相比增加替换操作,所以不同时dp[i-1][j-1]变成+1因为可以通过替换 + - [ ] 583 两个字符串的删除操作:和392相比是双向删除,注意初始化是序列长度,相同$dp[i][j]=dp[i-1][j-1]$, + 不同$dp[i][j] = min(dp[i][j-1]+1,dp[i-1][j]+1,dp[i-1][j-1]+2)$ - 子序列 diff --git "a/\345\212\250\346\200\201\350\247\204\345\210\222/115. \344\270\215\345\220\214\347\232\204\345\255\220\345\272\217\345\210\227.md" "b/\345\212\250\346\200\201\350\247\204\345\210\222/115. \344\270\215\345\220\214\347\232\204\345\255\220\345\272\217\345\210\227.md" index 70a7627..31666d2 100644 --- "a/\345\212\250\346\200\201\350\247\204\345\210\222/115. \344\270\215\345\220\214\347\232\204\345\255\220\345\272\217\345\210\227.md" +++ "b/\345\212\250\346\200\201\350\247\204\345\210\222/115. \344\270\215\345\220\214\347\232\204\345\255\220\345\272\217\345\210\227.md" @@ -66,6 +66,7 @@ Tips - $dp[i][j]$含义是$s[i-1]$中出现$t[j-1]$的次数 - 初始化dp[i][0]=1 +- dp[i][j]是前i个s里面有几个前j个t字符= 前i-1个s有多少个j-1个t+ 前i-个s有多少个j个t - 状态转移: - s[j-1]=t[j-1]:$dp[i][j] = dp[i-1][j-1]+dp[i-1][j]$ 这里是继承j-2和i-2的状态,以及j-1和i-2的状态(继承之前就匹配当前字符的状态 - s[j-1]!=t[j-1]: $dp[i][j]= dp[i-1][j-1]$ \ No newline at end of file diff --git "a/\345\212\250\346\200\201\350\247\204\345\210\222/368.\346\234\200\345\244\247\346\225\264\351\231\244\345\255\220\351\233\206.md" "b/\345\212\250\346\200\201\350\247\204\345\210\222/368.\346\234\200\345\244\247\346\225\264\351\231\244\345\255\220\351\233\206.md" new file mode 100644 index 0000000..16b76be --- /dev/null +++ "b/\345\212\250\346\200\201\350\247\204\345\210\222/368.\346\234\200\345\244\247\346\225\264\351\231\244\345\255\220\351\233\206.md" @@ -0,0 +1,69 @@ +给你一个由 无重复 正整数组成的集合 nums ,请你找出并返回其中最大的整除子集 answer ,子集中每一元素对 (answer[i], answer[ +j]) 都应当满足: + + answer[i] % answer[j] == 0 ,或 + answer[j] % answer[i] == 0 + + + 如果存在多个有效解子集,返回其中任何一个均可。 +如果存在多个有效解子集 + + + 示例 1: + + +输入:nums = [1,2,3] +输出:[1,2] +解释:[1,3] 也会被视为正确答案。 + + + 示例 2: + + +输入:nums = [1,2,4,8] +输出:[1,2,4,8] + + + + + 提示: + + + 1 <= nums.length <= 1000 + 1 <= nums[i] <= 2 * 109 + nums 中的所有整数 互不相同 + + Related Topics 数组 数学 动态规划 排序 + 👍 459 👎 0 + + +```python +class Solution: + def largestDivisibleSubset(self, nums: List[int]) -> List[int]: + l = len(nums) + dp = [1] * l + nums = sorted(nums) + maxl = 1 + maxval = nums[0] + + for i in range(l): + for j in range(i): + if nums[i]%nums[j]==0: + dp[i] = max(dp[i], dp[j]+1) + if dp[i]>maxl: + maxl = dp[i] + maxval = nums[i] + #反向遍历得到子集 + result = [] + for i in range(l-1,-1,-1): + if dp[i]==maxl and maxval%nums[i]==0: + result.append(nums[i]) + maxl-=1 + maxval = nums[i] + + return result +``` + +tips +1. 按照300,最长递增子序列的思路得到最长整除子集的长度 +2. 从后向前遍历,依次得到子集的元素 diff --git "a/\345\212\250\346\200\201\350\247\204\345\210\222/377. \347\273\204\345\220\210\346\200\273\345\222\214 \342\205\243.md" "b/\345\212\250\346\200\201\350\247\204\345\210\222/377. \347\273\204\345\220\210\346\200\273\345\222\214 \342\205\243.md" index a123dc6..8d3c1a8 100644 --- "a/\345\212\250\346\200\201\350\247\204\345\210\222/377. \347\273\204\345\220\210\346\200\273\345\222\214 \342\205\243.md" +++ "b/\345\212\250\346\200\201\350\247\204\345\210\222/377. \347\273\204\345\220\210\346\200\273\345\222\214 \342\205\243.md" @@ -1,4 +1,4 @@ -给你一个由 不同 整数组成的数组 nums ,和一个目标整数 target 。请你从 nums 中找出并返回总和为 target 的元素组合的个数。 +\给你一个由 不同 整数组成的数组 nums ,和一个目标整数 target 。请你从 nums 中找出并返回总和为 target 的元素组合的个数。 题目数据保证答案符合 32 位整数范围。 @@ -67,5 +67,5 @@ $$ -2. 如果存在负数 +2. 如果存在负数:可能会出现无线长度的排列, 需要限制最大的排列顺序 diff --git "a/\345\212\250\346\200\201\350\247\204\345\210\222/96. \344\270\215\345\220\214\347\232\204\344\272\214\345\217\211\346\220\234\347\264\242\346\240\221.md" "b/\345\212\250\346\200\201\350\247\204\345\210\222/96. \344\270\215\345\220\214\347\232\204\344\272\214\345\217\211\346\220\234\347\264\242\346\240\221.md" index 475f4ab..3840626 100644 --- "a/\345\212\250\346\200\201\350\247\204\345\210\222/96. \344\270\215\345\220\214\347\232\204\344\272\214\345\217\211\346\220\234\347\264\242\346\240\221.md" +++ "b/\345\212\250\346\200\201\350\247\204\345\210\222/96. \344\270\215\345\220\214\347\232\204\344\272\214\345\217\211\346\220\234\347\264\242\346\240\221.md" @@ -24,6 +24,7 @@ class Solution: def numTrees(self, n: int) -> int: dp = [1] + [0] * n + for i in range(1,n+1): for j in range(i): dp[i] += dp[j] * dp[i-j-1] @@ -34,14 +35,9 @@ class Solution: Tips - - -1. 这道题只用返回种数,所以适合用动态规划进行求解。搜索树的root可以为n中的任意一个,如果是k,则左子树为长度为k-1,右子树长度为n-k, 总共有h(n-k)*h(k-1)种构建方式。dp[0]=1 - +i $$ -dp(n) += dp(j-1) * dp(n-j) +dp(n) += dp(j) * dp(n-j-1) $$ -2. 动态规划解法一次计算h(2),h(3) - 3. 许多动态规划题都涉及到从1开始计数,这个时候简单的解决方案就dp数组长度为n+1,不去调整index状态 diff --git "a/\345\212\250\346\200\201\350\247\204\345\210\222\346\200\273\347\273\223.md" "b/\345\212\250\346\200\201\350\247\204\345\210\222\346\200\273\347\273\223.md" index eb64b98..f8f91fb 100644 --- "a/\345\212\250\346\200\201\350\247\204\345\210\222\346\200\273\347\273\223.md" +++ "b/\345\212\250\346\200\201\350\247\204\345\210\222\346\200\273\347\273\223.md" @@ -1109,6 +1109,81 @@ dp[i] = max(dp[i-j]*j, (i-j)*j) $$ 4. 初始化,这里选择直接初始化dp[2]=1, 前面的0和1是哦否初始化都没有安息,因为在计算中可以让j从1开始也就可以避开dp[0]和dp[1] + + +### 368. 最大整除子集.md + +给你一个由 无重复 正整数组成的集合 nums ,请你找出并返回其中最大的整除子集 answer ,子集中每一元素对 (answer[i], answer[ +j]) 都应当满足: + + answer[i] % answer[j] == 0 ,或 + answer[j] % answer[i] == 0 + + + 如果存在多个有效解子集,返回其中任何一个均可。 +如果存在多个有效解子集 + + + 示例 1: + + +输入:nums = [1,2,3] +输出:[1,2] +解释:[1,3] 也会被视为正确答案。 + + + 示例 2: + + +输入:nums = [1,2,4,8] +输出:[1,2,4,8] + + + + + 提示: + + + 1 <= nums.length <= 1000 + 1 <= nums[i] <= 2 * 109 + nums 中的所有整数 互不相同 + + Related Topics 数组 数学 动态规划 排序 + 👍 459 👎 0 + + +```python +class Solution: + def largestDivisibleSubset(self, nums: List[int]) -> List[int]: + l = len(nums) + dp = [1] * l + nums = sorted(nums) + maxl = 1 + maxval = nums[0] + + for i in range(l): + for j in range(i): + if nums[i]%nums[j]==0: + dp[i] = max(dp[i], dp[j]+1) + if dp[i]>maxl: + maxl = dp[i] + maxval = nums[i] + #反向遍历得到子集 + result = [] + for i in range(l-1,-1,-1): + if dp[i]==maxl and maxval%nums[i]==0: + result.append(nums[i]) + maxl-=1 + maxval = nums[i] + + return result +``` + +tips +1. 按照300,最长递增子序列的思路得到最长整除子集的长度 +2. 从后向前遍历,依次得到子集的元素 + + ### 377. 组合总和 Ⅳ.md 给你一个由 不同 整数组成的数组 nums ,和一个目标整数 target 。请你从 nums 中找出并返回总和为 target 的元素组合的个数。 diff --git "a/\346\225\260\347\273\204/0.\346\200\273\347\273\223.md" "b/\346\225\260\347\273\204/0.\346\200\273\347\273\223.md" index 639cae4..014f689 100644 --- "a/\346\225\260\347\273\204/0.\346\200\273\347\273\223.md" +++ "b/\346\225\260\347\273\204/0.\346\200\273\347\273\223.md" @@ -17,13 +17,13 @@ - [ ] 747 至少是其他数字两倍的最大数 - [ ] 766 托普利茨矩阵 - [ ] 830 较大分组的位置 - - [ ] 832 翻转图像: [i,j] -> [j, n-i-1] - 矩阵操作 - [ ] 48 旋转图像 - [ ] 189 轮转数组 - [ ] 401 二进制手表 - [ ] 506 相对名次 - [ ] 566 重塑矩阵 + - [ ] 832 翻转图像: [i,j] -> [j, n-i-1] - 技巧题 - [ ] 6 Z 字形变换 - [ ] 54 螺旋矩阵: 注意最后剩余部分的边界问题 diff --git "a/\346\225\260\347\273\204/48. \346\227\213\350\275\254\345\233\276\345\203\217.md" "b/\346\225\260\347\273\204/48. \346\227\213\350\275\254\345\233\276\345\203\217.md" index 09bb818..e80b287 100644 --- "a/\346\225\260\347\273\204/48. \346\227\213\350\275\254\345\233\276\345\203\217.md" +++ "b/\346\225\260\347\273\204/48. \346\227\213\350\275\254\345\233\276\345\203\217.md" @@ -83,12 +83,15 @@ class Solution: """ Do not return anything, modify matrix in-place instead. """ - n=len(matrix) - for i in range(n//2): - for j in range(n): - matrix[i][j] ,matrix[n-1-i][j]= matrix[n-1-i][j], matrix[i][j] - for i in range(n): + nrow = len(matrix) + for i in range(nrow//2): + matrix[i][:],matrix[nrow-1-i][:] = matrix[nrow-1-i][:], matrix[i][:] + for i in range(nrow): for j in range(i): matrix[i][j], matrix[j][i] = matrix[j][i], matrix[i][j] -``` + return matrix + + + + diff --git "a/\346\225\260\347\273\204/495. \346\217\220\350\216\253\346\224\273\345\207\273.md" "b/\346\225\260\347\273\204/495. \346\217\220\350\216\253\346\224\273\345\207\273.md" index cd4a646..23a8242 100644 --- "a/\346\225\260\347\273\204/495. \346\217\220\350\216\253\346\224\273\345\207\273.md" +++ "b/\346\225\260\347\273\204/495. \346\217\220\350\216\253\346\224\273\345\207\273.md" @@ -33,15 +33,12 @@ ```python class Solution: def findPoisonedDuration(self, timeSeries: List[int], duration: int) -> int: - harm = duration - pos = timeSeries[0]+duration - for i in timeSeries[1:]: - if pos>i: - harm += i+duration-pos - else: - harm+=duration - pos = i+duration - return harm + total = 0 + pre = 0 + for i in range(len(timeSeries)): + total += max(duration - max(pre-timeSeries[i],0),0) + pre = timeSeries[i]+duration + return total ``` Tips diff --git "a/\346\225\260\347\273\204/54. \350\236\272\346\227\213\347\237\251\351\230\265.md" "b/\346\225\260\347\273\204/54. \350\236\272\346\227\213\347\237\251\351\230\265.md" index d8dcce4..a420c4a 100644 --- "a/\346\225\260\347\273\204/54. \350\236\272\346\227\213\347\237\251\351\230\265.md" +++ "b/\346\225\260\347\273\204/54. \350\236\272\346\227\213\347\237\251\351\230\265.md" @@ -58,7 +58,7 @@ class Solution: result.append(matrix[i][left]) return result -``` +````` diff --git "a/\346\225\260\347\273\204\346\200\273\347\273\223.md" "b/\346\225\260\347\273\204\346\200\273\347\273\223.md" index 448ae93..db30122 100644 --- "a/\346\225\260\347\273\204\346\200\273\347\273\223.md" +++ "b/\346\225\260\347\273\204\346\200\273\347\273\223.md" @@ -787,13 +787,13 @@ class Solution: """ Do not return anything, modify matrix in-place instead. """ - n=len(matrix) - for i in range(n//2): - for j in range(n): - matrix[i][j] ,matrix[n-1-i][j]= matrix[n-1-i][j], matrix[i][j] - for i in range(n): + nrow = len(matrix) + for i in range(nrow//2): + matrix[i][:],matrix[nrow-1-i][:] = matrix[nrow-1-i][:], matrix[i][:] + for i in range(nrow): for j in range(i): matrix[i][j], matrix[j][i] = matrix[j][i], matrix[i][j] + return matrix ``` @@ -928,15 +928,12 @@ Tips ```python class Solution: def findPoisonedDuration(self, timeSeries: List[int], duration: int) -> int: - harm = duration - pos = timeSeries[0]+duration - for i in timeSeries[1:]: - if pos>i: - harm += i+duration-pos - else: - harm+=duration - pos = i+duration - return harm + total = 0 + pre = 0 + for i in range(len(timeSeries)): + total += max(duration - max(pre-timeSeries[i],0),0) + pre = timeSeries[i]+duration + return total ``` Tips diff --git "a/\346\240\210/316. \345\216\273\351\231\244\351\207\215\345\244\215\345\255\227\346\257\215.md" "b/\346\240\210/316. \345\216\273\351\231\244\351\207\215\345\244\215\345\255\227\346\257\215.md" index 43acf9b..fa17a7f 100644 --- "a/\346\240\210/316. \345\216\273\351\231\244\351\207\215\345\244\215\345\255\227\346\257\215.md" +++ "b/\346\240\210/316. \345\216\273\351\231\244\351\207\215\345\244\215\345\255\227\346\257\215.md" @@ -41,4 +41,5 @@ class Solution: Tips -和402一脉相承,单调栈+贪心。原理来源于高位的字符越小整体的字典序越小,所以对于存在重复的字符,只要该字符在栈尾,且新的元素比它更小,就自动pop \ No newline at end of file +1. 和402一脉相承,单调栈+贪心。原理来源于高位的字符越小整体的字典序越小,所以对于存在重复的字符,只要该字符在栈尾,且新的元素比它更小,就自动pop +2. 这里有个两个计数存储,seen用来判断是否入栈,已经在栈内的元素不入栈,hash的计数用来判断是否出栈,如果没有剩余元素则不能出栈 \ No newline at end of file diff --git "a/\346\240\210/32. \346\234\200\351\225\277\346\234\211\346\225\210\346\213\254\345\217\267.md" "b/\346\240\210/32. \346\234\200\351\225\277\346\234\211\346\225\210\346\213\254\345\217\267.md" index 011fa8d..8c376db 100644 --- "a/\346\240\210/32. \346\234\200\351\225\277\346\234\211\346\225\210\346\213\254\345\217\267.md" +++ "b/\346\240\210/32. \346\234\200\351\225\277\346\234\211\346\225\210\346\213\254\345\217\267.md" @@ -49,4 +49,6 @@ class Solution: Tips -有效括号的升级版。计算最长的连续有效括号,计算括号是否有效通过左括号入栈,右括号弹出的操作可以实现,但是最长连续这里又一点tricky。其实是通过右括号也入栈来对有效的括号进行隔断。如果只有右括号,则右括号自动隔断前面的所有有效括号,这里stack=[-1]的初始位置是精髓 \ No newline at end of file +有效括号的升级版。计算最长的连续有效括号,计算括号是否有效通过左括号入栈,右括号弹出的操作可以实现,但是最长连续这里又一点tricky。 +1. 左括号多:左括号本身不会被消掉,所以左index+1 +2. 右括号多:没有左括号与之匹配,所以右括号入栈形成隔断 \ No newline at end of file diff --git "a/\346\240\221/117. \345\241\253\345\205\205\346\257\217\344\270\252\350\212\202\347\202\271\347\232\204\344\270\213\344\270\200\344\270\252\345\217\263\344\276\247\350\212\202\347\202\271\346\214\207\351\222\210 II.md" "b/\346\240\221/117. \345\241\253\345\205\205\346\257\217\344\270\252\350\212\202\347\202\271\347\232\204\344\270\213\344\270\200\344\270\252\345\217\263\344\276\247\350\212\202\347\202\271\346\214\207\351\222\210 II.md" index bbf1da8..559c77d 100644 --- "a/\346\240\221/117. \345\241\253\345\205\205\346\257\217\344\270\252\350\212\202\347\202\271\347\232\204\344\270\213\344\270\200\344\270\252\345\217\263\344\276\247\350\212\202\347\202\271\346\214\207\351\222\210 II.md" +++ "b/\346\240\221/117. \345\241\253\345\205\205\346\257\217\344\270\252\350\212\202\347\202\271\347\232\204\344\270\213\344\270\200\344\270\252\345\217\263\344\276\247\350\212\202\347\202\271\346\214\207\351\222\210 II.md" @@ -72,4 +72,5 @@ class Solution: return root ``` -117 和116的差异在于常数空间占用,因为next指针本身提供了横向遍历的可能,所以用3个指针分别指向当前,上一个节点,以及下一行的初始节点 \ No newline at end of file +1. 117 和116的差异在于常数空间占用,因为next指针本身提供了横向遍历的可能,所以用3个指针分别指向当前,上一个节点,以及下一行的初始节点 +2. 双层循环,外层是下一行,内层是每行遍历。pre指针是next的前节点,head是下一层的头节点。每一步cur向右移动,pre也向右移动 diff --git "a/\350\264\252\345\277\203/0.\350\264\252\345\277\203\346\200\273\347\273\223.md" "b/\350\264\252\345\277\203/0.\350\264\252\345\277\203\346\200\273\347\273\223.md" index 4b61891..1a9d350 100644 --- "a/\350\264\252\345\277\203/0.\350\264\252\345\277\203\346\200\273\347\273\223.md" +++ "b/\350\264\252\345\277\203/0.\350\264\252\345\277\203\346\200\273\347\273\223.md" @@ -26,4 +26,5 @@ - [ ] 605 种花问题:如何计算每个区间能种的花的数量,以及左右边界的处理 - [ ] 674 最长连续递增序列 - [ ] 738: 单调递增的数字:找到递减的位置,当前位置-1,把后面的所有数字都变成9999就是最大的递增数据 - - [ ] 860 柠檬水找零:没啥说的遍历就完了 \ No newline at end of file + - [ ] 860 柠檬水找零:没啥说的遍历就完了 + - [ ] 1005. K 次取反后最大化的数组和 \ No newline at end of file diff --git "a/\350\264\252\345\277\203\346\200\273\347\273\223.md" "b/\350\264\252\345\277\203\346\200\273\347\273\223.md" index c180888..6c1992a 100644 --- "a/\350\264\252\345\277\203\346\200\273\347\273\223.md" +++ "b/\350\264\252\345\277\203\346\200\273\347\273\223.md" @@ -28,6 +28,7 @@ - [ ] 674 最长连续递增序列 - [ ] 738: 单调递增的数字:找到递减的位置,当前位置-1,把后面的所有数字都变成9999就是最大的递增数据 - [ ] 860 柠檬水找零:没啥说的遍历就完了 + - [ ] 1005. K 次取反后最大化的数组和 ### 1005. K 次取反后最大化的数组和.md 给定一个整数数组 A,我们只能用以下方法修改该数组:我们选择某个索引 i 并将 A[i] 替换为 -A[i],然后总共重复这个过程 K 次。(我们可以多次选择同一个索引 i。) diff --git "a/\351\223\276\350\241\250/0.\351\223\276\350\241\250\346\200\273\347\273\223.md" "b/\351\223\276\350\241\250/0.\351\223\276\350\241\250\346\200\273\347\273\223.md" index 894ab96..301acad 100644 --- "a/\351\223\276\350\241\250/0.\351\223\276\350\241\250\346\200\273\347\273\223.md" +++ "b/\351\223\276\350\241\250/0.\351\223\276\350\241\250\346\200\273\347\273\223.md" @@ -29,8 +29,7 @@ - 234 回文链表:中间节点+翻转链表+遍历 - 设计类 - 146 LRU:双向链表,插入head(先建立node左右link,再插入),超过长度移除tail.prev, 移除是把元素左右node链接 - - 460 LFU: - 707 设计链表 - 技巧题 - - 160 相交链表: - - 382 链表随机节点:蓄水池算法,第K个节点有1/K的概率overwrite之前sample的元素 + - 160 相交链表:不用技巧,常规解法是把两个链表拼接到相同长度,然后开始遍历寻找相同节点 + - 382 链表随机节点:蓄水池算法,第K个节点有1/K的概率被采样 diff --git "a/\351\223\276\350\241\250/143. \351\207\215\346\216\222\351\223\276\350\241\250v.md" "b/\351\223\276\350\241\250/143. \351\207\215\346\216\222\351\223\276\350\241\250v.md" index da2049e..d6931cd 100644 --- "a/\351\223\276\350\241\250/143. \351\207\215\346\216\222\351\223\276\350\241\250v.md" +++ "b/\351\223\276\350\241\250/143. \351\207\215\346\216\222\351\223\276\350\241\250v.md" @@ -52,49 +52,50 @@ class Solution: """ Do not return anything, modify head in-place instead. """ + if not head: - return - middle= self.find_middle(head) - l2 = middle.next - l1 = head - middle.next = None - l2 = self.reverse(l2) - result = self.merge_linklist(l1, l2) - - @staticmethod - def find_middle(head): - slow =head - fast = head - while fast.next and fast.next.next: - fast = fast.next.next - slow = slow.next - return slow - - @staticmethod - def reverse(head): - cur = head - newnode = None - while cur: - tmp = cur.next - cur.next = newnode - newnode = cur - cur = tmp - return newnode - - @staticmethod - def merge_linklist(head1, head2): - while head1 and head2: - tmp1 = head1.next - tmp2 = head2.next - - head1.next = head2 - - head1 = tmp1 - head2 = tmp2 + return None + + def reverse(head): + newnode = None + cur = head + while cur: + nextnode = cur.next + cur.next=newnode + newnode = cur + cur = nextnode + return newnode + + def getmid(head): + slow, fast = head, head + while fast.next and fast.next.next: + slow = slow.next + fast = fast.next.next + return slow + + def merge(l1, l2): + while l1 and l2: + l1_tmp = l1.next + l2_tmp = l2.next + + l1.next = l2 + l1 = l1_tmp + + l2.next = l1 + l2 = l2_tmp + ptr1 = head + left_mid = getmid(head) + mid = left_mid.next + left_mid.next=None # 注意这一步 + + ptr2 = reverse(mid) + merge(ptr1, ptr2) ``` Tips -1. 这道题融合了三道题,快慢指针找中点,反转链表,合并两个链表 \ No newline at end of file +1. 这道题融合了三道题,快慢指针找中点,反转链表,合并两个链表 +2. 比148多了融合这一步,融合是在原地进行的只改变link不改变value +3. 需要注意的是这里find_mid找的是中点的左边界,因为需要设置mid.next=None, 把前半部分隔出来 \ No newline at end of file diff --git "a/\351\223\276\350\241\250/2. \344\270\244\346\225\260\347\233\270\345\212\240.md" "b/\351\223\276\350\241\250/2. \344\270\244\346\225\260\347\233\270\345\212\240.md" index 38c67d1..00d7034 100644 --- "a/\351\223\276\350\241\250/2. \344\270\244\346\225\260\347\233\270\345\212\240.md" +++ "b/\351\223\276\350\241\250/2. \344\270\244\346\225\260\347\233\270\345\212\240.md" @@ -68,4 +68,6 @@ class Solution: Tips: 1. 注意链表的赋值一般都是对next,这样可以有效避免创建空节点。如果每次val都是赋值给当前节点,则需要额外判断l1和l2是否为空决定是否创建链表的next节点 +2. 注意审题,是顺序向后加,remainder也是加在后面 + diff --git "a/\351\223\276\350\241\250/382. \351\223\276\350\241\250\351\232\217\346\234\272\350\212\202\347\202\271.md" "b/\351\223\276\350\241\250/382. \351\223\276\350\241\250\351\232\217\346\234\272\350\212\202\347\202\271.md" index e6d85bc..6f43f5d 100644 --- "a/\351\223\276\350\241\250/382. \351\223\276\350\241\250\351\232\217\346\234\272\350\212\202\347\202\271.md" +++ "b/\351\223\276\350\241\250/382. \351\223\276\350\241\250\351\232\217\346\234\272\350\212\202\347\202\271.md" @@ -41,9 +41,7 @@ Tips 蓄水池抽样 -N个候选,第K个候选被采用的概率是1/K, - - K=1, p=1 - K=2, p=1/2,覆盖K=1的概率是1/2 -- K=3, p=1/3, 覆盖之前的概率是2/3,所以K=2的元素被选择的概率变成1/2 * 2/3 = 1/3 +- K=3, p=1/3, 第3个节点本身被采样的概率论是1/3,保留之前随机数的概率是2/3,所以K=2的元素被选择的概率变成1/2 * 2/3 = 1/3 - \ No newline at end of file diff --git "a/\351\223\276\350\241\250/460. LFU \347\274\223\345\255\230.md" "b/\351\223\276\350\241\250/460. LFU \347\274\223\345\255\230.md" deleted file mode 100644 index 8c858d0..0000000 --- "a/\351\223\276\350\241\250/460. LFU \347\274\223\345\255\230.md" +++ /dev/null @@ -1,60 +0,0 @@ -请你为 最不经常使用(LFU)缓存算法设计并实现数据结构。 - -实现 LFUCache 类: - - LFUCache(int capacity) - 用数据结构的容量 capacity 初始化对象 - int get(int key) - 如果键存在于缓存中,则获取键的值,否则返回 -1。 - void put(int key, int value) - 如果键已存在,则变更其值;如果键不存在,请插入键值对。当缓存达到其容量时,则应该在插入新项之前,使最不经常使用的项无效。在此问题中,当存在平局(即两个或更多个键具有相同使用频率)时,应该去除 最近最久未使用 的键。 - -注意「项的使用次数」就是自插入该项以来对其调用 get 和 put 函数的次数之和。使用次数会在对应项被移除后置为 0 。 - -为了确定最不常使用的键,可以为缓存中的每个键维护一个 使用计数器 。使用计数最小的键是最久未使用的键。 - -当一个键首次插入到缓存中时,它的使用计数器被设置为 1 (由于 put 操作)。对缓存中的键执行 get 或 put 操作,使用计数器的值将会递增。 - - - -示例: - -输入: -["LFUCache", "put", "put", "get", "put", "get", "get", "put", "get", "get", "get"] -[[2], [1, 1], [2, 2], [1], [3, 3], [2], [3], [4, 4], [1], [3], [4]] -输出: -[null, null, null, 1, null, -1, 3, null, -1, 3, 4] - -解释: -// cnt(x) = 键 x 的使用计数 -// cache=[] 将显示最后一次使用的顺序(最左边的元素是最近的) -LFUCache lFUCache = new LFUCache(2); -lFUCache.put(1, 1); // cache=[1,_], cnt(1)=1 -lFUCache.put(2, 2); // cache=[2,1], cnt(2)=1, cnt(1)=1 -lFUCache.get(1); // 返回 1 - // cache=[1,2], cnt(2)=1, cnt(1)=2 -lFUCache.put(3, 3); // 去除键 2 ,因为 cnt(2)=1 ,使用计数最小 - // cache=[3,1], cnt(3)=1, cnt(1)=2 -lFUCache.get(2); // 返回 -1(未找到) -lFUCache.get(3); // 返回 3 - // cache=[3,1], cnt(3)=2, cnt(1)=2 -lFUCache.put(4, 4); // 去除键 1 ,1 和 3 的 cnt 相同,但 1 最久未使用 - // cache=[4,3], cnt(4)=1, cnt(3)=2 -lFUCache.get(1); // 返回 -1(未找到) -lFUCache.get(3); // 返回 3 - // cache=[3,4], cnt(4)=1, cnt(3)=3 -lFUCache.get(4); // 返回 4 - // cache=[3,4], cnt(4)=2, cnt(3)=3 - - - -提示: - - 0 <= capacity, key, value <= 104 - 最多调用 105 次 get 和 put 方法 - - - - -进阶:你可以为这两种操作设计时间复杂度为 O(1) 的实现吗? - -``` -``` - diff --git "a/\351\223\276\350\241\250\346\200\273\347\273\223.md" "b/\351\223\276\350\241\250\346\200\273\347\273\223.md" index 045964e..d80beab 100644 --- "a/\351\223\276\350\241\250\346\200\273\347\273\223.md" +++ "b/\351\223\276\350\241\250\346\200\273\347\273\223.md" @@ -30,11 +30,11 @@ - 234 回文链表:中间节点+翻转链表+遍历 - 设计类 - 146 LRU:双向链表,插入head(先建立node左右link,再插入),超过长度移除tail.prev, 移除是把元素左右node链接 - - 460 LFU: - 707 设计链表 - 技巧题 - - 160 相交链表:可以用常规接发, 找到长度,拼接成相同长度,然后遍历判断是否有相交节点 - - 382 链表随机节点:蓄水池算法,第K个节点有1/K的概率overwrite之前sample的元素 + - 160 相交链表:不用技巧,常规解法是把两个链表拼接到相同长度,然后开始遍历寻找相同节点 + - 382 链表随机节点:蓄水池算法,第K个节点有1/K的概率被采样 + ### 138. 复制带随机指针的链表.md @@ -291,6 +291,7 @@ $$ 也就是当slow和fast在C点相遇后,只要有一个ptr从head开始,和slow一起向前跑,当slow再次走到C,并绕着环跑了n-1圈后,两者会在B相遇 ### 143. 重排链表v.md + 给定一个单链表 L 的头节点 head ,单链表 L 表示为: L0 → L1 → … → Ln - 1 → Ln @@ -320,70 +321,50 @@ L0 → Ln → L1 → Ln - 1 → L2 → Ln - 2 → … 链表的长度范围为 [1, 5 * 104] 1 <= node.val <= 1000 - - - - - ```python -# Definition for singly-linked list. -class ListNode: - def __init__(self, val=0, next=None): - self.val = val - self.next = next - - def __str__(self): - res = [] - cur = self - while cur: - res.append(str(cur.val)) - cur = cur.next - return '->'.join(res) - class Solution: def reorderList(self, head: ListNode) -> None: """ Do not return anything, modify head in-place instead. """ + if not head: - return - middle= self.find_middle(head) - l2 = middle.next - l1 = head - middle.next = None - l2 = self.reverse(l2) - result = self.merge_linklist(l1, l2) - - @staticmethod - def find_middle(head): - slow =head - fast = head - while fast.next and fast.next.next: - fast = fast.next.next - slow = slow.next - return slow + return None - @staticmethod - def reverse(head): - cur = head - newnode = None - while cur: - tmp = cur.next - cur.next = newnode - newnode = cur - cur = tmp - return newnode + def reverse(head): + newnode = None + cur = head + while cur: + nextnode = cur.next + cur.next=newnode + newnode = cur + cur = nextnode + return newnode + + def getmid(head): + slow, fast = head, head + while fast.next and fast.next.next: + slow = slow.next + fast = fast.next.next + return slow + + def merge(l1, l2): + while l1 and l2: + l1_tmp = l1.next + l2_tmp = l2.next - @staticmethod - def merge_linklist(head1, head2): - while head1 and head2: - tmp1 = head1.next - tmp2 = head2.next - - head1.next = head2 + l1.next = l2 + l1 = l1_tmp + + l2.next = l1 + l2 = l2_tmp + ptr1 = head + left_mid = getmid(head) + mid = left_mid.next + left_mid.next=None # 注意这一步 - head1 = tmp1 - head2 = tmp2 + ptr2 = reverse(mid) + merge(ptr1, ptr2) ``` @@ -391,6 +372,9 @@ class Solution: Tips 1. 这道题融合了三道题,快慢指针找中点,反转链表,合并两个链表 +2. 比148多了融合这一步,融合是在原地进行的只改变link不改变value +3. 需要注意的是这里find_mid找的是中点的左边界,因为需要设置mid.next=None, 把前半部分隔出来 + ### 146. LRU 缓存机制.md 运用你所掌握的数据结构,设计和实现一个 LRU (最近最少使用) 缓存机制 。 @@ -564,6 +548,7 @@ Tips - 插入搜索:如果比当前位置大直接插入,如果小就会到链表的起点进行重新搜索 - 注意比较时只能比较next节点,如果比较当前节点无法插入 + ### 148. 排序链表.md 给你链表的头结点 head ,请将其按 升序 排列并返回 排序后的链表 。 @@ -1500,73 +1485,10 @@ Tips 蓄水池抽样 -N个候选,第K个候选被采用的概率是1/K, - - K=1, p=1 - K=2, p=1/2,覆盖K=1的概率是1/2 -- K=3, p=1/3, 覆盖之前的概率是2/3,所以K=2的元素被选择的概率变成1/2 * 2/3 = 1/3 +- K=3, p=1/3, 第3个节点本身被采样的概率论是1/3,保留之前随机数的概率是2/3,所以K=2的元素被选择的概率变成1/2 * 2/3 = 1/3 - -### 460. LFU 缓存.md -请你为 最不经常使用(LFU)缓存算法设计并实现数据结构。 - -实现 LFUCache 类: - - LFUCache(int capacity) - 用数据结构的容量 capacity 初始化对象 - int get(int key) - 如果键存在于缓存中,则获取键的值,否则返回 -1。 - void put(int key, int value) - 如果键已存在,则变更其值;如果键不存在,请插入键值对。当缓存达到其容量时,则应该在插入新项之前,使最不经常使用的项无效。在此问题中,当存在平局(即两个或更多个键具有相同使用频率)时,应该去除 最近最久未使用 的键。 - -注意「项的使用次数」就是自插入该项以来对其调用 get 和 put 函数的次数之和。使用次数会在对应项被移除后置为 0 。 - -为了确定最不常使用的键,可以为缓存中的每个键维护一个 使用计数器 。使用计数最小的键是最久未使用的键。 - -当一个键首次插入到缓存中时,它的使用计数器被设置为 1 (由于 put 操作)。对缓存中的键执行 get 或 put 操作,使用计数器的值将会递增。 - - - -示例: - -输入: -["LFUCache", "put", "put", "get", "put", "get", "get", "put", "get", "get", "get"] -[[2], [1, 1], [2, 2], [1], [3, 3], [2], [3], [4, 4], [1], [3], [4]] -输出: -[null, null, null, 1, null, -1, 3, null, -1, 3, 4] - -解释: -// cnt(x) = 键 x 的使用计数 -// cache=[] 将显示最后一次使用的顺序(最左边的元素是最近的) -LFUCache lFUCache = new LFUCache(2); -lFUCache.put(1, 1); // cache=[1,_], cnt(1)=1 -lFUCache.put(2, 2); // cache=[2,1], cnt(2)=1, cnt(1)=1 -lFUCache.get(1); // 返回 1 - // cache=[1,2], cnt(2)=1, cnt(1)=2 -lFUCache.put(3, 3); // 去除键 2 ,因为 cnt(2)=1 ,使用计数最小 - // cache=[3,1], cnt(3)=1, cnt(1)=2 -lFUCache.get(2); // 返回 -1(未找到) -lFUCache.get(3); // 返回 3 - // cache=[3,1], cnt(3)=2, cnt(1)=2 -lFUCache.put(4, 4); // 去除键 1 ,1 和 3 的 cnt 相同,但 1 最久未使用 - // cache=[4,3], cnt(4)=1, cnt(3)=2 -lFUCache.get(1); // 返回 -1(未找到) -lFUCache.get(3); // 返回 3 - // cache=[3,4], cnt(4)=1, cnt(3)=3 -lFUCache.get(4); // 返回 4 - // cache=[3,4], cnt(4)=2, cnt(3)=3 - - - -提示: - - 0 <= capacity, key, value <= 104 - 最多调用 105 次 get 和 put 方法 - - - - -进阶:你可以为这两种操作设计时间复杂度为 O(1) 的实现吗? - -``` -``` - ### 61. 旋转链表.md ####