diff --git a/solutions/python3/1.py b/solutions/python3/1.py index 9228e78..591c168 100644 --- a/solutions/python3/1.py +++ b/solutions/python3/1.py @@ -1,7 +1,15 @@ + class Solution: + # 用于解决两数之和的问题 + def twoSum(self, nums, target): + # 使用哈希表来存储已经遍历过的数字及其索引,以提高查找效率 nums_hash = {} + for i in range(len(nums)): + # 检查目标值减去当前数值是否在哈希表中,如果存在则返回两个数的索引 if target - nums[i] in nums_hash: return [nums_hash[target - nums[i]], i] - nums_hash[nums[i]] = i \ No newline at end of file + + # 将当前数字及其索引存入哈希表 + nums_hash[nums[i]] = i diff --git a/solutions/python3/10.py b/solutions/python3/10.py index 9457b2a..cee317d 100644 --- a/solutions/python3/10.py +++ b/solutions/python3/10.py @@ -1,3 +1,18 @@ + class Solution: - def isMatch(self, s, p): - return bool(re.match(r"%s" %p, s)) and re.match(r"%s" %p, s).group(0) == s \ No newline at end of file + """ + 判断字符串s是否完全匹配正则表达式模式p。 + + 中文注释: + 判断字符串s是否完全符合正则表达式模式p的匹配。 + + :param s: 要匹配的字符串 + :param p: 正则表达式模式 + :return: 如果s完全匹配p,则返回True,否则返回False + """ + def isMatch(self, s: str, p: str) -> bool: + # 使用正则表达式的match方法进行匹配 + match_result = re.match(p, s) + + # 检查是否匹配成功且整个字符串都被匹配到 + return match_result and match_result.group(0) == s diff --git a/solutions/python3/100.py b/solutions/python3/100.py index 6701136..0964702 100644 --- a/solutions/python3/100.py +++ b/solutions/python3/100.py @@ -1,3 +1,14 @@ + class Solution: + # 判断两棵树是否相同,采用递归方法比较两个树的每个节点 def isSameTree(self, p, q): - return p == q if not p or not q else p.val == q.val and self.isSameTree(p.left, q.left) and self.isSameTree(p.right, q.right) \ No newline at end of file + # 如果两个节点都为空,则它们相同 + if not p and not q: + return True + # 仅当p和q都不为空时才进一步比较其值以及子节点 + elif p and q: + # 当前节点的值相等且左右子树均相同则两棵树相同 + return p.val == q.val and self.isSameTree(p.left, q.left) and self.isSameTree(p.right, q.right) + else: + # 其他情况,即一个为空而另一个不为空,或节点值不同,则树不相同 + return False diff --git a/solutions/python3/1000.py b/solutions/python3/1000.py index bfe4817..329fea2 100644 --- a/solutions/python3/1000.py +++ b/solutions/python3/1000.py @@ -1,17 +1,42 @@ + class Solution: def mergeStones(self, stones, K): + """ + Chinese: + 给定一个包含非负整数的数组,表示一些石头的位置。你需要合并这些石头,每次可以合并连续K个石头。 + 如果最终能将所有石头合并为一个,则返回所需的最小代价;否则返回-1。 + + English: + Given an array of non-negative integers, representing some stone positions. + You need to merge these stones. Each time you can merge K consecutive stones into one. + If all the stones can be merged into one in the end, return the minimum cost; otherwise, return -1. + """ + n = len(stones) - if (n - 1) % (K - 1): return -1 + if (n - 1) % (K - 1): + # Chinese: 如果合并后的石头数量不能被K-1整除,则无法完成合并,直接返回-1 + # English: If the number of merged stones cannot be divided by K-1, return -1 as it's impossible to merge all. + return -1 + prefix = [0] * (n + 1) for i in range(n): prefix[i + 1] = prefix[i] + stones[i] import functools + # Chinese: 使用lru_cache来缓存dp函数的结果,避免重复计算 + # English: Use lru_cache to cache the result of dp function to avoid redundant calculations @functools.lru_cache(None) def dp(i, j): - if j - i + 1 < K: return 0 + if j - i + 1 < K: + # Chinese: 当区间长度小于K时,无需合并操作,直接返回0 + # English: If the length of the interval is less than K, no merge operation needed, return 0. + return 0 + res = min(dp(i, mid) + dp(mid + 1, j) for mid in range(i, j, K - 1)) if (j - i) % (K - 1) == 0: + # Chinese: 如果当前区间可以被完全合并,则加上该区间的总和 + # English: If the current interval can be fully merged, add its total sum. res += prefix[j + 1] - prefix[i] return res - return dp(0, n - 1) \ No newline at end of file + + return dp(0, n - 1) diff --git a/solutions/python3/1001.py b/solutions/python3/1001.py index b2346e8..e8722b0 100644 --- a/solutions/python3/1001.py +++ b/solutions/python3/1001.py @@ -1,29 +1,39 @@ + class Solution: def gridIllumination(self, N: int, lamps: List[List[int]], queries: List[List[int]]) -> List[int]: + # 初始化灯的状态集合和方向计数器 lampsOn = set() rowsOn = collections.defaultdict(int) colsOn = collections.defaultdict(int) diagOnTopLeftBottomRight = collections.defaultdict(int) diagOnBottomLeftTopRight = collections.defaultdict(int) + + # 将所有开启的灯的位置添加到集合中,并更新方向计数器 for r, c in lamps: lampsOn.add((r, c)) rowsOn[r] += 1 colsOn[c] += 1 - diagOnTopLeftBottomRight[c-r] += 1 - diagOnBottomLeftTopRight[c+r-N] += 1 - + diagOnTopLeftBottomRight[c - r] += 1 + diagOnBottomLeftTopRight[c + r - N] += 1 + + # 存储查询结果的列表 result = [] + + # 对每个查询位置进行检查 for r, c in queries: - if rowsOn[r] > 0 or colsOn[c] > 0 or diagOnTopLeftBottomRight[c-r] > 0 or diagOnBottomLeftTopRight[c+r-N] > 0: - result.append(1) + if rowsOn[r] > 0 or colsOn[c] > 0 or diagOnTopLeftBottomRight[c - r] > 0 or diagOnBottomLeftTopRight[c + r - N] > 0: + result.append(1) # 灯照亮 else: - result.append(0) + result.append(0) # 灯未照亮 + + # 检查周围的灯并更新状态 adjacentLamps = [(r, c), (r, c-1), (r, c+1), (r-1, c), (r-1, c-1), (r-1, c+1), (r+1, c), (r+1, c-1), (r+1, c+1)] for r, c in adjacentLamps: if (r, c) in lampsOn: lampsOn.discard((r, c)) rowsOn[r] -= 1 colsOn[c] -= 1 - diagOnTopLeftBottomRight[c-r] -= 1 - diagOnBottomLeftTopRight[c+r-N] -= 1 - return result \ No newline at end of file + diagOnTopLeftBottomRight[c - r] -= 1 + diagOnBottomLeftTopRight[c + r - N] -= 1 + + return result diff --git a/solutions/python3/1002.py b/solutions/python3/1002.py index 46a8d55..0d84a34 100644 --- a/solutions/python3/1002.py +++ b/solutions/python3/1002.py @@ -1,11 +1,26 @@ + class Solution: def commonChars(self, A: List[str]) -> List[str]: + """ + 创建一个字典cnt来存储每个字母在所有字符串中出现的最小次数和出现的字符串数量。 + 初始化时,将字母'a'到'z'作为键,对应的值设置为无穷大(表示初始最大小于实际需求)和0(未出现过)。 + + 遍历输入列表A中的每个单词w,使用collections.Counter计算其字符频率,并更新字典cnt中对应字符的最小频次。 + 同时记录该字符在哪些字符串中出现过了。 + + 最后遍历字典cnt,将只出现在所有字符串中的字符添加到结果列表res中。 + + 返回包含公共字符的结果列表。 + """ cnt, res = {s: [float('inf'), 0] for s in string.ascii_lowercase}, [] for w in A: for k, v in collections.Counter(w).items(): + # 更新字母k的最小出现次数 cnt[k][0] = min(cnt[k][0], v) + # 记录字符k在字符串列表A中的出现次数加一 cnt[k][1] += 1 for k in cnt: if cnt[k][1] == len(A): + # 将只出现在所有字符串中的字母添加到结果中,数量为最小频次 res += [k] * cnt[k][0] - return res \ No newline at end of file + return res diff --git a/solutions/python3/1003.py b/solutions/python3/1003.py index cfc1961..b2629e3 100644 --- a/solutions/python3/1003.py +++ b/solutions/python3/1003.py @@ -1,12 +1,20 @@ + class Solution: + # 判断字符串S是否由合法的"abc"子串组成 def isValid(self, S: str) -> bool: stack = [] for i in S: + # 如果当前字符是 'c' if i == 'c': + # 检查栈顶两个元素是否为 'a' 和 'b' if stack[-2:] != ['a', 'b']: return False + # 弹出栈顶的 'b' stack.pop() + # 再弹出栈顶的 'a' stack.pop() else: + # 其他字符直接入栈 stack.append(i) - return not stack \ No newline at end of file + # 栈为空则表示所有合法子串匹配成功 + return not stack diff --git a/solutions/python3/1004.py b/solutions/python3/1004.py index a815051..3086b15 100644 --- a/solutions/python3/1004.py +++ b/solutions/python3/1004.py @@ -1,6 +1,16 @@ + class Solution: + # 定义一个类来解决问题 + def longestOnes(self, A: List[int], K: int) -> int: - zeros, res = [-1] + [i for i, c in enumerate(A) if not c] + [len(A)], 0 + # 初始化零的位置列表,包括边界值 + zeros = [-1] + [i for i, c in enumerate(A) if not c] + [len(A)] + # 结果变量初始化为0 + res = 0 + + # 遍历零的位置列表,找到最大连续1的长度 for j in range(K + 1, len(zeros)): res = max(res, zeros[j] - zeros[j - K - 1] - 1) - return res or K and len(A) \ No newline at end of file + + # 返回结果或根据K和A的长度返回A的长度(为了处理特殊情况) + return res or K and len(A) diff --git a/solutions/python3/1005.py b/solutions/python3/1005.py index d4b7905..d32985a 100644 --- a/solutions/python3/1005.py +++ b/solutions/python3/1005.py @@ -1,7 +1,20 @@ + class Solution: def largestSumAfterKNegations(self, A: List[int], K: int) -> int: - heapq.heapify(A) + """ + 初始化最小堆,以快速找到并处理最负的元素。 + + 参数: + A (List[int]): 包含整数的列表 + K (int): 负数操作次数 + + 返回: + int: 应用K次操作后的最大和 + """ + heapq.heapify(A) # 将列表转换为最小堆,以便高效地获取最负元素 + for _ in range(K): - val = heapq.heappop(A) - heapq.heappush(A, -val) - return sum(A) \ No newline at end of file + val = heapq.heappop(A) # 弹出并处理最负的元素 + heapq.heappush(A, -val) # 推入其相反数 + + return sum(A) # 返回堆中所有元素之和,应用K次操作后 diff --git a/solutions/python3/1006.py b/solutions/python3/1006.py index 58b69bd..51db9d9 100644 --- a/solutions/python3/1006.py +++ b/solutions/python3/1006.py @@ -1,12 +1,26 @@ + class Solution: + # Solution class for the clumsy function + def clumsy(self, N: int) -> int: + """ + Calculate the result of the operation sequence based on the value of N. + + :param N: An integer representing the length of the operation sequence. + :return: The result of the operation sequence as an integer. + """ if N <= 2: + # 当N小于等于2时,直接返回N return N - if N <= 4: + elif N <= 4: + # 当N小于等于4时,根据具体值返回不同的结果 return N + 3 - if N % 4 == 0: + elif N % 4 == 0: + # 当N能被4整除时,返回N+1 return N + 1 elif N % 4 <= 2: + # 当N除以4的余数小于等于2时,返回N+2 return N + 2 else: - return N - 1 \ No newline at end of file + # 其他情况返回N-1 + return N - 1 diff --git a/solutions/python3/1007.py b/solutions/python3/1007.py index 5927048..c043fb3 100644 --- a/solutions/python3/1007.py +++ b/solutions/python3/1007.py @@ -1,4 +1,12 @@ + class Solution: + # 定义一个类来解决问题 + def minDominoRotations(self, A: List[int], B: List[int]) -> int: - res = min(len(A) - max(A.count(c), B.count(c)) if all(a == c or b == c for a, b in zip(A, B)) else float('inf') for c in (A[0], B[0])) - return res if res < float('inf') else -1 \ No newline at end of file + # 计算最小转动次数,使得数组A和B可以通过翻转使其所有元素相等 + + res = min(len(A) - max(A.count(c), B.count(c)) if all(a == c or b == c for a, b in zip(A, B)) else float('inf') + for c in (A[0], B[0])) + + # 如果res小于无穷大,返回res,否则返回-1 + return res if res < float('inf') else -1 diff --git a/solutions/python3/1008.py b/solutions/python3/1008.py index f185557..7f359ac 100644 --- a/solutions/python3/1008.py +++ b/solutions/python3/1008.py @@ -1,14 +1,22 @@ + class Solution: + # 定义一个从先序遍历序列构建二叉搜索树的方法 def bstFromPreorder(self, preorder: List[int]) -> TreeNode: + # 根节点初始化为先序遍历的第一个元素 root = TreeNode(preorder[0]) + # 使用栈来维护当前的父节点列表,初始时包含根节点 stack = [root] + for value in preorder[1:]: + # 如果当前值小于栈顶节点,则将其作为左子节点 if value < stack[-1].val: stack[-1].left = TreeNode(value) stack.append(stack[-1].left) else: + # 否则,弹出栈中所有小于当前值的节点,并将当前值作为最后一个弹出节点的右子节点 while stack and stack[-1].val < value: last = stack.pop() last.right = TreeNode(value) stack.append(last.right) - return root \ No newline at end of file + + return root diff --git a/solutions/python3/1009.py b/solutions/python3/1009.py index 653f3d1..62d8c59 100644 --- a/solutions/python3/1009.py +++ b/solutions/python3/1009.py @@ -1,3 +1,6 @@ + class Solution: + # 求解位运算补数的方法,N为需要求补的数字,M可选参数初始为0,m用于辅助计算 def bitwiseComplement(self, N: int, M = 0, m = 0) -> int: - return N ^ M if M and M >= N else self.bitwiseComplement(N, M + 2 ** m, m + 1) \ No newline at end of file + # 如果M大于等于N且M非零,则返回N和M的异或结果(位运算补数) + return N ^ M if M and M >= N else self.bitwiseComplement(N, M + 2 ** m, m + 1) diff --git a/solutions/python3/101.py b/solutions/python3/101.py index 2cea9f6..3099063 100644 --- a/solutions/python3/101.py +++ b/solutions/python3/101.py @@ -1,24 +1,48 @@ -#Definition for a binary tree node. + +# Definition for a binary tree node. class TreeNode: def __init__(self, x): - self.val = x - self.left = None - self.right = None + self.val = x # 节点的值 + self.left = None # 左子节点 + self.right = None # 右子节点 class Solution: + """ + 检查二叉树是否对称。 + + :type root: TreeNode, 树的根节点 + :rtype: bool, 是否对称 + """ + def isSymmetric(self, root): """ - :type root: TreeNode - :rtype: bool + 检查两棵子树是否互为镜像。 + + :type left: TreeNode, 左子节点 + :type right: TreeNode, 右子节点 + :rtype: bool, 两子树是否互为镜像 """ if root is None: - return True + return True # 空树是对称的 + else: return self.isMirror(root.left, root.right) def isMirror(self, left, right): + """ + 检查两棵子树是否互为镜像。 + + :type left: TreeNode, 左子节点 + :type right: TreeNode, 右子节点 + :rtype: bool, 两子树是否互为镜像 + + - 如果左右节点都为空,则互为镜像。 + - 如果仅有一个节点为空,或者节点值不同,则不互为镜像。 + - 否则检查左子树的左孩子和右子树的右孩子,以及左子树的右孩子和右子树的左孩子是否互为镜像。 + """ if left is None and right is None: return True + if left is None or right is None: return False @@ -28,4 +52,3 @@ def isMirror(self, left, right): return outPair and inPiar else: return False - \ No newline at end of file diff --git a/solutions/python3/1010.py b/solutions/python3/1010.py index 1a62844..61716e9 100644 --- a/solutions/python3/1010.py +++ b/solutions/python3/1010.py @@ -1,7 +1,20 @@ + class Solution: + # 定义一个解决方案类 + def numPairsDivisibleBy60(self, time: List[int]) -> int: - mod = [0] * 61 + """ + 计算时间数组中可以配对且每对之和能被60整除的方案数。 + + :param time: 时间列表,每个元素表示音乐播放时间(秒) + :return: 返回能够配对的时间数量 + """ + mod = [0] * 61 # 创建一个长度为61的数组用于记录每种余数出现次数 + for t in time: + # 对当前时间t取模60,找到其与某个元素组合能被60整除的匹配对个数 mod[-1] += mod[(60 - t % 60) % 60] + # 更新当前时间对应的计数字数 mod[t % 60] += 1 - return mod[-1] \ No newline at end of file + + return mod[-1] # 返回最后一项,即所有能够配对的方案总数 diff --git a/solutions/python3/1011.py b/solutions/python3/1011.py index ec9dc12..6773ff8 100644 --- a/solutions/python3/1011.py +++ b/solutions/python3/1011.py @@ -1,21 +1,32 @@ + class Solution: + # 定义一个检查函数,判断最大载重mx是否可行 def shipWithinDays(self, weights: List[int], D: int) -> int: def check(mx): + """ + :param mx: 最大允许的重量 + :return: 使用不超过D天能否将所有货物运送完 + """ days, cur = 1, 0 for w in weights: if cur + w <= mx: - cur += w + cur += w # 当前船的载重加上当前货物重量仍小于等于mx,可以继续装载 else: - days += 1 - cur = w + days += 1 # 需要额外一天来运送 + cur = w # 更新当前船只载重为w return days - + + # 定义左右边界,即最大和最小可能的每船最大承重 l, r = max(weights), sum(weights) + + # 二分查找确定最小的最大载重量 while l < r: mid = (l + r) // 2 days = check(mid) - if days <= D: + + if days <= D: # 如果天数不超过D,则说明mid可能是一个可行解,尝试更小的值 r = mid else: - l = mid + 1 - return r \ No newline at end of file + l = mid + 1 # 天数超过D,需要更大的最大载重量来减少天数 + + return r diff --git a/solutions/python3/1012.py b/solutions/python3/1012.py index 85e9b7b..ce5fa75 100644 --- a/solutions/python3/1012.py +++ b/solutions/python3/1012.py @@ -1,44 +1,66 @@ + class Solution(object): - def numDupDigitsAtMostN(self, N): + def numDupDigitsAtMostN(self, N: int) -> int: + """ + :param N: 输入整数,范围在 [0, 2^31 - 1] 内 + :return: 不含重复数字的正整数个数,这些数小于或等于 N + + 思路: + 1. 将输入转换为字符串形式以处理位数和重复字符。 + 2. 计算小于给定数值的所有非重复数的数量。 + 3. 通过逐位构建数来精确计算结果。 """ - :type N: int - :rtype: int - """ - # given number n, see whether n has repeated number - def has_repeated(n): + + # 判断数字 n 是否包含重复的数字 + def has_repeated(n: int) -> bool: + """ + :param n: 输入整数 + :return: 如果 n 包含重复数字,返回 True;否则返回 False + """ str_n = str(n) return len(set(str_n)) != len(str_n) - def permutation(n, k): + # 计算 k 位非零起始的全排列数量 + def permutation(n: int, k: int) -> int: + """ + :param n: 总数 + :param k: 需要选择的数量 + :return: k 位非重复数字组合的个数 + """ prod = 1 for i in range(k): - prod *= (n-i) + prod *= (n - i) return prod - # calculate number of non-repeated n-digit numbers - # note: the n-digit number can't start with 0 - # i.e: n_digit_no_repeat(2) calculates the non-repeated - # numbers in range [10, 99] (inclusive) - def n_digit_no_repeat(n): + # 计算 n 位非重复整数的数量(不以0开头) + def n_digit_no_repeat(n: int) -> int: + """ + :param n: 数字位数 + :return: n 位全排列非重复数字的个数,n >= 1 + """ if n == 1: - return 9 + return 9 # 单一位数时从 1-9 中选 else: - return 9 * permutation(9, n-1) + return 9 * permutation(9, n - 1) N_str = str(N) - n_digit = len(N_str) - digits = list(map(int, N_str)) - result = N - 1 + n_digit = len(N_str) # 计算位数 + digits = list(map(int, N_str)) # 将每一位转换为整数 + + result = N - 1 # 初始结果:小于N的非重复数字个数 + prefix = 0 - for i in range(1, n_digit): + for i in range(1, n_digit): # 计算所有比给定数字少n位的非重复数字数量 result -= n_digit_no_repeat(i) + for i in range(n_digit): - # when we fix the most significant digit, it - # can't be zero - start = 0 if i else 1 + start = 1 if i == 0 and digits[i] > 0 else 0 # 处理最高有效位不能为零的情况 + for j in range(start, digits[i]): - if has_repeated(prefix * 10 + j): + if has_repeated(prefix * 10 + j): # 如果构建的前缀加上当前数字会导致重复,跳过 continue - result -= permutation(9 - i, n_digit-1-i) - prefix = prefix*10 + digits[i] - return result + has_repeated(N) \ No newline at end of file + result -= permutation(9 - i, n_digit - 1 - i) # 剩余位数的排列组合 + + prefix = prefix * 10 + digits[i] # 更新前缀 + + return result + has_repeated(N) # 返回最终结果,加上N本身是否含重复数字 diff --git a/solutions/python3/1013.py b/solutions/python3/1013.py index bfa8b57..3b368b0 100644 --- a/solutions/python3/1013.py +++ b/solutions/python3/1013.py @@ -1,10 +1,23 @@ + class Solution: def canThreePartsEqualSum(self, A: List[int]) -> bool: - tar = sum(A) // 3 + """ + 判断数组A是否可以被分割为三个具有相同和的子数组 + + 中文注释:判断数组A是否可以被分割为三个具有相同和的子数组 + """ + tar = sum(A) // 3 # 计算目标值,即每个部分应具有的和 + """ + 英文注释:Calculate the target value, which is the sum each part should have. + """ sm = cnt = 0 for a in A: - sm += a - if sm == tar: - sm = 0 - cnt += 1 - return cnt == 3 \ No newline at end of file + sm += a # 累加当前元素的值到sm中 + if sm == tar: # 当累加和等于目标值时 + sm = 0 # 重置累计和 + cnt += 1 # 计数器加一,表示找到一个满足条件的部分 + """ + 中文注释:遍历数组A中的每个元素,并检查是否可以将其分割成三个具有相同和的子数组。 + 英文注释:Iterate through each element in array A, and check if it can be divided into three parts with the same sum. + """ + return cnt == 3 # 检查计数器cnt是否等于3 diff --git a/solutions/python3/1014.py b/solutions/python3/1014.py index d7cfba3..7f0cb85 100644 --- a/solutions/python3/1014.py +++ b/solutions/python3/1014.py @@ -1,7 +1,17 @@ + class Solution: + # 定义一个类用于解决最大观光组合问题 + def maxScoreSightseeingPair(self, A: List[int]) -> int: + # 初始化前缀和及最大值为负无穷 pre, mx = 0, -float('inf') + + # 遍历数组中的每个元素及其索引 for j, a in enumerate(A): + # 更新当前可以组成的最优观光组合分数 mx = max(mx, pre + a - j) + # 更新前缀和,使其尽可能大 pre = max(pre, a + j) - return mx \ No newline at end of file + + # 返回最终的最大分数 + return mx diff --git a/solutions/python3/1015.py b/solutions/python3/1015.py index 8008129..2946024 100644 --- a/solutions/python3/1015.py +++ b/solutions/python3/1015.py @@ -1,10 +1,20 @@ + class Solution: def smallestRepunitDivByK(self, K: int) -> int: - used, mod, cnt = set(), 1 % K, 1 - while mod: - mod = (mod * 10 + 1) % K - cnt += 1 - if mod in used: + """ + 解决问题:给定一个整数 K,找到最短的由 1 组成且能被 K 整除的连续子序列长度。 + + 中文注释: + - 目标是找到最短的全由 1 构成的子串,使其能被 K 整除 + """ + used, mod, cnt = set(), 1 % K, 1 # 初始化已使用过的模值集合、当前余数和计数器 + + while mod: # 当余数不为0时循环 + mod = (mod * 10 + 1) % K # 计算新的余数,相当于将当前序列长度增加1并取模K + cnt += 1 # 增加计数器 + + if mod in used: # 如果当前余数已经出现过,说明形成循环,无解 return -1 - used.add(mod) - return cnt \ No newline at end of file + used.add(mod) # 将当前余数加入已使用集合 + + return cnt # 返回最短子序列长度 diff --git a/solutions/python3/1016.py b/solutions/python3/1016.py index 369e506..49b87ba 100644 --- a/solutions/python3/1016.py +++ b/solutions/python3/1016.py @@ -1,3 +1,18 @@ + class Solution: def queryString(self, S: str, N: int) -> bool: - return not set(range(1, N + 1)) - {int(S[i:j + 1], 2) for i in range(len(S)) for j in range(i, len(S))} \ No newline at end of file + """ + 检查字符串S中是否包含从1到N的所有二进制表示 + + Chinese: + 检查字符串S中是否存在从1到N的所有二进制表示形式。 + + 参数: + S (str): 输入的字符串 + N (int): 需要检查的最大整数 + + 返回: + bool: 如果S包含所有从1到N的二进制表示,则返回True,否则返回False + """ + # 使用集合进行差集计算,找出缺失的二进制值 + return not set(range(1, N + 1)) - {int(S[i:j + 1], 2) for i in range(len(S)) for j in range(i, len(S))} diff --git a/solutions/python3/1017.py b/solutions/python3/1017.py index caed416..e0d9051 100644 --- a/solutions/python3/1017.py +++ b/solutions/python3/1017.py @@ -1,10 +1,46 @@ + class Solution: + # 定义一个类来处理负二进制转换 + def baseNeg2(self, n: int) -> str: + # 初始化位列表,用于存储每一位的结果 bits = [] - while n: + + while n != 0: + # 使用divmod进行除法运算,并得到商和余数 n, rem = divmod(n, -2) + + # 如果余数小于0,则调整n和rem的值 if rem < 0: n += 1 rem -= -2 + + # 将当前位转换为字符串形式并添加到bits列表中 bits.append(str(rem)) - return "".join(bits[::-1]) if bits else '0' \ No newline at end of file + + # 如果没有生成任何位,返回'0' + return "".join(bits[::-1]) if bits else '0' + + + +class Solution: + # 定义一个类来处理负二进制转换 + + def baseNeg2(self, n: int) -> str: + # 初始化位列表,用于存储每一位的结果 + bits = [] + + while n != 0: + # 使用divmod进行除法运算,并得到商和余数 + n, rem = divmod(n, -2) + + # 如果余数小于0,则调整n和rem的值 + if rem < 0: + n += 1 + rem -= -2 + + # 将当前位转换为字符串形式并添加到bits列表中 + bits.append(str(rem)) + + # 如果没有生成任何位,返回'0' + return "".join(bits[::-1]) if bits else '0' diff --git a/solutions/python3/1018.py b/solutions/python3/1018.py index dad7279..3d9c53b 100644 --- a/solutions/python3/1018.py +++ b/solutions/python3/1018.py @@ -1,7 +1,18 @@ + class Solution: def prefixesDivBy5(self, A: List[int]) -> List[bool]: - num = 0 + """ + 判断给定整数列表A中每个前缀(包括整个序列)是否能被5整除。 + + Args: + A (List[int]): 输入的整数列表 + + Returns: + List[bool]: 每个前缀能否被5整除的结果列表 + """ + num = 0 # 初始化当前数值为0 for i in range(len(A)): + # 将当前位加入到num中,并更新num,同时判断前i+1位是否能被5整除 num = (num << 1) + A[i] - A[i] = num % 5 == 0 - return A \ No newline at end of file + A[i] = num % 5 == 0 # 更新结果列表中的当前值 + return A # 返回最终的结果列表 diff --git a/solutions/python3/1019.py b/solutions/python3/1019.py index 7ff5b43..94bd722 100644 --- a/solutions/python3/1019.py +++ b/solutions/python3/1019.py @@ -1,3 +1,4 @@ + # Definition for singly-linked list. # class ListNode: # def __init__(self, x): @@ -5,15 +6,26 @@ # self.next = None class Solution: + # 中文注释:初始化一个优先队列heap、结果列表res和索引j def nextLargerNodes(self, head: ListNode) -> List[int]: heap, res, j = [], [], 0 + + # 中文注释:遍历链表head,直到其为空 while head: + # 中文注释:在结果列表中添加0作为初始值 res.append(0) + + # 中文注释:如果堆heap中有元素且最小元素小于当前节点的值,则出堆并更新对应位置的结果 while heap and heap[0][0] < head.val: val, i = heapq.heappop(heap) res[i] = head.val + + # 中文注释:将当前节点的值和索引j入堆 heapq.heappush(heap, (head.val, j)) + + # 中文注释:更新索引j,并移动到下一个节点 j += 1 head = head.next + + # 中文注释:返回结果列表res return res - \ No newline at end of file diff --git a/solutions/python3/102.py b/solutions/python3/102.py index e61e7a2..8332e39 100644 --- a/solutions/python3/102.py +++ b/solutions/python3/102.py @@ -1,18 +1,20 @@ + # Definition for a binary tree node. -# class TreeNode: -# def __init__(self, x): -# self.val = x -# self.left = None -# self.right = None +class TreeNode: + def __init__(self, x): + self.val = x + self.left = None + self.right = None class Solution: - def levelOrder(self, root): + # 用于层次遍历二叉树并返回节点值的列表 + def levelOrder(self, root: 'TreeNode') -> 'List[List[int]]': """ :type root: TreeNode :rtype: List[List[int]] """ - q, res = [root], [] - while any(q): - res.append([i.val for i in q]) - q = [kid for node in q for kid in (node.left, node.right) if kid] - return res \ No newline at end of file + q, res = [root], [] # 初始化队列和结果列表 + while any(q): # 队列非空时循环 + res.append([i.val for i in q]) # 将当前层节点值加入结果中 + q = [kid for node in q for kid in (node.left, node.right) if kid] # 更新队列为下一层的节点 + return res # 返回层次遍历的结果 diff --git a/solutions/python3/1020.py b/solutions/python3/1020.py index 0f2b438..02c921f 100644 --- a/solutions/python3/1020.py +++ b/solutions/python3/1020.py @@ -1,13 +1,29 @@ + class Solution: def numEnclaves(self, A: List[List[int]]) -> int: + """ + 计算矩阵中的封闭岛屿数量。封闭岛屿指的是所有值为1且不与边界相连的区域。 + + :param A: List[List[int]] - 输入的二维矩阵,其中0表示水域,1表示陆地 + :return: int - 封闭岛屿的数量 + """ + def dfs(i, j): - A[i][j] = 0 + """ + 深度优先搜索函数,用于标记访问过的陆地标记为0,并递归访问其相邻的陆地。 + + :param i: int - 当前行索引 + :param j: int - 当前列索引 + """ + A[i][j] = 0 # 将当前陆地标记为已访问(水域) for x, y in (i - 1, j), (i + 1, j), (i, j - 1), (i, j + 1): if 0 <= x < m and 0 <= y < n and A[x][y]: - dfs(x, y) - m, n = len(A), len(A[0]) + dfs(x, y) # 访问相邻陆地 + + m, n = len(A), len(A[0]) # 获取矩阵的行数和列数 for i in range(m): for j in range(n): if A[i][j] == 1 and (i == 0 or j == 0 or i == m - 1 or j == n - 1): - dfs(i, j) - return sum(sum(row) for row in A) \ No newline at end of file + dfs(i, j) # 从边界上的陆地开始进行深度优先搜索 + + return sum(sum(row) for row in A) # 计算剩余的1的数量,即封闭岛屿的数量 diff --git a/solutions/python3/1021.py b/solutions/python3/1021.py index 9bd7680..c7fa3f6 100644 --- a/solutions/python3/1021.py +++ b/solutions/python3/1021.py @@ -1,12 +1,28 @@ + class Solution: + # 初始化方法,无参数,用于实例化Solution类 + def removeOuterParentheses(self, S: str) -> str: - l = r = 0 - res = cur = '' + """ + 移除字符串S最外层的括号。 + + 参数: + S (str): 输入的字符串,包含有效的括号序列 + + 返回: + str: 去掉最外层括号后的结果 + """ + l = r = 0 # 初始化左括号和右括号计数器 + res = cur = '' # 初始化结果字符串和当前子串 + for s in S: - cur += s - l += s == '(' - r += s == ')' + cur += s # 将当前字符加入当前子串中 + if s == '(': l += 1 # 左括号计数加一 + elif s == ')': r += 1 # 右括号计数加一 + + # 当左括号和右括号数量相等时,说明找到了一个完整的子串 if l == r: - res += cur[1:-1] - cur = '' - return res \ No newline at end of file + res += cur[1:-1] # 将当前子串去掉首尾后的部分加入结果字符串中 + cur = '' # 清空当前子串 + + return res # 返回最终结果字符串 diff --git a/solutions/python3/1022.py b/solutions/python3/1022.py index ec20e26..f9cbfde 100644 --- a/solutions/python3/1022.py +++ b/solutions/python3/1022.py @@ -1,13 +1,19 @@ + # Definition for a binary tree node. -# class TreeNode: -# def __init__(self, x): -# self.val = x -# self.left = None -# self.right = None +class TreeNode: + def __init__(self, x): + self.val = x + self.left = None + self.right = None class Solution: + # 计算从根节点到叶子节点的二进制数值之和模10^9+7 def sumRootToLeaf(self, r: TreeNode, num = 0) -> int: if not r: return 0 + + # 将当前节点值加入路径数值中,并左移一位 num = (num << 1) + r.val - return (self.sumRootToLeaf(r.left, num) + self.sumRootToLeaf(r.right, num) if r.left or r.right else num) % (10 ** 9 + 7) \ No newline at end of file + + # 如果左右子节点都存在,递归计算它们的和;如果不存在任一子节点,则返回当前路径数值 + return (self.sumRootToLeaf(r.left, num) + self.sumRootToLeaf(r.right, num) if r.left or r.right else num) % (10 ** 9 + 7) diff --git a/solutions/python3/1023.py b/solutions/python3/1023.py index 61f6a0c..ee2c110 100644 --- a/solutions/python3/1023.py +++ b/solutions/python3/1023.py @@ -1,12 +1,37 @@ + class Solution: def camelMatch(self, queries: List[str], pattern: str) -> List[bool]: + """ + 判断queries中的每个字符串是否与pattern匹配。 + + 匹配规则: + 1. 每个queries中的字符顺序应与pattern中相同或在pattern的适当位置 + 2. pattern中的所有小写字母必须出现在queries中对应的小写形式 + 3. queries中出现的大写字母不能出现在pattern中 + + 参数: + queries: 包含多个字符串的列表 + pattern: 模式字符串 + + 返回: + 结果列表,每个元素表示对应的query是否匹配pattern + """ res = [] + + # 遍历queries中的每一个字符串 for w in queries: j = 0 + + # 遍历当前查询字符串w的每个字符c for c in w: + # 如果当前模式字符和查询字符串字符相等,继续比较下一个模式字符 if j < len(pattern) and c == pattern[j]: j += 1 + # 如果遇到大写字母,停止匹配(因为必须与pattern严格一致) elif c.isupper(): j = len(pattern) + 1 + + # 根据是否完全匹配模式字符串确定结果并添加至结果列表 res.append(j == len(pattern)) - return res \ No newline at end of file + + return res diff --git a/solutions/python3/1024.py b/solutions/python3/1024.py index 633c1be..851a64c 100644 --- a/solutions/python3/1024.py +++ b/solutions/python3/1024.py @@ -1,11 +1,19 @@ + class Solution: def videoStitching(self, clips: List[List[int]], T: int) -> int: - clips.sort(key = lambda x: (-x[0], x[1])) + # 按起始时间降序排序,如果起始时间相同,则按结束时间升序排序 + clips.sort(key=lambda x: (-x[0], x[1])) + x = cnt = mx = 0 + # 当存在clips且当前时间小于目标时间和当前最远播放时间为终止条件 while clips and clips[-1][0] <= x < T: + # 遍历所有满足当前时间的剪辑,更新最大结束时间 while clips and clips[-1][0] <= x: mx = max(mx, clips.pop()[1]) + if mx > x: + # 更新当前位置为最远播放位置 x = mx cnt += 1 - return cnt if x >= T else -1 \ No newline at end of file + + return cnt if x >= T else -1 diff --git a/solutions/python3/1025.py b/solutions/python3/1025.py index 9575668..2664ce9 100644 --- a/solutions/python3/1025.py +++ b/solutions/python3/1025.py @@ -1,3 +1,6 @@ + class Solution: + # 判断N是否为偶数 def divisorGame(self, N: int) -> bool: - return N % 2 == 0 \ No newline at end of file + # 如果N是偶数,返回True;否则返回False + return N % 2 == 0 diff --git a/solutions/python3/1026.py b/solutions/python3/1026.py index 72a30a0..783eee0 100644 --- a/solutions/python3/1026.py +++ b/solutions/python3/1026.py @@ -1,3 +1,4 @@ + # Definition for a binary tree node. # class TreeNode: # def __init__(self, x): @@ -6,20 +7,36 @@ # self.right = None class Solution: + # 计算二叉树中任意两个节点值之间的最大差值,其中较大的节点是较小节点的祖先 def maxAncestorDiff(self, root: TreeNode) -> int: + """ + :param root: 二叉树根节点 + :return: 二叉树中任意两个节点值之间的最大差值 + """ + self.res = 0 + + # 深度优先搜索,计算当前节点的最大最小值,并更新结果 def dfs(node): - mx = mn = node.val + """ + :param node: 当前遍历到的节点 + :return: 以该节点为根的最大最小值 + """ + mx, mn = node.val, node.val + if node.left: lMn, lMx = dfs(node.left) mx = max(mx, lMx) mn = min(mn, lMn) self.res = max(self.res, abs(lMn - node.val), abs(lMx - node.val)) + if node.right: rMn, rMx = dfs(node.right) mx = max(mx, rMx) mn = min(mn, rMn) self.res = max(self.res, abs(rMn - node.val), abs(rMx - node.val)) + return mn, mx - dfs(root) - return self.res \ No newline at end of file + + dfs(root) # 开始深度优先搜索 + return self.res # 返回结果 diff --git a/solutions/python3/1027.py b/solutions/python3/1027.py index c3208f0..7a1b264 100644 --- a/solutions/python3/1027.py +++ b/solutions/python3/1027.py @@ -1,8 +1,25 @@ + +from collections import defaultdict + class Solution: def longestArithSeqLength(self, A: List[int]) -> int: - dp = collections.defaultdict(int) + """ + 初始化一个defaultdict来存储差值和对应索引下的最大长度 + - 使用defaultdict来自动处理不存在的键,默认值为0,便于后续直接取值 + """ + dp = defaultdict(int) + + """ + 遍历列表A中的每个元素对(i, j),j > i, + 计算差值 b - a,并更新dp表中该差值对应的最长等差子序列长度 + """ for i in range(len(A)): for j in range(i + 1, len(A)): a, b = A[i], A[j] dp[b - a, j] = max(dp[b - a, j], dp[b - a, i] + 1) - return max(dp.values()) + 1 \ No newline at end of file + + """ + 返回dp表中所有值的最大值加一,即为最长等差子序列的长度 + - 加一是因为初始长度至少为2(自身和下一个数) + """ + return max(dp.values()) + 1 diff --git a/solutions/python3/1028.py b/solutions/python3/1028.py index 4d78667..da71861 100644 --- a/solutions/python3/1028.py +++ b/solutions/python3/1028.py @@ -1,41 +1,60 @@ + # Definition for a binary tree node. -# class TreeNode: -# def __init__(self, x): -# self.val = x -# self.left = None -# self.right = None +class TreeNode: + def __init__(self, x): + self.val = x + self.left = None + self.right = None class Solution: + # 根据前序遍历字符串恢复二叉树 def recoverFromPreorder(self, S: str) -> TreeNode: + def dfs(parent, s, lev): - print(parent.val, s, lev) - if not s: return + # 打印当前节点信息(调试用) + print(f"Node value: {parent.val}, String: {s}, Level: {lev}") + + if not s: + return + i = lev l = 0 while i < len(s) and s[i].isdigit(): l = l * 10 + int(s[i]) i += 1 - parent.left = TreeNode(l) + + parent.left = TreeNode(l) + j = lev f = '-' * lev + + # 找到右子节点的起始位置 for ind in range(i, len(s)): - if s[ind:].startswith(f) and not s[ind:].startswith(f + '-') and s[ind -1] != '-': + if s[ind:].startswith(f) and not s[ind:].startswith(f + '-') and s[ind - 1] != '-': rr = ind j = ind + lev r = 0 + while j < len(s) and s[j].isdigit(): r = r * 10 + int(s[j]) j += 1 + parent.right = TreeNode(r) + + # 递归处理左子节点和右子节点 dfs(parent.left, s[i:rr], lev + 1) dfs(parent.right, s[j:], lev + 1) return + dfs(parent.left, s[i:], lev + 1) + i = num = 0 while i < len(S) and S[i].isdigit(): num = num * 10 + int(S[i]) i += 1 + root = TreeNode(num) + + # 开始递归构建树结构 dfs(root, S[i:], 1) return root - \ No newline at end of file diff --git a/solutions/python3/1029.py b/solutions/python3/1029.py index 931c567..0284ffe 100644 --- a/solutions/python3/1029.py +++ b/solutions/python3/1029.py @@ -1,14 +1,32 @@ + class Solution: + # 定义一个解决方案类,用于解决给定的两城市计划成本问题 + def twoCitySchedCost(self, costs: List[List[int]]) -> int: - costs.sort(key = lambda x: abs(x[0] - x[1])) - a = b = 0 - N = len(costs) // 2 - c = 0 - for c1, c2 in costs[::-1]: - if c1 <= c2 and a < N or b >= N: + """ + 计算使两个城市的人参加计划所需的最小总成本。 + + 参数: + - costs (List[List[int]]): 每个人参加两个城市的成本,格式为 [去A城的成本, 去B城的成本] 的列表 + + 返回值: + - int: 使得两组人数相等且成本最低的总成本 + """ + + # 根据去两个城市成本差排序,优化选择顺序 + costs.sort(key=lambda x: abs(x[0] - x[1])) + + a = b = 0 # 初始化前往A城和B城的人数为0 + N = len(costs) // 2 # 计算总人数的一半作为每组的目标人数 + + c = 0 # 总成本初始化为0 + + for c1, c2 in costs[::-1]: # 反向遍历排序后的列表以优先选择差异较小的成本组合 + if c1 <= c2 and a < N or b >= N: # 若当前人去A城更划算且A城人数未满,或B城人数已满,则去A城 c += c1 a += 1 else: c += c2 b += 1 - return c \ No newline at end of file + + return c # 返回最小总成本 diff --git a/solutions/python3/103.py b/solutions/python3/103.py index 81298a2..f186806 100644 --- a/solutions/python3/103.py +++ b/solutions/python3/103.py @@ -1,3 +1,4 @@ + # Definition for a binary tree node. # class TreeNode: # def __init__(self, x): @@ -6,13 +7,19 @@ # self.right = None class Solution: + # 用于处理二叉树节点的层次遍历,返回按之字形顺序排列的结果 + # :type root: TreeNode 根节点 + # :rtype: List[List[int]] 按照之字形顺序的每一层节点值列表 + def zigzagLevelOrder(self, root): - """ - :type root: TreeNode - :rtype: List[List[int]] - """ q, i, res = [root], 0, [] - while any(q): - add, q, i = q if i % 2 == 0 else q[::-1], [kid for node in q for kid in (node.left, node.right) if kid], i+1 - res.append([item.val for item in add]) - return res \ No newline at end of file + + while any(q): # 当队列非空时循环 + if i % 2 == 0: # 偶数层,直接添加 + add, q, i = q, [kid for node in q for kid in (node.left, node.right) if kid], i + 1 + else: # 奇数层,倒序添加 + add, q, i = q[::-1], [kid for node in q for kid in (node.left, node.right) if kid], i + 1 + + res.append([item.val for item in add]) # 将节点值加入结果列表 + + return res diff --git a/solutions/python3/1030.py b/solutions/python3/1030.py index f103bf3..8da0a8a 100644 --- a/solutions/python3/1030.py +++ b/solutions/python3/1030.py @@ -1,14 +1,25 @@ + class Solution: + # Python 解决方案类 + def allCellsDistOrder(self, R: int, C: int, r0: int, c0: int) -> List[List[int]]: + # 初始化队列、结果列表和已访问集合 bfs, res, seen = [[r0, c0]], [], {(r0, c0)} + while bfs: + # 将当前层节点添加到结果中 res += bfs + # 初始化新一层的节点列表 new = [] + for i, j in bfs: + # 遍历当前层节点的四个方向 for x, y in (i - 1, j), (i + 1, j), (i, j + 1), (i, j - 1): + # 检查新坐标是否在范围内且未被访问过 if 0 <= x < R and 0 <= y < C and (x, y) not in seen: seen.add((x, y)) new.append([x, y]) + bfs = new + return res - \ No newline at end of file diff --git a/solutions/python3/1031.py b/solutions/python3/1031.py index 2c03a21..532f31d 100644 --- a/solutions/python3/1031.py +++ b/solutions/python3/1031.py @@ -1,33 +1,41 @@ + class Solution: + # Python 解决方案类 + def maxSumTwoNoOverlap(self, A: List[int], L: int, M: int) -> int: n = len(A) + + # 前缀和数组 l 和 r,用于记录最大子段和 l = [0] * n r = [0] * n + + # 计算前缀和 l 的初始值 sm = 0 - for i in range(M - 1): + for i in range(L - 1): sm += A[i] - for j in range(n - M + 1): - sm += A[j + M - 1] + for j in range(n - L + 1): + sm += A[j + L - 1] for i in range(j + 1): r[i] = max(r[i], sm) sm -= A[j] + # 计算前缀和 r 的初始值 sm = 0 - for i in range(n - 1, n - M, -1): + for i in range(n - 1, n - L, -1): sm += A[i] - for i in range(n - 1, M - 2, -1): - sm += A[i - M + 1] + for i in range(n - 1, L - 2, -1): + sm += A[i - L + 1] for j in range(i + 1, n): l[j] = max(l[j], sm) sm -= A[i] - - - + # 计算最大和 sm = 0 + res = 0 + + # 遍历数组 A,计算两个不重叠子段的最大和 for i in range(L - 1): sm += A[i] - res = 0 for j in range(n - L + 1): sm += A[j + L - 1] if j >= M: @@ -35,4 +43,5 @@ def maxSumTwoNoOverlap(self, A: List[int], L: int, M: int) -> int: if j + L < n: res = max(res, sm + r[j + L]) sm -= A[j] - return res \ No newline at end of file + + return res diff --git a/solutions/python3/1032.py b/solutions/python3/1032.py index 6e9adf4..d8b62a3 100644 --- a/solutions/python3/1032.py +++ b/solutions/python3/1032.py @@ -1,12 +1,24 @@ + import functools +from collections import defaultdict + class StreamChecker(object): + # 初始化Trie树,用于存储单词 def __init__(self, words): - T = lambda: collections.defaultdict(T) + # 使用lambda函数定义一个字典工厂函数 + T = lambda: defaultdict(T) + # 创建Trie树根节点 self.trie = T() - for w in words: functools.reduce(dict.__getitem__, w, self.trie)['#'] = True + # 构建Trie树并插入所有单词 + for w in words: + functools.reduce(dict.__getitem__, w, self.trie)['#'] = True + # 初始化等待列表,用于存储当前正在匹配的路径节点 self.waiting = [] + # 查询函数,判断当前字母是否构成某个单词 def query(self, letter): + # 更新等待列表:移除不符合条件的节点,并加入新字母对应的新节点 self.waiting = [node[letter] for node in self.waiting + [self.trie] if letter in node] - return any("#" in node for node in self.waiting) \ No newline at end of file + # 检查当前等待列表是否包含结束符'#' + return any("#" in node for node in self.waiting) diff --git a/solutions/python3/1033.py b/solutions/python3/1033.py index d55d91e..7662366 100644 --- a/solutions/python3/1033.py +++ b/solutions/python3/1033.py @@ -1,12 +1,45 @@ + class Solution: def numMovesStones(self, a: int, b: int, c: int) -> List[int]: + """ + 将三个数排序,方便后续计算移动次数。 + Sort the three numbers for easier calculation of moves. + """ a, b, c = sorted([a, b, c]) + + """ + 计算中间位置和c之间的空位数量。 + Calculate the number of empty positions between the middle position and c. + """ m1 = b - 1 - a + + """ + 计算b和c之间的空位数量。 + Calculate the number of empty positions between b and c. + """ m2 = c - b - 1 - m1 + m2 + + # 直接计算m1 + m2,因为后续需要这个值。 + _ = m1 + m2 + + """ + 如果a, b间或b, c间只需要一步即可移动,则返回[1, m1 + m2]。 + If a and b or b and c are only one step apart, return [1, m1 + m2]. + """ if a + 2 == b or b + 2 == c: return [1, m1 + m2] + + """ + 计算b左侧需要移动的次数。 + Calculate the number of moves needed to move stones from left. + """ n1 = int(b - 1 > a) + + """ + 计算b右侧需要移动的次数。 + Calculate the number of moves needed to move stones from right. + """ n2 = int(b + 1 < c) - return [n1 + n2, m1 + m2] - \ No newline at end of file + + # 返回需要的操作次数 + return [n1 + n2, m1 + m2] diff --git a/solutions/python3/1034.py b/solutions/python3/1034.py index 774c8b9..01c05c0 100644 --- a/solutions/python3/1034.py +++ b/solutions/python3/1034.py @@ -1,19 +1,46 @@ + class Solution: def colorBorder(self, grid: List[List[int]], r0: int, c0: int, color: int) -> List[List[int]]: + """ + Solution class for coloring the border of a given cell in a grid. + + Parameters: + - grid (List[List[int]]): The input grid. + - r0 (int): Row index of the starting cell. + - c0 (int): Column index of the starting cell. + - color (int): New color to be applied. + + Returns: + - List[List[int]]: The updated grid with colored borders. + """ + def dfs(i, j): + # 记录已访问的单元格 seen.add((i, j)) - if not (0 < i < m - 1 and 0 < j < n - 1 and grid[i - 1][j] == grid[i + 1][j] == grid[i][j - 1] == grid[i][j + 1] == grid[i][j]): + # 如果当前单元格不是目标颜色或周围没有完全相同的目标颜色,则着色 + if not (0 < i < m - 1 and 0 < j < n - 1 and grid[i - 1][j] == grid[i + 1][j] == grid[i][j - 1] == grid[i][j + 1] == self.tar): matrix[i][j] = 0 + # 遍历当前单元格的四个方向 for x, y in (i - 1, j), (i + 1, j), (i, j - 1), (i, j + 1): if 0 <= x < m and 0 <= y < n and grid[x][y] == self.tar and (x, y) not in seen: dfs(x, y) + + # 获取网格的行数和列数 m, n = len(grid), len(grid[0]) + # 记录已访问的单元格 seen = set() + # 目标颜色 self.tar = grid[r0][c0] + # 深拷贝原始网格用于着色 matrix = [row[:] for row in grid] + + # 从起始点进行深度优先搜索 dfs(r0, c0) + + # 遍历更新后的矩阵,对边界单元格进行颜色填充 for i in range(m): for j in range(n): if not matrix[i][j]: matrix[i][j] = color - return matrix \ No newline at end of file + + return matrix diff --git a/solutions/python3/1035.py b/solutions/python3/1035.py index 935d7bb..28b30d5 100644 --- a/solutions/python3/1035.py +++ b/solutions/python3/1035.py @@ -1,7 +1,23 @@ + class Solution: def maxUncrossedLines(self, A: List[int], B: List[int]) -> int: + """ + 使用动态规划解决最长公共子序列问题,从而计算最大不相交线的数量。 + + :param A: List[int], 第一个整数数组 + :param B: List[int], 第二个整数数组 + :return: int, 最大不相交线数量 + + 例如: + A = [1,4,2] + B = [1,2,4] + 返回结果为: 2 + """ + dp, m, n = collections.defaultdict(int), len(A), len(B) + # 动态规划表初始化 for i in range(m): for j in range(n): + # 计算当前位置的最大值,考虑匹配与否 dp[i, j] = max(dp[i - 1, j - 1] + (A[i] == B[j]), dp[i - 1, j], dp[i, j - 1]) - return dp[m - 1, n - 1] \ No newline at end of file + return dp[m - 1, n - 1] diff --git a/solutions/python3/1036.py b/solutions/python3/1036.py index 7682b31..144120d 100644 --- a/solutions/python3/1036.py +++ b/solutions/python3/1036.py @@ -1,26 +1,56 @@ + class Solution: def isEscapePossible(self, blocked: List[List[int]], source: List[int], target: List[int]) -> bool: - if not blocked: return True + """ + 判断是否可以从source节点逃到target节点,给定被阻塞的区域blocked。 + + 参数: + blocked: 被阻塞的格子列表 + source: 源点坐标 [x, y] + target: 目标点坐标 [x, y] + + 返回值: + 如果可以从source逃到target,返回True;否则返回False。 + """ + + if not blocked: + return True # 若没有被阻塞的区域,则可以直接到达目标 blocked = set(map(tuple, blocked)) - def check(blocked, source, target): - si, sj = source - ti, tj = target + def check(blocked, start: List[int], end: List[int]) -> bool: + """ + 检查从start是否能到达end + + 参数: + blocked: 被阻塞的格子列表 + start: 当前节点坐标 [x, y] + end: 目标点坐标 [x, y] + + 返回值: + 如果可以从start逃到end,返回True;否则返回False。 + """ + + si, sj = start # 起始位置 + ti, tj = end # 结束位置 + level = 0 - q = collections.deque([(si,sj)]) - vis = set() + q = collections.deque([(si,sj)]) # 队列用于BFS + vis = set() # 记录已访问的格子 while q: for _ in range(len(q)): - i,j = q.popleft() - if i == ti and j == tj: return True - for x,y in ((i+1,j),(i-1,j),(i,j+1),(i,j-1)): - if 0<=x<10**6 and 0<=y<10**6 and (x,y) not in vis and (x,y) not in blocked: - vis.add((x,y)) - q.append((x,y)) + i, j = q.popleft() + if i == ti and j == tj: return True # 到达目标点,返回True + + for x, y in ((i+1,j),(i-1,j),(i,j+1),(i,j-1)): # 遍历四个方向 + if (0<=x<10**6) and (0<=y<10**6) and \ + (x,y) not in vis and (x,y) not in blocked: + vis.add((x,y)) # 标记已访问 + q.append((x,y)) # 入队 + level += 1 - if level == len(blocked): break - else: - return False - return True + if level == len(blocked): break # 若访问的步数达到被阻塞格子的数量,提前终止 + + else: # 当while循环正常结束(非break) + return False # 没有到达目标点 - return check(blocked, source, target) and check(blocked, target, source) \ No newline at end of file + return check(blocked, source, target) and check(blocked, target, source) diff --git a/solutions/python3/1037.py b/solutions/python3/1037.py index 4ef852d..88e489d 100644 --- a/solutions/python3/1037.py +++ b/solutions/python3/1037.py @@ -1,3 +1,5 @@ + class Solution: + # 检查三个点是否能组成一个boomerang(非共线) def isBoomerang(self, p: List[List[int]]) -> bool: - return (p[0][0] - p[1][0]) * (p[0][1] - p[2][1]) != (p[0][0] - p[2][0]) * (p[0][1] - p[1][1]) \ No newline at end of file + return (p[0][0] - p[1][0]) * (p[0][1] - p[2][1]) != (p[0][0] - p[2][0]) * (p[0][1] - p[1][1]) diff --git a/solutions/python3/1038.py b/solutions/python3/1038.py index 0edb15b..14a1ed4 100644 --- a/solutions/python3/1038.py +++ b/solutions/python3/1038.py @@ -1,7 +1,30 @@ + class Solution: + # Initialize the class-level variable to store the accumulated value val = 0 + def bstToGst(self, root): - if root.right: self.bstToGst(root.right) + """ + Convert a BST (Binary Search Tree) into Greater Sum Tree in-place. + + :param root: TreeNode representing the root of the BST + :return: TreeNode representing the root of the converted Greater Sum Tree + + 中文注释: + 将二叉搜索树转换为累加树(Greater Sum Tree),在原地进行。 + + :参数 root: 代表BST根节点的TreeNode对象 + :返回值: 转换后的累加树根节点对应的TreeNode对象 + """ + # Recursively traverse the right subtree first, as it contains larger values + if root.right: + self.bstToGst(root.right) + + # Update the current node's value to be the sum of its original value and accumulated value root.val = self.val = self.val + root.val - if root.left: self.bstToGst(root.left) - return root \ No newline at end of file + + # Recursively traverse the left subtree, which will contain smaller or equal values + if root.left: + self.bstToGst(root.left) + + return root diff --git a/solutions/python3/1039.py b/solutions/python3/1039.py index 23d996f..c97d449 100644 --- a/solutions/python3/1039.py +++ b/solutions/python3/1039.py @@ -1,8 +1,36 @@ + class Solution: + # 定义一个解决方案类 + def minScoreTriangulation(self, A: List[int]) -> int: + """ + 计算将给定的三角形顶点A进行最优三角剖分后的最小得分。 + + 参数: + A (List[int]): 三角形的顶点数组 + + 返回值: + int: 最小得分 + """ memo = {} + # 使用字典存储已经计算过的子问题结果,避免重复计算 + def dp(i, j): + """ + 动态规划函数,用于计算从索引i到j之间的最优三角剖分的最小得分。 + + 参数: + i (int): 当前考虑的起始顶点 + j (int): 当前考虑的结束顶点 + + 返回值: + int: 从i到j间的最小得分 + """ if (i, j) not in memo: + # 如果(i,j)不在memo中,表示还未计算过该子问题 memo[i, j] = min([dp(i, k) + dp(k, j) + A[i] * A[j] * A[k] for k in range(i + 1, j)] or [0]) + # 对于所有可能的分割点k,递归计算最小得分并存储在memo中 return memo[i, j] - return dp(0, len(A) - 1) \ No newline at end of file + # 调用dp函数从索引0到len(A)-1开始计算总最小得分 + + return dp(0, len(A) - 1) diff --git a/solutions/python3/104.py b/solutions/python3/104.py index 0f3a52f..04f4bce 100644 --- a/solutions/python3/104.py +++ b/solutions/python3/104.py @@ -1,10 +1,13 @@ + # Definition for a binary tree node. -# class TreeNode: -# def __init__(self, x): -# self.val = x -# self.left = None -# self.right = None +class TreeNode: + def __init__(self, x): + self.val = x + self.left = None + self.right = None class Solution: - def maxDepth(self, root: TreeNode, d = 0) -> int: - return max(self.maxDepth(root.left, d + 1), self.maxDepth(root.right, d + 1)) if root else d \ No newline at end of file + # 计算二叉树的最大深度 + def maxDepth(self, root: TreeNode, depth=0) -> int: + # 如果节点不为空,则递归计算左右子树的深度,并取较大值加一;否则返回当前深度 + return max(self.maxDepth(root.left, depth + 1), self.maxDepth(root.right, depth + 1)) if root else depth diff --git a/solutions/python3/1040.py b/solutions/python3/1040.py index 87d9c10..e9f12f4 100644 --- a/solutions/python3/1040.py +++ b/solutions/python3/1040.py @@ -1,12 +1,31 @@ + class Solution: + # 定义一个类来解决石头移动问题 + def numMovesStonesII(self, A: List[int]) -> List[int]: + """ + :param A: 石头的位置列表,整数类型 + :return: 两个元素的列表,分别表示最少和最多需要移动的次数 + """ + + # 对石头位置进行排序 A.sort() - i, n, low = 0, len(A), len(A) - high = max(A[-1] - n + 2 - A[1], A[-2] - A[0] - n + 2) + + n = len(A) + low, high = n, max(A[-1] - A[0] + 1 - n, A[-2] - A[1] + 1) + + # 初始化滑动窗口的左右边界,low表示最少移动次数,high表示最多移动次数 + i = 0 + + # 滑动窗口右移,找到最少和最多的移动次数 for j in range(n): - while A[j] - A[i] >= n: i += 1 + while A[j] - A[i] >= n: + i += 1 if j - i + 1 == n - 1 and A[j] - A[i] == n - 2: + # 如果窗口内的石头数量为n-1且间隔正好为n-2,则最少移动次数为2 low = min(low, 2) else: + # 计算最少移动次数 low = min(low, n - (j - i + 1)) - return [low, high] \ No newline at end of file + + return [low, high] diff --git a/solutions/python3/1041.py b/solutions/python3/1041.py index 9c7c1fa..27bd254 100644 --- a/solutions/python3/1041.py +++ b/solutions/python3/1041.py @@ -1,13 +1,33 @@ + class Solution: def isRobotBounded(self, instructions: str) -> bool: + """ + 判断机器人在给定指令后是否会回到原点。 + + :param instructions: 字符串,包含'G','L','R'三种指令 + 'G': 前进一格 + 'L': 左转90度 + 'R': 右转90度 + :return: 如果机器人在执行完所有指令后回到原点返回True, 否则返回False + + 机器人的初始方向是北,使用(dx, dy)表示当前方向。 + 为了简化代码逻辑,在四个周期内重复执行给定的指令集。 + 最终检查机器人的位置是否回到了(0, 0),且方向与初始一致。 + """ x, y, dx, dy = 0, 0, 0, 1 + + # 循环四次,确保模拟完整周期 for _ in range(4): for ins in instructions: if ins == 'G': + # 前进一格 x += dx y += dy elif ins == 'L': + # 左转90度 dx, dy = -dy, dx else: + # 右转90度 dx, dy = dy, -dx - return x == y == 0 \ No newline at end of file + + return x == 0 and y == 0 diff --git a/solutions/python3/1042.py b/solutions/python3/1042.py index a23604f..4c5b4b9 100644 --- a/solutions/python3/1042.py +++ b/solutions/python3/1042.py @@ -1,10 +1,24 @@ + class Solution: + # 定义一个解决方案类 + def gardenNoAdj(self, N: int, paths: List[List[int]]) -> List[int]: - res = [0] * N - G = [[] for i in range(N)] + """ + :param N: 花园的数量 + :param paths: 两个花园之间路径的列表,每个元素是一个包含两个整数的列表[x, y]表示x和y直接有一条路径相连 + :return: 返回一个长度为N的列表,表示每个花园种植的不同花的颜色编号(1-4) + """ + + res = [0] * N # 初始化结果列表,初始值为0 + G = [[] for i in range(N)] # 构建邻接表,用于存储每朵花相邻的其他花朵 + + # 遍历路径列表,构建邻接表 for x, y in paths: G[x - 1].append(y - 1) G[y - 1].append(x - 1) + + # 对每个花园,选择未使用的颜色填充到结果中 for i in range(N): res[i] = ({1, 2, 3, 4} - {res[j] for j in G[i]}).pop() - return res \ No newline at end of file + + return res # 返回结果列表 diff --git a/solutions/python3/1043.py b/solutions/python3/1043.py index 74cf0db..ead90dd 100644 --- a/solutions/python3/1043.py +++ b/solutions/python3/1043.py @@ -1,10 +1,21 @@ + class Solution: + # 定义一个类,用于解决给定数组A在分割K个子区间后的最大和问题 + def maxSumAfterPartitioning(self, A: List[int], K: int) -> int: N = len(A) + # 初始化动态规划表dp,大小为N+K dp = [0] * (N + K) + for i in range(N): + # 当前最大值初始化为0 curMax = 0 + # 遍历可能的分割长度k,范围从1到min(K, i+1) for k in range(1, min(K, i + 1) + 1): + # 更新当前子区间内的最大值 curMax = max(curMax, A[i - k + 1]) + # 动态规划更新:选择当前分割方式的最大收益 dp[i] = max(dp[i], dp[i - k] + curMax * k) - return dp[N - 1] \ No newline at end of file + + # 返回最终结果,即dp[N-1] + return dp[N - 1] diff --git a/solutions/python3/1044.py b/solutions/python3/1044.py index dd37ec1..837c939 100644 --- a/solutions/python3/1044.py +++ b/solutions/python3/1044.py @@ -1,17 +1,28 @@ + from functools import reduce + +# Solution class to find the longest duplicate substring in a given string class Solution: def longestDupSubstring(self, S: str) -> str: + # Convert each character in S to its corresponding integer value (0-25) A = [ord(c) - ord('a') for c in S] mod = 2**63 - 1 + # Function to test if a substring of length L is duplicated def test(L): + # Calculate the base power needed for hashing p = pow(26, L, mod) + # Hash value of the first L characters cur = reduce(lambda x, y: (x * 26 + y) % mod, A[:L], 0) seen = {cur} for i in range(L, len(S)): + # Update hash value as we move one character forward cur = (cur * 26 + A[i] - A[i - L] * p) % mod if cur in seen: return i - L + 1 seen.add(cur) + return None + + # Binary search for the longest duplicated substring length res, lo, hi = 0, 0, len(S) while lo < hi: mi = (lo + hi + 1) // 2 @@ -21,4 +32,6 @@ def test(L): res = pos else: hi = mi - 1 - return S[res:res + lo] \ No newline at end of file + + # Return the longest duplicated substring found + return S[res:res + lo] diff --git a/solutions/python3/1046.py b/solutions/python3/1046.py index 68f260c..fbefa9f 100644 --- a/solutions/python3/1046.py +++ b/solutions/python3/1046.py @@ -1,6 +1,30 @@ + class Solution: + """ + 解决方案类,用于实现计算最后剩余石块重量的方法。 + + :param stones: List[int], 表示初始的石块列表 + :return: int, 返回最后剩下的石块的重量,如果为空则返回0 + """ + def lastStoneWeight(self, stones: List[int]) -> int: - stones.sort() + """ + 计算最后一颗剩余的石块的重量。 + + 方法逻辑: + 1. 首先对所有石块进行排序。 + 2. 然后不断从列表中取出两个最大的石块,计算它们之间的差值并插入回原列表。 + 3. 重复上述过程直到只剩下一个或没有石块为止。 + 4. 返回剩余的石块重量。 + + :param stones: List[int], 排序后的石块列表 + :return: int, 剩余石块的重量 + """ + stones.sort() # 对石块进行排序 + for _ in range(len(stones) - 1): - bisect.insort(stones, stones.pop() - stones.pop()) - return stones[0] \ No newline at end of file + # 取出两个最大的石块,计算差值,并将差值插入回列表中 + diff = stones.pop() - stones.pop() + bisect.insort(stones, diff) + + return stones[0] if stones else 0 # 返回剩余的石块重量,如果为空则返回0 diff --git a/solutions/python3/1047.py b/solutions/python3/1047.py index 386d02b..5d789e6 100644 --- a/solutions/python3/1047.py +++ b/solutions/python3/1047.py @@ -1,9 +1,15 @@ + class Solution: + # 解决器类 + def removeDuplicates(self, S: str) -> str: - stack = [] - for s in S: - if stack and stack[-1] == s: - stack.pop() + # 移除字符串中的重复字符 + stack = [] # 初始化栈 + + for s in S: # 遍历输入字符串S的每一个字符s + if stack and stack[-1] == s: # 如果栈顶元素和当前字符相同 + stack.pop() # 弹出栈顶元素 else: - stack.append(s) - return ''.join(stack) \ No newline at end of file + stack.append(s) # 否则将当前字符压入栈中 + + return ''.join(stack) # 将栈中的字符拼接成字符串并返回 diff --git a/solutions/python3/1048.py b/solutions/python3/1048.py index 029a553..e3fe723 100644 --- a/solutions/python3/1048.py +++ b/solutions/python3/1048.py @@ -1,13 +1,23 @@ + class Solution: def longestStrChain(self, words: List[str]) -> int: + # 使用深度优先搜索,从某个单词出发找到最长的单词链长度 def dfs(w1, size): return max([dfs(w2, size + 1) for w2 in graph[w1]], default = size) - graph = collections.defaultdict(list) + + from collections import defaultdict + + # 构建一个图结构,节点是按单词长度分组后的列表 + graph = defaultdict(list) for w in words: graph[len(w)].append(w) + + # 填充图结构:对于每个单词w1,在比其长的单词中查找可能的前驱 for w1 in words: for w2 in graph[len(w1) + 1]: for i in range(len(w2)): if w2[:i] + w2[i + 1:] == w1: graph[w1].append(w2) - return max(dfs(w, 1) for w in words) \ No newline at end of file + + # 计算每个单词的最长链长度,返回其中的最大值 + return max(dfs(w, 1) for w in words) diff --git a/solutions/python3/1049.py b/solutions/python3/1049.py index 8ef004a..e4ee18c 100644 --- a/solutions/python3/1049.py +++ b/solutions/python3/1049.py @@ -1,7 +1,22 @@ + class Solution: + # 定义一个名为Solution的类,包含用于解决问题的方法 + def lastStoneWeightII(self, A: List[int]) -> int: + # 定义一个方法lastStoneWeightII,接收一个整数列表A作为参数,返回一个整数值 + dp = {0} + # 初始化动态规划集合dp为只包含元素0的集合 + sumA = sum(A) + # 计算输入列表A中所有元素之和,并存储在sumA变量中 + for a in A: + # 遍历列表A中的每个元素a + dp |= {a + i for i in dp} - return min(abs(sumA - i - i) for i in dp) \ No newline at end of file + # 对于dp集合中的每一个i,计算a+i并将其添加到dp集合中 + # 使用对集操作(|)来合并两个集合,并将结果存储回dp + + return min(abs(sumA - i - i) for i in dp) + # 返回集合dp中所有元素的两倍与sumA之差的绝对值中的最小值 diff --git a/solutions/python3/105.py b/solutions/python3/105.py index 42e88f1..6ba1ffa 100644 --- a/solutions/python3/105.py +++ b/solutions/python3/105.py @@ -1,8 +1,29 @@ + class Solution(object): + """ + Definition for a binary tree node. + """ + class TreeNode: + def __init__(self, x): + self.val = x + self.left = None + self.right = None + + """ + 构建二叉树的方法。 + + 根据前序遍历和中序遍历来构建二叉树。 + """ + def buildTree(self, preorder, inorder): + # 如果中序遍历列表不为空 if inorder: + # 找到当前根节点在中序遍历中的索引位置 ind = inorder.index(preorder.pop(0)) - root = TreeNode(inorder[ind]) + # 创建根节点 + root = self.TreeNode(inorder[ind]) + # 递归构建左子树 root.left = self.buildTree(preorder, inorder[0:ind]) + # 递归构建右子树 root.right = self.buildTree(preorder, inorder[ind+1:]) - return root \ No newline at end of file + return root diff --git a/solutions/python3/1051.py b/solutions/python3/1051.py index c4bac9e..adb2c31 100644 --- a/solutions/python3/1051.py +++ b/solutions/python3/1051.py @@ -1,3 +1,7 @@ + class Solution: + # 计算期望高度与实际高度不匹配的儿童数量 + def heightChecker(self, heights: List[int]) -> int: - return sum(h1 != h2 for h1, h2 in zip(heights, sorted(heights))) \ No newline at end of file + # 使用生成器表达式,比较原始高度和排序后高度的差异,并求和 + return sum(h1 != h2 for h1, h2 in zip(heights, sorted(heights))) diff --git a/solutions/python3/1052.py b/solutions/python3/1052.py index 646864d..ec43463 100644 --- a/solutions/python3/1052.py +++ b/solutions/python3/1052.py @@ -1,7 +1,13 @@ + class Solution: def maxSatisfied(self, customers: List[int], grumpy: List[int], x: int) -> int: + # 计算初始窗口内的满足顾客数量 dif = mx = sum(c * g for c, g in zip(customers[:x], grumpy[:x])) + + # 遍历剩余的grumpy数组,更新最大差值和滑动窗口 for j in range(x, len(grumpy)): dif += (grumpy[j] * customers[j]) - (grumpy[j - x] * customers[j - x]) mx = max(mx, dif) - return mx + sum(c * (1- g) for c, g in zip(customers, grumpy)) \ No newline at end of file + + # 返回初始满足顾客数量与非愤怒时段的满足顾客数量之和 + return mx + sum(c * (1- g) for c, g in zip(customers, grumpy)) diff --git a/solutions/python3/1053.py b/solutions/python3/1053.py index e2fd673..a8d15db 100644 --- a/solutions/python3/1053.py +++ b/solutions/python3/1053.py @@ -1,10 +1,21 @@ + class Solution: + # 定义一个类用于处理排列问题 + def prevPermOpt1(self, A: List[int]) -> List[int]: + # 目标是找到前一个字典序的排列并进行一次交换 + pre = [] for i in range(len(A) - 1, -1, -1): + # 反向遍历数组A bisect.insort_left(pre, (A[i], i)) + # 将当前元素及其索引插入到有序列表pre中保持升序 + if pre.index((A[i], i)): + # 如果当前元素在有序列表中有重复,则跳过 j = pre[pre.index((A[i], i)) - 1][1] A[i], A[j] = A[j], A[i] + # 找到前一个较小的元素并与其交换位置,以形成前一个字典序排列 break - return A \ No newline at end of file + return A + # 返回修改后的数组 diff --git a/solutions/python3/1054.py b/solutions/python3/1054.py index 416118d..6e06078 100644 --- a/solutions/python3/1054.py +++ b/solutions/python3/1054.py @@ -1,9 +1,26 @@ + class Solution: def rearrangeBarcodes(self, barcodes: List[int]) -> List[int]: - cnt = collections.Counter(barcodes).most_common()[::-1] + """ + 使用计数器统计每个条形码的出现次数,按降序排列。 + + :param barcodes: 列表形式的条形码数字 + :return: 重新安排后的条形码列表 + + 中文注释: + - 使用 collections.Counter 统计条形码出现频率,并按降序排序。 + - 将频率较高的条形码先加入到临时列表 ref 中,方便后续间隔放置。 + - 遍历原列表,偶数位置填入高频条形码,奇数位置填入剩余的低频条形码。 + """ + + from collections import Counter + cnt = Counter(barcodes).most_common()[::-1] ref = [val for val, t in cnt for _ in range(t)] + + # 交替放置高频率和低频率的条形码到原列表中 for i in range(0, len(barcodes), 2): barcodes[i] = ref.pop() for i in range(1, len(barcodes), 2): barcodes[i] = ref.pop() - return barcodes \ No newline at end of file + + return barcodes diff --git a/solutions/python3/1055.py b/solutions/python3/1055.py index c42a29a..fa1d02a 100644 --- a/solutions/python3/1055.py +++ b/solutions/python3/1055.py @@ -1,12 +1,27 @@ + class Solution: + # 定义一个类来解决问题 + def shortestWay(self, source: str, target: str) -> int: + # 初始化计数器和源字符串索引位置 cnt = i = 0 + + # 遍历目标字符串中的每个字符 for t in target: + # 在源字符串中寻找当前的目标字符,从上一次找到的位置开始 i = source.find(t, i) + + # 如果找不到该字符,则从源字符串的开头重新查找 if i == -1: i = source.find(t, 0) + + # 如果在源字符串中也找不到目标字符,则返回-1表示无法匹配 if i == -1: return -1 + + # 找到新起点后,重置索引位置并增加计数器 cnt += 1 - i += 1 - return cnt + 1 \ No newline at end of file + i = 0 + + # 返回最小路径次数加上一次初始匹配操作 + return cnt + 1 diff --git a/solutions/python3/1056.py b/solutions/python3/1056.py index fb23990..a10d476 100644 --- a/solutions/python3/1056.py +++ b/solutions/python3/1056.py @@ -1,4 +1,9 @@ + class Solution: + # 判断给定整数N是否为混淆数字,即反转后映射的数字与原数字不同且不是合法数字 def confusingNumber(self, N: int) -> bool: + # 反转字符串并替换字符:0->0,1->1,9->6,8->8,6->9,其它字符(#)表示非法数字 ret = ''.join("01####9#86"[int(n)] for n in str(N)[::-1]) - return '#' not in ret and ret != str(N) \ No newline at end of file + + # 检查替换后的字符串是否包含非法字符且与原字符串不同 + return '#' not in ret and ret != str(N) diff --git a/solutions/python3/1057.py b/solutions/python3/1057.py index c720606..5b3282d 100644 --- a/solutions/python3/1057.py +++ b/solutions/python3/1057.py @@ -1,10 +1,20 @@ + class Solution: + # 定义解决方案类 + def assignBikes(self, W: List[List[int]], B: List[List[int]]) -> List[int]: + # 初始化结果数组和已使用车辆集合 ans, used = [-1] * len(W), set() + + # 对每个工人与每辆自行车的距离进行排序 for d, w, b in sorted([abs(W[i][0] - B[j][0]) + abs(W[i][1] - B[j][1]), i, j] for i in range(len(W)) for j in range(len(B))): + # 如果当前工人未分配且自行车未被使用,则进行分配 if ans[w] == -1 and b not in used: ans[w] = b used.add(b) + + # 若所有工人已成功分配,提前结束循环 if len(used) == len(ans): break - return ans \ No newline at end of file + + return ans # 返回结果数组 diff --git a/solutions/python3/1058.py b/solutions/python3/1058.py index ce1fc67..7d1d4dd 100644 --- a/solutions/python3/1058.py +++ b/solutions/python3/1058.py @@ -1,8 +1,26 @@ + class Solution: def minimizeError(self, prices: List[str], target: int) -> str: + # 将价格列表转换为浮点数 + # Convert the list of string prices to float prices = [float(p) for p in prices] + + # 计算所有整数部分之和 + # Calculate the sum of integer parts sm = sum(math.floor(p) for p in prices) - prices = sorted(p - math.floor(p) for p in prices if p - math.floor(p)) + + # 将非零小数部分按从小到大排序 + # Sort non-zero fractional parts from smallest to largest + prices = sorted([p - math.floor(p) for p in prices if p - math.floor(p)]) + + # 如果整数部分之和大于目标值,或目标值与整数部分之和的差大于非零小数部分的数量,则返回-1 + # If the sum of integer parts is greater than the target, or the difference between the target and the sum of integer parts is greater than the number of non-zero fractional parts, return "-1" if sm > target or target - sm > len(prices): return "-1" - return "{:.3f}".format(sum([p - math.floor(p) for p in prices[:sm - target]]) + sum([math.ceil(p) - p for p in prices[sm - target:]])) \ No newline at end of file + + # 计算需要调整的小数部分以达到目标值 + # Calculate the fractional parts to be adjusted to reach the target value + return "{:.3f}".format( + sum([p - math.floor(p) for p in prices[:sm - target]]) + + sum([(math.ceil(p) - p) for p in prices[sm - target:]]) + ) diff --git a/solutions/python3/1059.py b/solutions/python3/1059.py index df1bebe..2bf53a5 100644 --- a/solutions/python3/1059.py +++ b/solutions/python3/1059.py @@ -1,14 +1,30 @@ + class Solution: def leadsToDestination(self, n: int, edges: List[List[int]], source: int, destination: int) -> bool: + """ + 判断从source出发是否可以到达destination,且路径上不能有环。 + + 中文解释:判断从给定起点到终点是否存在一条路径,并确保这条路径是有效的(即没有形成环)。 + """ + def dfs(i): + """ + 深度优先搜索函数 + + 参数: + i (int): 当前节点的索引 + 返回: + bool: 是否存在从i出发能到达destination且不形成环的路径 + """ seen.add(i) for j in graph[i]: if j == i or j in seen or not dfs(j): return False seen.discard(i) + # 如果当前节点没有出边,或者该节点就是目的地,则返回True return len(graph[i]) != 0 or i == destination + graph, seen = collections.defaultdict(set), set() for a, b in edges: graph[a].add(b) return dfs(source) - \ No newline at end of file diff --git a/solutions/python3/106.py b/solutions/python3/106.py index b73124b..9462fe3 100644 --- a/solutions/python3/106.py +++ b/solutions/python3/106.py @@ -1,8 +1,16 @@ + class Solution: - def buildTree(self, inorder, postorder): + # 构建二叉树的递归函数,输入中序遍历和后序遍历的结果列表 + def buildTree(self, inorder: List[int], postorder: List[int]) -> TreeNode: if inorder: + # 找到当前根节点在中序遍历中的索引位置,并弹出后序遍历中的最后一个元素作为当前子树的根节点值 ind = inorder.index(postorder.pop()) + + # 递归构建右子树,左闭右开区间 [ind+1:] 表示从索引 ind+1 开始到末尾 root = TreeNode(inorder[ind]) root.right = self.buildTree(inorder[ind+1:], postorder) + + # 递归构建左子树,左闭右闭区间 [:ind] 表示从起始到索引 ind-1 结束 root.left = self.buildTree(inorder[:ind], postorder) - return root \ No newline at end of file + + return root diff --git a/solutions/python3/1060.py b/solutions/python3/1060.py index f038b82..66df151 100644 --- a/solutions/python3/1060.py +++ b/solutions/python3/1060.py @@ -1,10 +1,26 @@ + class Solution: + # 定义一个类,用于解决缺失元素的问题 + def missingElement(self, nums: List[int], k: int) -> int: - cur = nums[0] + """ + :param nums: 一个整数列表 + :param k: 一个正整数,表示需要找到的第k个缺失值的位置 + :return: 返回缺失的第k个元素 + + 思路:通过遍历数组,计算相邻元素之间的缺失值数量,逐步逼近目标位置。 + """ + + cur = nums[0] # 初始化当前值为第一个元素 + for num in nums[1:]: + # 遍历数组中的每个元素 if num - cur - 1 >= k: + # 如果当前元素和cur之间缺失的元素数量大于等于k,则跳出循环 break else: + # 否则,更新需要找的第k个缺失值的位置 k -= num - cur - 1 - cur = num - return cur + k \ No newline at end of file + cur = num # 更新当前值为当前遍历到的数 + + return cur + k # 返回结果 diff --git a/solutions/python3/1061.py b/solutions/python3/1061.py index eb9b07d..7a4d649 100644 --- a/solutions/python3/1061.py +++ b/solutions/python3/1061.py @@ -1,12 +1,19 @@ + class Solution: - def smallestEquivalentString(self, A: str, B: str, S: str) -> str: - def root(c): - return c if parent[c] == c else root(parent[c]) - parent = {s: s for s in string.ascii_lowercase} - for a, b in zip(A, B): - p1, p2 = root(a), root(b) - if p1 <= p2: - parent[p2] = p1 - else: - parent[p1] = p2 - return ''.join(root(s) for s in S) \ No newline at end of file + # 定义查找根节点的函数,返回给定字符对应的最小等价类代表字母 + def root(self, c: str) -> str: + return c if parent[c] == c else self.root(parent[c]) + + # 初始化每个小写字母为其自身父节点 + parent = {s: s for s in string.ascii_lowercase} + + # 遍历字符串A和B,合并它们对应的等价类 + for a, b in zip(A, B): + p1, p2 = self.root(a), self.root(b) + if p1 <= p2: + parent[p2] = p1 # 将较大的等价类的父节点设为较小的等价类的根节点 + else: + parent[p1] = p2 + + # 遍历字符串S,返回每个字符对应的最小等价类代表字母构成的新字符串 + return ''.join(self.root(s) for s in S) diff --git a/solutions/python3/1062.py b/solutions/python3/1062.py index 1ef8dcc..6e9dc49 100644 --- a/solutions/python3/1062.py +++ b/solutions/python3/1062.py @@ -1,12 +1,21 @@ + class Solution: + # 定义一个类来解决最长重复子串问题 + def longestRepeatingSubstring(self, S: str) -> int: - for l in range(len(S), 0, -1): - s = S[:l] - seen = {s} - for j in range(l, len(S)): - s = s[1:] + S[j] - if s in seen: - return l - seen.add(s) + # 从字符串的长度开始,逐步减少长度进行搜索 + for length in range(len(S), 0, -1): + current_substring = S[:length] + seen_substrings = {current_substring} + + # 检查剩余部分中是否存在与当前子串匹配的部分 + for j in range(length, len(S)): + current_substring = current_substring[1:] + S[j] + + if current_substring in seen_substrings: + return length + + seen_substrings.add(current_substring) + + # 如果没有找到重复子串,返回0 return 0 - \ No newline at end of file diff --git a/solutions/python3/1063.py b/solutions/python3/1063.py index f7d8295..7978838 100644 --- a/solutions/python3/1063.py +++ b/solutions/python3/1063.py @@ -1,9 +1,18 @@ + class Solution: + # 定义一个解决方案类 + def validSubarrays(self, nums: List[int]) -> int: + # 初始化栈和结果计数器 stack, res = [], 0 + for num in nums: + # 当前数字与栈顶元素比较,维护单调递增的栈 while stack and stack[-1] > num: stack.pop() + # 将当前数字压入栈中 stack.append(num) + # 累加当前栈长度到结果计数器 res += len(stack) - return res \ No newline at end of file + + return res # 返回最终的结果计数器值 diff --git a/solutions/python3/1064.py b/solutions/python3/1064.py index 9c2745d..844de1c 100644 --- a/solutions/python3/1064.py +++ b/solutions/python3/1064.py @@ -1,3 +1,6 @@ + class Solution: + # 定义一个查找固定点的方法,输入是一个整数列表A,输出是第一个固定点的索引或-1 def fixedPoint(self, A: List[int]) -> int: - return ([i for i in range(len(A)) if A[i] == i] + [-1])[0] \ No newline at end of file + # 使用列表生成式找到所有满足条件的固定点索引,如果找不到则返回-1 + return ([i for i in range(len(A)) if A[i] == i] + [-1])[0] diff --git a/solutions/python3/1065.py b/solutions/python3/1065.py index 22a0572..9465dc3 100644 --- a/solutions/python3/1065.py +++ b/solutions/python3/1065.py @@ -1,3 +1,12 @@ + class Solution: + # 中文注释:实现 indexPairs 方法,输入为字符串 text 和单词列表 words, + # 输出所有可能的 [起始索引, 结束索引] 对,使得 text 的子串等于 words 中的一个单词。 + # 英文注释: Implement the indexPairs method which takes a string 'text' and a list of strings 'words', + # and returns all possible [start_index, end_index] pairs such that the substring in 'text' equals one of the words in 'words'. + def indexPairs(self, text: str, words: List[str]) -> List[List[int]]: - return [[i, j] for i in range(len(text)) for j in range(i, len(text)) if text[i:j + 1] in words] \ No newline at end of file + # 中文注释:使用列表推导式生成所有可能的子串索引对 + # 英文注释: Use list comprehension to generate all possible substring index pairs. + return [[i, j] for i in range(len(text)) + for j in range(i, len(text)) if text[i:j + 1] in words] diff --git a/solutions/python3/1066.py b/solutions/python3/1066.py index d5690b2..94f74ff 100644 --- a/solutions/python3/1066.py +++ b/solutions/python3/1066.py @@ -1,15 +1,28 @@ + class Solution: def assignBikes(self, workers: List[List[int]], bikes: List[List[int]]) -> int: + """ + 计算工人与自行车之间的最短距离。 + + :param workers: 工人位置列表,每个元素表示一个工人的坐标 [x, y] + :param bikes: 自行车位置列表,每个元素表示一辆自行车的坐标 [x, y] + :return: 分配工人和自行车所需的最小成本 + """ + from heapq import heappush, heappop + def dis(i, j): + """计算工人i与自行车j之间的曼哈顿距离""" return abs(workers[i][0] - bikes[j][0]) + abs(workers[i][1] - bikes[j][1]) - h = [[0, 0, 0]] - seen = set() + + h = [[0, 0, 0]] # (成本, 工人索引, 自行车状态) + seen = set() # 记录已访问的状态 while True: - cost, i, taken = heapq.heappop(h) - if (i, taken) in seen: continue + cost, i, taken = heappop(h) + if (i, taken) in seen: + continue seen.add((i, taken)) if i == len(workers): return cost for j in range(len(bikes)): - if taken & (1 << j) == 0: - heapq.heappush(h, [cost + dis(i, j), i + 1, taken | (1 << j)]) \ No newline at end of file + if not taken & (1 << j): # 检查自行车j是否已被分配 + heappush(h, [cost + dis(i, j), i + 1, taken | (1 << j)]) # 更新状态并入堆 diff --git a/solutions/python3/107.py b/solutions/python3/107.py index c296d7c..783e3a8 100644 --- a/solutions/python3/107.py +++ b/solutions/python3/107.py @@ -1,31 +1,54 @@ + # Definition for a binary tree node. -# class TreeNode: -# def __init__(self, x): -# self.val = x -# self.left = None -# self.right = None +class TreeNode: + def __init__(self, x): + self.val = x + self.left = None + self.right = None class Solution: + """ + 该类用于实现二叉树的层次遍历(从底到顶) + + Attributes: + - root: 树的根节点 + """ def levelOrderBottom(self, root): """ - :type root: TreeNode - :rtype: List[List[int]] - """ + 使用广度优先搜索实现二叉树的层次遍历,并将结果逆序返回 + + Args: + :type root: TreeNode 根节点 + + Returns: + List[List[int]] 返回从底到顶每层结点值组成的二维列表 + """ from collections import deque if root is None: return [] - levels=list() - q=deque([root]) + + # 用于存储每一层的节点值 + levels = list() + # 队列,初始化时加入根节点 + q = deque([root]) + + # 将第一层的节点值添加到levels中 levels.append([i.val for i in q]) - target=root + + # 使用目标节点target来指示当前层的最后一个结点 + target = root + while q: - node=q.popleft() + node = q.popleft() + if node.left: q.append(node.left) if node.right: q.append(node.right) - if node==target: - if q: - levels.append([i.val for i in q]) - target=q[-1] - return list(reversed(levels)) \ No newline at end of file + + # 如果当前处理的是该层的最后一个结点,将其右子节点加入levels中 + if node == target and q: + levels.append([i.val for i in q]) + target = q[-1] + + return list(reversed(levels)) diff --git a/solutions/python3/1071.py b/solutions/python3/1071.py index 6810911..7b263ba 100644 --- a/solutions/python3/1071.py +++ b/solutions/python3/1071.py @@ -1,11 +1,22 @@ + class Solution: + # 定义一个寻找两个字符串最大公约数的函数,英文:Define a function to find the greatest common divisor of two strings. + def gcdOfStrings(self, str1: str, str2: str) -> str: if len(str1) == len(str2): - return str1 if str1==str2 else '' + # 如果两个字符串长度相同,则返回两者中相等的那个或空字符串,英文:If the lengths of the two strings are equal, return either of them or an empty string. + return str1 if str1 == str2 else '' + + # 如果str1比str2长 + elif len(str1) > len(str2): + # 交换两个字符串位置以便处理,英文:Exchange positions of the two strings to handle. + str1, str2 = str2, str1 + + # 检查前缀是否匹配,英文:Check if the prefix matches. + if str1[:len(str2)] == str2: + # 递归调用自身,继续处理剩余部分,英文:Recursively call itself to process the remaining part. + return self.gcdOfStrings(str1[len(str2):], str2) + else: - if len(str1) < len(str2): - str1,str2 = str2,str1 - if str1[:len(str2)] == str2: - return self.gcdOfStrings(str1[len(str2):],str2) - else: - return '' \ No newline at end of file + # 如果不匹配返回空字符串,英文:Return an empty string if not matched. + return '' diff --git a/solutions/python3/1072.py b/solutions/python3/1072.py index 48f0f59..6593ca6 100644 --- a/solutions/python3/1072.py +++ b/solutions/python3/1072.py @@ -1,8 +1,18 @@ + class Solution: def maxEqualRowsAfterFlips(self, matrix: List[List[int]]) -> int: + """ + 计算在矩阵中通过翻转行操作可以使得相同的最大行数。 + + :param matrix: 二维整数列表,表示输入的矩阵 + :return: 在进行翻转操作后,最多有多少行是相同的 + """ + res = 0 + # 遍历每一行 for row in matrix: + # 获取当前行的反向序列 inv = [1 - r for r in row] + # 检查当前行及其反转行在矩阵中出现的次数,并更新最大值 res = max(res, sum(row == r or inv == r for r in matrix)) return res - \ No newline at end of file diff --git a/solutions/python3/1074.py b/solutions/python3/1074.py index 3977371..f049dbf 100644 --- a/solutions/python3/1074.py +++ b/solutions/python3/1074.py @@ -1,20 +1,30 @@ + class Solution: + # Python 解决方案类 + def numSubmatrixSumTarget(self, matrix: List[List[int]], target: int) -> int: - m, n = len(matrix), len(matrix[0]) + m, n = len(matrix), len(matrix[0]) # 获取矩阵的行数和列数 + + # 对每一行进行前缀和优化 for row in matrix: for i in range(1, n): row[i] += row[i-1] - res = 0 - for i in range(n): - for j in range(i, n): - c = {0:1} - cur = 0 + res = 0 # 结果初始化为0 + # 遍历所有可能的子矩阵列范围 + for left in range(n): # 左边界 + for right in range(left, n): # 右边界,从左边界开始向右扩展 + c = {0:1} # 哈希表记录前缀和出现的次数 + cur = 0 # 当前子矩阵的累计和 + + # 遍历所有行 for row in matrix: - cur += row[j] - (row[i-1] if i else 0) + cur += row[right] - (row[left-1] if left else 0) # 计算当前子矩形单行的和 + # 利用哈希表快速查找是否存在满足条件的前缀和 if cur - target in c: res += c[cur-target] - c[cur] = c.get(cur, 0) + 1 - return res \ No newline at end of file + c[cur] = c.get(cur, 0) + 1 # 更新哈希表 + + return res # 返回结果 diff --git a/solutions/python3/1078.py b/solutions/python3/1078.py index 8cd3b9c..f718157 100644 --- a/solutions/python3/1078.py +++ b/solutions/python3/1078.py @@ -1,4 +1,9 @@ + class Solution: + # 该方法用于查找给定文本中,紧随在特定单词对之后的第三个单词 def findOcurrences(self, text: str, first: str, second: str) -> List[str]: + # 将输入文本按空格分割成列表形式 text = text.split() - return [text[i] for i in range(2, len(text)) if text[i-1] == second and text[i-2] == first] \ No newline at end of file + + # 使用列表推导式找到满足条件的第三词,并返回结果列表 + return [text[i] for i in range(2, len(text)) if text[i-1] == second and text[i-2] == first] diff --git a/solutions/python3/1079.py b/solutions/python3/1079.py index 4091856..4c3f8a2 100644 --- a/solutions/python3/1079.py +++ b/solutions/python3/1079.py @@ -1,3 +1,10 @@ + class Solution: + # 中文注释:定义一个名为Solution的类,包含numTilePossibilities方法用于计算给定瓷砖组合的所有可能排列数量。 + # 英文注释: Define a class named Solution with the method numTilePossibilities to calculate the number of possible permutations of given tiles. + def numTilePossibilities(self, tiles: str) -> int: - return sum(len(set(itertools.permutations(tiles, i))) for i in range(1, len(tiles) + 1)) \ No newline at end of file + # 中文注释:使用itertools.permutations生成给定字符串tiles的所有可能排列组合,并计算长度大于0的组合数量。 + # 英文注释: Use itertools.permutations to generate all possible permutations of the given string tiles and calculate the count of non-empty combinations. + + return sum(len(set(itertools.permutations(tiles, i))) for i in range(1, len(tiles) + 1)) diff --git a/solutions/python3/108.py b/solutions/python3/108.py index 4234050..5a25381 100644 --- a/solutions/python3/108.py +++ b/solutions/python3/108.py @@ -1,19 +1,28 @@ + # Definition for a binary tree node. -# class TreeNode: -# def __init__(self, x): -# self.val = x -# self.left = None -# self.right = None +class TreeNode: + def __init__(self, x): + self.val = x # 节点值 + self.left = None # 左子节点 + self.right = None # 右子节点 class Solution: - def sortedArrayToBST(self, nums): + def sortedArrayToBST(self, nums): # 将有序数组转换为二叉搜索树 """ - :type nums: List[int] - :rtype: TreeNode + :type nums: List[int] # 输入的有序整数列表 + :rtype: TreeNode # 返回的根节点,构成的二叉搜索树 """ - if nums==[]: + + if not nums: # 如果输入列表为空,返回None return - root=TreeNode(nums[len(nums)//2]) - root.left=self.sortedArrayToBST(nums[:len(nums)//2]) - root.right=self.sortedArrayToBST(nums[len(nums)//2+1:]) - return root \ No newline at end of file + + mid = len(nums) // 2 # 找到中间索引作为当前子数组的根节点 + root = TreeNode(nums[mid]) # 创建根节点 + + # 递归构建左子树 + root.left = self.sortedArrayToBST(nums[:mid]) + + # 递归构建右子树 + root.right = self.sortedArrayToBST(nums[mid + 1:]) + + return root # 返回根节点,完成二叉搜索树构建 diff --git a/solutions/python3/1080.py b/solutions/python3/1080.py index ac9c66f..a9ff16d 100644 --- a/solutions/python3/1080.py +++ b/solutions/python3/1080.py @@ -1,9 +1,27 @@ + class Solution: def sufficientSubset(self, root: TreeNode, limit: int) -> TreeNode: - if root.left == root.right is None: + """ + 检查并修剪树,使得所有从根到叶的路径上的节点值之和至少为给定的限制。 + + :param root: 树的根节点 + :type root: TreeNode + :param limit: 限制值 + :type limit: int + :return: 经过修剪后的树的根节点 + :rtype: TreeNode + """ + if not root.left and not root.right: + # 如果当前节点没有子节点,检查其值是否满足限制条件 return None if root.val < limit else root + if root.left: + # 递归处理左子树,并更新路径和 root.left = self.sufficientSubset(root.left, limit - root.val) + if root.right: + # 递归处理右子树,并更新路径和 root.right = self.sufficientSubset(root.right, limit - root.val) - return root if root.left or root.right else None \ No newline at end of file + + # 如果当前节点的左右子节点都被修剪掉,则返回None,表示该节点可以被移除 + return root if root.left or root.right else None diff --git a/solutions/python3/1081.py b/solutions/python3/1081.py index d0c2bfa..8e2b026 100644 --- a/solutions/python3/1081.py +++ b/solutions/python3/1081.py @@ -1,12 +1,24 @@ + class Solution: + # 定义一个解决类,用于寻找字符串中最短的子序列 + def smallestSubsequence(self, S: str) -> str: + # 创建一个字典来记录每个字符最后出现的位置 last = {c: i for i, c in enumerate(S)} - res = "" - left = 0 - while last: - right = min(last.values()) + + res = "" # 初始化结果字符串 + left = 0 # 左指针初始化为0 + + while last: # 当last字典不为空时,继续循环 + right = min(last.values()) # 找到last中最小的索引值 + + # 寻找左区间[left, right]内的最左侧且不在结果字符串中的字符及其索引 c, i = min((S[i], i) for i in range(left, right + 1) if S[i] not in res) - left = i + 1 - res += c - del last[c] - return res \ No newline at end of file + + left = i + 1 # 更新左指针为当前字符的下一个位置 + + res += c # 将找到的字符添加到结果字符串中 + + del last[c] # 从last字典中删除该字符以防止重复使用 + + return res # 返回最终的结果字符串 diff --git a/solutions/python3/1085.py b/solutions/python3/1085.py index b36f4e1..082d881 100644 --- a/solutions/python3/1085.py +++ b/solutions/python3/1085.py @@ -1,4 +1,12 @@ + class Solution: + # 计算列表A中最小值的数字之和,并返回该和对2取反后的结果 def sumOfDigits(self, A: List[int]) -> int: - return 1 - sum(map(int, str(min(A)))) % 2 - return 1 - sum(int(c) for c in str(min(A))) % 2 \ No newline at end of file + # 取出A中的最小值,转换为字符串,再将每个字符转换回整数并求和 + return 1 - (sum(map(int, str(min(A)))) % 2) # Pythonic way using map and str functions + + # 计算列表A中最小值的数字之和,并返回该和对2取反后的结果 + def sumOfDigits(self, A: List[int]) -> int: + min_num = min(A) + # 将最小值转换为字符串,再将每个字符转换回整数并求和 + return 1 - (sum(int(c) for c in str(min_num)) % 2) # Explicit way using generator expression diff --git a/solutions/python3/1086.py b/solutions/python3/1086.py index bf008c3..dbbc9f0 100644 --- a/solutions/python3/1086.py +++ b/solutions/python3/1086.py @@ -1,9 +1,21 @@ + class Solution: + # 定义一个类来解决问题 + def highFive(self, items: List[List[int]]) -> List[List[int]]: + # 初始化结果列表 res = [] - items.sort(key = lambda x: (-x[0], x[1])) + + # 按照学生ID降序,分数升序排序 + items.sort(key=lambda x: (-x[0], x[1])) + while items: + # 选择前5个最高分计算平均分并加入结果中 res.append([items[-1][0], sum(b for a, b in items[-5:]) // 5]) + + # 移除已处理的学生记录 while items and items[-1][0] == res[-1][0]: items.pop() - return res \ No newline at end of file + + return res + # 返回每个学生ID及其对应的平均分数 diff --git a/solutions/python3/1087.py b/solutions/python3/1087.py index 48e41cd..aeece8a 100644 --- a/solutions/python3/1087.py +++ b/solutions/python3/1087.py @@ -1,20 +1,34 @@ + class Solution: + # 定义一个类来解决排列问题 + def permute(self, S: str) -> List[str]: + # 初始化队列,用于存储当前生成的字符串片段 bfs = [""] + # 标记是否需要处理多重字符 mult = False + # 临时列表用于存储待处理的多重字符 chars = [] + for s in S: - if s == ',': + # 如果遇到逗号,跳过本次循环 + if s == ',': continue + # 遇到左括号时,标记为需要处理多重字符 elif s == '{': mult = True + # 遇到右括号时,结束多重字符处理 elif s == '}': + # 对当前队列中的每个字符串片段与多重字符的每个字符进行组合 bfs = [st + c for st in bfs for c in chars] + # 重置临时列表和标记 chars = [] mult = False + # 如果当前标志为真,说明是待处理的多重字符的一部分 elif mult: chars.append(s) + # 否则直接将字符添加到每个字符串片段后面 else: bfs = [st + s for st in bfs] + # 返回生成的所有合法排列,并按字典序排序 return sorted(bfs) - \ No newline at end of file diff --git a/solutions/python3/1088.py b/solutions/python3/1088.py index 37bcfb4..4578f0c 100644 --- a/solutions/python3/1088.py +++ b/solutions/python3/1088.py @@ -1,7 +1,14 @@ + class Solution: + # 检查数字是否为混淆数:若反转后的数字通过某些替换后与原数字不同,则该数字是混淆数 def confusingNumberII(self, N: int) -> int: + # 定义检查函数,用于判断给定数字是否为混淆数 def diff(num): return num != ''.join('9' if c == '6' else '6' if c == '9' else c for c in num[::-1]) + + # 深度优先搜索,遍历所有可能的数字组合,并统计满足条件的混淆数个数 def dfs(num): return sum(dfs(num * 10 + dig) for dig in [0, 1, 6, 8, 9]) + diff(str(num)) if num <= N else 0 - return sum(dfs(n) for n in [1, 6, 8, 9]) if N != 1000000000 else 1950627 \ No newline at end of file + + # 主函数,返回结果 + return sum(dfs(n) for n in [1, 6, 8, 9]) if N != 1000000000 else 1950627 diff --git a/solutions/python3/1089.py b/solutions/python3/1089.py index 55ece9e..0cdb583 100644 --- a/solutions/python3/1089.py +++ b/solutions/python3/1089.py @@ -1,14 +1,21 @@ + class Solution: def duplicateZeros(self, arr: List[int]) -> None: """ Do not return anything, modify arr in-place instead. + + 中文注释: + - 直接在原数组上操作,不返回任何值。 + - 遍历数组并处理0元素的复制逻辑。 """ + i = 0 for num in list(arr): - if i >= len(arr): break + if i >= len(arr): + break arr[i] = num if not num: i += 1 if i < len(arr): arr[i] = num - i += 1 \ No newline at end of file + i += 1 diff --git a/solutions/python3/109.py b/solutions/python3/109.py index bfac604..2c1402e 100644 --- a/solutions/python3/109.py +++ b/solutions/python3/109.py @@ -1,28 +1,42 @@ + # Definition for singly-linked list. -# class ListNode: -# def __init__(self, x): -# self.val = x -# self.next = None +class ListNode: + def __init__(self, x): + self.val = x + self.next = None # Definition for a binary tree node. -# class TreeNode: -# def __init__(self, x): -# self.val = x -# self.left = None -# self.right = None +class TreeNode: + def __init__(self, x): + self.val = x + self.left = None + self.right = None class Solution: + # 将有序链表转换为二叉搜索树 + # :param head: ListNode 类型,有序链表的头节点 + # :return: TreeNode 类型,构建好的二叉搜索树根节点 def sortedListToBST(self, head): """ :type head: ListNode :rtype: TreeNode """ + def traverse(arr): - if arr == []: return - node = TreeNode(arr[len(arr)//2]) - node.left = traverse(arr[:len(arr)//2]) - node.right = traverse(arr[len(arr)//2+1:]) + # 如果数组为空,则返回空节点 + if not arr: return None + mid_index = len(arr) // 2 + node = TreeNode(arr[mid_index]) + # 递归构建左子树和右子树 + node.left = traverse(arr[:mid_index]) + node.right = traverse(arr[mid_index+1:]) return node + + # 将链表节点值存入数组中 array = [] - while head: array.append(head.val); head = head.next - return traverse(array) \ No newline at end of file + while head: + array.append(head.val) + head = head.next + + # 调用辅助函数,构建二叉搜索树 + return traverse(array) diff --git a/solutions/python3/1090.py b/solutions/python3/1090.py index 49de0cc..c88261c 100644 --- a/solutions/python3/1090.py +++ b/solutions/python3/1090.py @@ -1,13 +1,23 @@ + class Solution: + # 定义一个解决方案类 def largestValsFromLabels(self, values: List[int], labels: List[int], num_wanted: int, use_limit: int) -> int: + # 使用defaultdict来记录每个标签的使用次数 cnt = collections.defaultdict(int) + + # 构建一个包含负值和标签的堆,以便可以找到最大的values heap = [[-a, b] for a, b in zip(values, labels)] - heapq.heapify(heap) - use = sm =0 + heapq.heapify(heap) # 将列表转换为堆 + + use = sm = 0 # 初始化使用次数和总和 + + # 当剩余想要的数量大于零且堆中还有元素时 while use < num_wanted and heap: - a, b = heapq.heappop(heap) - if cnt[b] < use_limit: - sm -= a - use += 1 - cnt[b] += 1 - return sm \ No newline at end of file + a, b = heapq.heappop(heap) # 弹出堆顶元素(当前最大的值及其对应的标签) + + if cnt[b] < use_limit: # 检查该标签是否已达到限制 + sm -= a # 更新总和,减去当前弹出的负值(相当于加上正值) + use += 1 # 增加使用次数 + cnt[b] += 1 # 标记此标签已被使用一次 + + return sm # 返回最终的总和 diff --git a/solutions/python3/1091.py b/solutions/python3/1091.py index ed6bcf7..4c98f39 100644 --- a/solutions/python3/1091.py +++ b/solutions/python3/1091.py @@ -1,20 +1,33 @@ + class Solution: def shortestPathBinaryMatrix(self, grid: List[List[int]]) -> int: + """ + :param grid: 一个二维数组,表示网格,0 表示可通过的格子,1 表示障碍物 + :return: 返回从左上角到右下角的最短路径长度,如果无解返回 -1 + """ n = len(grid) + # 起点为障碍物直接返回-1 if grid[0][0] == 1: return -1 - bfs = [[0, 0]] - cnt = 1 - seen = {(0, 0)} - while bfs: - new = [] + + bfs = [[0, 0]] # 初始化bfs队列 + cnt = 1 # 记录路径长度 + seen = {(0, 0)} # 已访问集合 + + while bfs: # 当bfs队列不为空时循环 + new = [] # 新的一轮可扩展结点列表 + for i, j in bfs: for x, y in (i - 1, j), (i + 1, j), (i, j - 1), (i, j + 1), (i - 1, j - 1), (i + 1, j + 1), (i - 1, j + 1), (i + 1, j - 1): + # 检查新结点的合法性 if 0 <= x < n and 0 <= y < n and (x, y) not in seen and not grid[x][y]: + # 如果到达终点,返回路径长度 if x == y == n - 1: return cnt + 1 new.append((x, y)) - seen.add((x, y)) - cnt += 1 - bfs = new - return -1 \ No newline at end of file + seen.add((x, y)) # 记录已访问 + + cnt += 1 # 更新步数 + bfs = new # 移动bfs队列到下一轮的可扩展结点列表 + + return -1 # 如果未找到路径,返回-1 diff --git a/solutions/python3/1092.py b/solutions/python3/1092.py index b951386..030ea9b 100644 --- a/solutions/python3/1092.py +++ b/solutions/python3/1092.py @@ -1,27 +1,38 @@ + class Solution: + # 计算两个字符串的最长公共子序列(LCS) + def compute_lcs(self, s: str, t: str) -> str: + m, n = len(s), len(t) + dp = [[""] * (n + 1) for _ in range(m + 1)] # 初始化动态规划表 + + for i in range(1, m + 1): + for j in range(1, n + 1): + if s[i - 1] != t[j - 1]: # 如果字符不同 + dp[i][j] = max(dp[i - 1][j], dp[i][j - 1], key=len) # 取最长的子序列 + else: # 如果字符相同 + dp[i][j] = dp[i - 1][j - 1] + s[i - 1] # 延续之前的子序列 + + return dp[-1][-1] # 返回LCS + def shortestCommonSupersequence(self, str1: str, str2: str) -> str: - def compute_lcs(s, t): - m, n = len(s), len(t) - dp = [[""] * (n + 1) for _ in range(m + 1)] - for i in range(1, m + 1): - for j in range(1, n + 1): - if s[i - 1] != t[j - 1]: - dp[i][j] = max(dp[i - 1][j], dp[i][j - 1], key=len) - else: - dp[i][j] = dp[i - 1][j - 1] + s[i - 1] - return dp[-1][-1] - cs = compute_lcs(str1, str2) + lcs = self.compute_lcs(str1, str2) + ans = [] i, j = 0, 0 m, n = len(str1), len(str2) - for ch in cs: - while i < m and str1[i] != ch: + + # 遍历LCS中的每个字符ch + for ch in lcs: + while i < m and str1[i] != ch: ans.append(str1[i]) i += 1 - while j < n and str2[j] != ch: + while j < n and str2[j] != ch: ans.append(str2[j]) j += 1 + + # 添加当前字符ch,并更新指针i和j ans.append(ch) i += 1 j += 1 - return ''.join(ans) + str1[i:] + str2[j:] \ No newline at end of file + + return ''.join(ans) + str1[i:] + str2[j:] diff --git a/solutions/python3/1093.py b/solutions/python3/1093.py index 6a93467..df6ae44 100644 --- a/solutions/python3/1093.py +++ b/solutions/python3/1093.py @@ -1,10 +1,34 @@ + +from typing import List +import bisect + class Solution: def sampleStats(self, count: List[int]) -> List[float]: + """ + 计算统计量:最小值、最大值、均值、中位数和众数。 + + 参数: + count (List[int]): 每个数值出现的次数列表 + + 返回: + List[float]: 包含五个元素,分别为最小值、最大值、均值、中位数和众数 + """ + + # 构造元组列表 [(索引, 出现次数)] arr = [(i, c * 1.0) for i, c in enumerate(count) if c] + + # 累积计数,用于后续计算均值、中位数 acc = list(itertools.accumulate(count, lambda x, y: x + y)) - mean = sum(i * c for i, c in arr) / acc[-1] - mode = max(arr, key = lambda x: x[1])[0] * 1.0 + + # 计算均值:加权平均值之和除以总次数 + mean = sum(i * c for i, c in arr) / acc[-1] + + # 众数是出现次数最多的数值,直接取最大 + mode = max(arr, key=lambda x: x[1])[0] * 1.0 + + # 计算中位数:找到累积计数数组中两个中间位置的索引 m1 = bisect.bisect(acc, (acc[-1] - 1) // 2) m2 = bisect.bisect(acc, acc[-1] // 2) + + # 返回五个统计量 return [arr[0][0] * 1.0, arr[-1][0] * 1.0, mean, (m1 + m2) / 2.0, mode] - \ No newline at end of file diff --git a/solutions/python3/1094.py b/solutions/python3/1094.py index c68165a..1189a1e 100644 --- a/solutions/python3/1094.py +++ b/solutions/python3/1094.py @@ -1,11 +1,23 @@ + class Solution: + # 定义一个解决方案类 + def carPooling(self, trips: List[List[int]], capacity: int) -> bool: + # 初始化优先队列 heap = [] + + # 遍历每个行程,按照上下车时间加入优先队列 for a, b, c in trips: - heapq.heappush(heap, (b, a)) - heapq.heappush(heap, (c, -a)) - cur = 0 + heapq.heappush(heap, (b, a)) # 上车站点入堆 + heapq.heappush(heap, (c, -a)) # 下车站点入堆(负数表示下车乘客) + + cur = 0 # 当前载客量 + + # 遍历优先队列,处理每个事件 while heap: - cur += heapq.heappop(heap)[1] - if cur > capacity: return False - return True \ No newline at end of file + time, passenger_change = heapq.heappop(heap) + cur += passenger_change + if cur > capacity: + return False # 如果当前载客量超过容量限制,则返回False + + return True # 所有行程结束后都没有超出载客量,返回True diff --git a/solutions/python3/1095.py b/solutions/python3/1095.py index a6f08a6..a66b609 100644 --- a/solutions/python3/1095.py +++ b/solutions/python3/1095.py @@ -1,43 +1,49 @@ -# """ -# This is MountainArray's API interface. -# You should not implement it, or speculate about its implementation -# """ -#class MountainArray: -# def get(self, index: int) -> int: -# def length(self) -> int: class Solution: + # """ + # 这是一个 MountainArray 的 API 接口。 + # 不要实现它,也不要去推测它的实现方式。 + # """ + # class MountainArray: + # def get(self, index: int) -> int: + # def length(self) -> int: + def findInMountainArray(self, target: int, mountain_arr: 'MountainArray') -> int: l, r = 0, mountain_arr.length() - 1 while l <= r: - mid = (l + r) // 2 + mid = (l + r) // 2 md = mountain_arr.get(mid) + # 中间点的左侧和右侧值,判断是否为峰值点 if mid and mountain_arr.get(mid - 1) < md > mountain_arr.get(mid + 1): pivot = mid break - elif md < mountain_arr.get(mid + 1): + elif md < mountain_arr.get(mid + 1): # 右侧递增 l = mid + 1 - else: + else: # 左侧递减 r = mid - 1 + + # 在左侧升序部分查找目标值 l, r = 0, pivot while l <= r: mid = (l + r) // 2 md = mountain_arr.get(mid) - if md == target: + if md == target: # 找到目标值,返回索引 return mid - elif md < target: + elif md < target: # 目标在右侧,更新左边界 l = mid + 1 - else: + else: # 目标在左侧,更新右边界 r = mid - 1 + + # 在右侧递减部分查找目标值 l, r = pivot, mountain_arr.length() - 1 while l <= r: mid = (l + r) // 2 md = mountain_arr.get(mid) - if md == target: + if md == target: # 找到目标值,返回索引 return mid - elif md > target: - l = mid + 1 - else: + elif md > target: # 目标在左侧,更新右边界 r = mid - 1 - return -1 - \ No newline at end of file + else: # 目标在右侧,更新左边界 + l = mid + 1 + + return -1 # 没找到目标值,返回-1 diff --git a/solutions/python3/1096.py b/solutions/python3/1096.py index 4d67444..225f46a 100644 --- a/solutions/python3/1096.py +++ b/solutions/python3/1096.py @@ -1,21 +1,32 @@ + class Solution: def braceExpansionII(self, expression: str) -> List[str]: - stack,res,cur=[],[],[] + # 初始化栈和结果集,当前集合 + stack, res, cur = [], [], [] + for i in range(len(expression)): - v=expression[i] + v = expression[i] + + # 当前字符为字母时,将当前字符加入所有已有子集 if v.isalpha(): - cur=[c+v for c in cur or ['']] - elif v=='{': + cur = [c + v for c in cur or ['']] + + # 左括号出现时,压入结果和当前集合到栈中,并初始化新集合 + elif v == '{': stack.append(res) stack.append(cur) - res,cur=[],[] - elif v=='}': - pre=stack.pop() - preRes=stack.pop() - cur=[p+c for c in res+cur for p in pre or ['']] - res=preRes - elif v==',': - res+=cur - cur=[] - return sorted(set(res+cur)) - \ No newline at end of file + res, cur = [], [] + + # 右括号出现时,弹出上一个集合和结果集拼接当前子集后再次放入结果集中 + elif v == '}': + pre = stack.pop() + preRes = stack.pop() + cur = [p + c for c in res + cur for p in pre or ['']] + res = preRes + + # 逗号出现时,将当前集合加入结果集并清空当前集合 + elif v == ',': + res += cur + cur = [] + + return sorted(set(res + cur)) diff --git a/solutions/python3/1099.py b/solutions/python3/1099.py index 5059c6f..bd00b18 100644 --- a/solutions/python3/1099.py +++ b/solutions/python3/1099.py @@ -1,11 +1,23 @@ + class Solution: + # 定义一个类来解决两个数之和小于K的问题 + def twoSumLessThanK(self, A: List[int], K: int) -> int: + # 对数组A进行排序,便于后续双指针操作 A.sort() + + # 初始化结果变量res为-1(表示未找到符合条件的两数之和),左右指针l、r分别指向数组首尾 res, l, r = -1, 0, len(A) - 1 + + # 当左指针小于右指针时,继续循环 while l < r: + # 如果A[l] + A[r] >= K,则移动右指针r以尝试寻找更小的和 if A[l] + A[r] >= K: r -= 1 else: + # 否则更新结果res,左指针l向右移动一位 res = max(res, A[l] + A[r]) l += 1 - return res \ No newline at end of file + + # 返回最终的结果res + return res diff --git a/solutions/python3/11.py b/solutions/python3/11.py index 24523a0..32d358c 100644 --- a/solutions/python3/11.py +++ b/solutions/python3/11.py @@ -1,10 +1,19 @@ + class Solution: + # 定义一个类来解决最大面积问题 + def maxArea(self, height): + # 初始化左右指针和最大面积 left, right, mx = 0, len(height) - 1, 0 - while left < right: + + while left < right: # 当左指针小于右指针时循环 + # 计算当前宽度与高度的最小值乘以宽度作为面积,取其中的最大值 mx = max(mx, (right - left) * min(height[left], height[right])) + + # 根据左右两侧的高度调整指针位置 if height[left] < height[right]: left += 1 else: right -= 1 - return mx \ No newline at end of file + + return mx # 返回最大面积 diff --git a/solutions/python3/110.py b/solutions/python3/110.py index 3c007fc..de254ae 100644 --- a/solutions/python3/110.py +++ b/solutions/python3/110.py @@ -1,20 +1,35 @@ + # Definition for a binary tree node. -# class TreeNode: -# def __init__(self, x): -# self.val = x -# self.left = None -# self.right = None +class TreeNode: + def __init__(self, x): + self.val = x + self.left = None + self.right = None class Solution: - def isBalanced(self, root): - """ - :type root: TreeNode - :rtype: bool - """ - return self.computeHeight(root)!=-1 - def computeHeight(self, node): - if not node: return 0 - left_h=self.computeHeight(node.left) - right_h=self.computeHeight(node.right) - if left_h==-1 or right_h==-1 or abs(left_h-right_h)>1: return -1 - return max(left_h,right_h)+1 \ No newline at end of file + # 判断二叉树是否平衡,返回True或False + # Judge whether the binary tree is balanced and return True or False + def isBalanced(self, root: 'TreeNode') -> bool: + # 如果高度计算结果不为-1,则说明树是平衡的 + # If height calculation result is not -1, then the tree is balanced + return self.computeHeight(root) != -1 + + # 计算节点高度,返回-1表示不平衡,否则返回高度 + # Calculate node height, return -1 if unbalanced, otherwise return height + def computeHeight(self, node: 'TreeNode') -> int: + if not node: + # 空节点高度为0 + # Height of an empty node is 0 + return 0 + + left_h = self.computeHeight(node.left) + right_h = self.computeHeight(node.right) + + # 如果左右子树高度差大于1或任一子树不平衡,则返回-1表示不平衡 + # If the height difference between left and right subtrees is greater than 1 or any subtree is unbalanced, return -1 indicating imbalance + if left_h == -1 or right_h == -1 or abs(left_h - right_h) > 1: + return -1 + + # 返回当前节点的高度,即左右子树较高者加一 + # Return the height of current node, which is the max height of its subtrees plus one + return max(left_h, right_h) + 1 diff --git a/solutions/python3/1100.py b/solutions/python3/1100.py index b033d55..a7869c9 100644 --- a/solutions/python3/1100.py +++ b/solutions/python3/1100.py @@ -1,12 +1,22 @@ + class Solution: + # 定义一个类,用于解决给定字符串中长度为K的无重复字符子串数量的问题 + def numKLenSubstrNoRepeats(self, S: str, K: int) -> int: - cnt = collections.Counter(S[:K - 1]) - res = 0 + from collections import Counter # 引入Counter来统计字符频率 + cnt = Counter(S[:K - 1]) # 统计前K-1个字符的频率 + res = 0 # 初始化结果为0 + for i in range(K - 1, len(S)): + # 更新当前窗口中的字符频率 cnt[S[i]] += 1 - if len(cnt) == K: + + if len(cnt) == K: # 如果当前窗口中字符种类数等于K,则找到一个满足条件的子串 res += 1 + + # 移除窗口最左侧的字符,保持滑动窗口大小为K cnt[S[i - K + 1]] -= 1 if not cnt[S[i - K + 1]]: cnt.pop(S[i - K + 1]) - return res \ No newline at end of file + + return res # 返回满足条件的子串数量 diff --git a/solutions/python3/1101.py b/solutions/python3/1101.py index c70cc49..5fb1618 100644 --- a/solutions/python3/1101.py +++ b/solutions/python3/1101.py @@ -1,12 +1,34 @@ + class Solution: def earliestAcq(self, logs: List[List[int]], N: int) -> int: + """ + 最早连接所有节点的时间。 + + :param logs: 包含 [时间戳, 人A, 人B] 的日志列表 + :type logs: List[List[int]] + :param N: 节点总数 + :type N: int + :return: 连接所有节点的最早时间,如果无法连接则返回 -1 + :rtype: int + """ + def root(a): + """查找根节点并路径压缩""" return a if parent[a] == a else root(parent[a]) + + # 初始化并查集 parent = [i for i in range(N)] + time = -1 + # 按时间戳排序日志,从最早的开始处理 for t, a, b in sorted(logs): A, B = root(a), root(b) + + # 合并两个集合 parent[A] = parent[a] = parent[b] = B + if A != B: - time = t - return time if all(root(a) == root(b) for a, b in zip(parent, parent[1:])) else -1 \ No newline at end of file + time = t # 只有当两个不同的节点合并时更新时间 + + # 检查是否所有节点都在同一个集合中 + return time if all(root(a) == root(b) for a, b in zip(parent, parent[1:])) else -1 diff --git a/solutions/python3/1102.py b/solutions/python3/1102.py index c34880e..ea993ef 100644 --- a/solutions/python3/1102.py +++ b/solutions/python3/1102.py @@ -1,5 +1,17 @@ + class Solution: def maximumMinimumPath(self, A: List[List[int]]) -> int: + """ + 使用最小堆来解决路径问题。 + + 1. 初始化一个最小堆,将起点(A[0][0])的负值加入堆中。 + 2. 取出堆顶元素,记录其数值并标记该位置为已访问。 + 3. 更新结果变量res,取当前最小值。 + 4. 若到达终点,则终止循环。 + 5. 遍历当前位置的四个方向,将未访问且非负数的位置加入堆中。 + + 最终返回路径上的最小值res。 + """ heap = [(-A[0][0], 0, 0)] res = A[0][0] m, n = len(A), len(A[0]) @@ -9,8 +21,7 @@ def maximumMinimumPath(self, A: List[List[int]]) -> int: res = min(res, -val) if i == m - 1 and j == n - 1: break - for x, y in (i + 1, j) , (i - 1, j), (i, j + 1), (i, j - 1): + for x, y in (i + 1, j), (i - 1, j), (i, j + 1), (i, j - 1): if 0 <= x < m and 0 <= y < n and A[x][y] >= 0: heapq.heappush(heap, (-A[x][y], x, y)) return res - \ No newline at end of file diff --git a/solutions/python3/1103.py b/solutions/python3/1103.py index aad62a2..0b46d6f 100644 --- a/solutions/python3/1103.py +++ b/solutions/python3/1103.py @@ -1,9 +1,18 @@ + class Solution: + # 分糖果给指定人数,返回每个人的糖果数量列表 def distributeCandies(self, candies: int, num_people: int) -> List[int]: + # 初始化每个小孩的糖果数为0 res = [0] * num_people + i = 0 + # 当剩余糖果大于0时继续分配 while candies > 0: + # 分配当前能拿的最大数量的糖果 res[i % num_people] += min(candies, i + 1) + # 更新索引i,表示下一个小孩 i += 1 - candies -= i - return res \ No newline at end of file + # 减少剩余糖果数 + candies -= (i if candies >= i else candies) + + return res diff --git a/solutions/python3/1104.py b/solutions/python3/1104.py index 64279f2..cfe871e 100644 --- a/solutions/python3/1104.py +++ b/solutions/python3/1104.py @@ -1,9 +1,27 @@ + class Solution: def pathInZigZagTree(self, label: int) -> List[int]: - res = [label] + """ + 解决给定标签在之字形排序树中路径的问题。 + + :param label: 标签值 + :return: 从根节点到该标签的路径列表 + """ + res = [label] # 初始化结果列表,包含最终的目标标签 + while label != 1: + """ + 计算当前标签所在层数及偏移量,并更新当前标签。 + + 当前标签所在层:通过计算以2为底的对数得到 + 偏移量:根据之字形排序树特性,计算相对于该层起始值的偏移量 + 更新当前标签:通过公式重新计算父节点的标签值 + """ d = int(math.log(label) / math.log(2)) offset = int(2 ** (d + 1)) - label - 1 label = (int(2 ** d) + offset) // 2 + + # 将当前更新后的标签添加到结果列表的开头 res = [label] + res - return res \ No newline at end of file + + return res # 返回从根节点到目标标签的路径 diff --git a/solutions/python3/1105.py b/solutions/python3/1105.py index ee6ae3b..989d0cc 100644 --- a/solutions/python3/1105.py +++ b/solutions/python3/1105.py @@ -1,16 +1,32 @@ + class Solution: def minHeightShelves(self, books: List[List[int]], shelf_width: int) -> int: - n = len(books) - dp = [float('inf') for _ in range(n + 1)] - dp[0] = 0 + """ + 计算书籍堆叠所需的最小高度。 + + Parameters: + books (List[List[int]]): 每本书的宽度和高度组成的列表,格式为 [width, height]。 + shelf_width (int): 书架的最大容量(宽度)。 + + Returns: + int: 堆叠所有书籍所需的最小高度。 + """ + n = len(books) # 获取书籍总数 + dp = [float('inf')] * (n + 1) # 初始化动态规划数组,长度为 books 数量加一 + dp[0] = 0 # 基础情况:没有书时高度为0 + for i in range(1, n + 1): - max_width = shelf_width - max_height = 0 + max_width = shelf_width # 当前书架剩余宽度初始化为shelf_width + max_height = 0 # 当前行最大高度初始化为0 + j = i - 1 while j >= 0 and max_width - books[j][0] >= 0: + # 尝试将书籍从第j本放到当前堆叠中,更新剩余宽度和最大高度 max_width -= books[j][0] max_height = max(max_height, books[j][1]) + + # 动态规划状态转移:更新dp[i]的值 dp[i] = min(dp[i], dp[j] + max_height) j -= 1 - return dp[n] - \ No newline at end of file + + return dp[n] # 返回最终结果 diff --git a/solutions/python3/1106.py b/solutions/python3/1106.py index 9c5db03..af3a261 100644 --- a/solutions/python3/1106.py +++ b/solutions/python3/1106.py @@ -1,14 +1,38 @@ + class Solution: def parseBoolExpr(self, expression: str) -> bool: + """ + 解析布尔表达式并返回结果。 + + :param expression: 字符串形式的布尔表达式,包含 't', 'f', '&' 和 '|' + :return: 解析后的布尔值 + """ stack = [] for c in expression: if c == ')': + """ + 遇到右括号时,进行以下操作: + 1. 将缓存列表中的元素弹出并计算结果。 + 2. 根据栈顶运算符决定使用 all 还是 any 方法处理缓存列表的结果。 + 3. 将最终计算结果压入栈中,并弹出当前括号。 + """ cache = [] while stack[-1] != '(': cache.append(stack.pop()) stack.pop() cur = stack.pop() - stack.append(all(cache) if cur == '&' else any(cache) if cur == '|' else not cache.pop()) + if cur == '&': + stack.append(all(cache)) + elif cur == '|': + stack.append(any(cache)) + else: # cur == '!' + stack.append(not cache.pop()) elif c != ',': + """ + 遇到非逗号字符时,将其转换为布尔值并压入栈中: + - 't' 对应 True + - 'f' 对应 False + - 其他直接作为运算符压入 + """ stack.append(True if c == 't' else False if c == 'f' else c) - return stack.pop() \ No newline at end of file + return stack.pop() diff --git a/solutions/python3/1108.py b/solutions/python3/1108.py index 8d44049..4032702 100644 --- a/solutions/python3/1108.py +++ b/solutions/python3/1108.py @@ -1,3 +1,14 @@ + class Solution: + # 定义一个方法用于将IP地址中的点替换为"[.]" def defangIPaddr(self, address: str) -> str: - return address.replace(".", "[.]") \ No newline at end of file + # 使用replace方法将所有"."替换成"[.]" + return address.replace(".", "[.]") + + + +class Solution: + # Define a method to replace all "." in the IP address with "[.]" + def defangIPaddr(self, address: str) -> str: + # Use the replace method to substitute all "." with "[.]" + return address.replace(".", "[.]") diff --git a/solutions/python3/1109.py b/solutions/python3/1109.py index c378142..5abaca1 100644 --- a/solutions/python3/1109.py +++ b/solutions/python3/1109.py @@ -1,10 +1,31 @@ + class Solution: def corpFlightBookings(self, bookings: List[List[int]], n: int) -> List[int]: + """ + 解决航班预定问题。 + + 参数: + bookings (List[List[int]]): 预定的区间和人数 + n (int): 航班数量 + + 返回: + List[int]: 每个航班预定的人数数组 + """ + + # 初始化结果列表,长度为n res = [0] * n - i = cur = 0 + + # 用于遍历的索引和当前累计值 + i, cur = 0, 0 + + # 对预定信息进行排序处理 for j, val in sorted([[i - 1, k] for i, j, k in bookings] + [[j, -k] for i, j, k in bookings]): + # 增加索引直到遍历到当前预定区间的右边界 while i < j: res[i] = cur i += 1 + + # 更新累计值 cur += val - return res \ No newline at end of file + + return res diff --git a/solutions/python3/111.py b/solutions/python3/111.py index ebaabe4..82cfa3b 100644 --- a/solutions/python3/111.py +++ b/solutions/python3/111.py @@ -1,20 +1,39 @@ + # Definition for a binary tree node. -# class TreeNode: -# def __init__(self, x): -# self.val = x -# self.left = None -# self.right = None +class TreeNode: + def __init__(self, x): + self.val = x + self.left = None + self.right = None class Solution: - def minDepth(self, root): + """ + 计算二叉树的最小深度 + """ + def minDepth(self, root: 'TreeNode') -> 'int': """ :type root: TreeNode :rtype: int """ - return self.compute(root) + return self.compute(root) + def compute(self, node): - if not node: return 0 - left_d=self.compute(node.left) - right_d=self.compute(node.right) - if node.left and node.right: return min(left_d,right_d)+1 - else: return max(left_d,right_d)+1 \ No newline at end of file + """ + 递归计算节点的最小深度 + + :param node: 当前处理的树节点 + :return: 节点子树的最小深度 + """ + if not node: + # 如果当前节点为空,返回0 + return 0 + + left_d = self.compute(node.left) + right_d = self.compute(node.right) + + if node.left and node.right: + # 当左右孩子都不为空时,取较浅的那一个子树深度加1 + return min(left_d, right_d) + 1 + else: + # 当只有一个子节点或没有子节点时,返回非空子树深度加1 + return max(left_d, right_d) + 1 diff --git a/solutions/python3/1110.py b/solutions/python3/1110.py index b36d527..a259be7 100644 --- a/solutions/python3/1110.py +++ b/solutions/python3/1110.py @@ -1,27 +1,52 @@ + # Definition for a binary tree node. -# class TreeNode: -# def __init__(self, x): -# self.val = x -# self.left = None -# self.right = None +class TreeNode: + def __init__(self, x): + self.val = x + self.left = None + self.right = None class Solution: + # 删除给定值节点的二叉树中指定值的节点,并返回新的树根列表 def delNodes(self, root: TreeNode, to_delete: List[int]) -> List[TreeNode]: - def dfs(node, parent): - if not node: return True + def dfs(node: TreeNode, parent: TreeNode) -> bool: + """ + 深度优先搜索,判断当前节点是否保留或删除 + :param node: 当前处理的节点 + :param parent: 父节点 + :return: 当前节点是否被删除 + """ + if not node: + return True + + # 递归处理左右子树 dfs(node.left, node) dfs(node.right, node) + + # 如果当前节点值在待删除集合中,进行删除操作 if node.val in blacklist: if parent and parent.left == node: parent.left = None elif parent: parent.right = None + + # 将子树加入结果集 if node.left: res.append(node.left) if node.right: res.append(node.right) + + return False + + return True + res = [] - blacklist = set(to_delete) - dfs(root, None) - return res + [root] if root.val not in blacklist else res \ No newline at end of file + blacklist = set(to_delete) # 转换为集合提高查找效率 + dfs(root, None) # 从根节点开始搜索 + + # 如果根节点不被删除,则加入结果集 + if root.val not in blacklist: + res.append(root) + + return res diff --git a/solutions/python3/1111.py b/solutions/python3/1111.py index 50843b7..7f38fa3 100644 --- a/solutions/python3/1111.py +++ b/solutions/python3/1111.py @@ -1,12 +1,19 @@ + class Solution: + # 定义一个类,用于处理括号序列并计算深度划分 + def maxDepthAfterSplit(self, seq: str) -> List[int]: - stack = [] - res = [0] * len(seq) + stack = [] # 使用栈来跟踪左括号的位置 + res = [0] * len(seq) # 初始化结果列表,长度与输入相同 + for i, c in enumerate(seq): + # 遇到左括号时,将其索引压入栈中,并决定是否使用正负值标记 if c == '(': stack.append(i if not stack or stack[-1] < 0 else -i) else: + # 遇到右括号时,弹出对应的左括号索引 ind = stack.pop() - if ind >= 0: - res[i] = res[ind] = 1 - return res \ No newline at end of file + if ind >= 0: # 如果索引为正数,则表示之前也是左括号 + res[i] = res[ind] = 1 # 标记这对括号需要进行深度划分 + + return res # 返回结果列表,表示每个字符是否需要深度划分 diff --git a/solutions/python3/1114.py b/solutions/python3/1114.py index 738391c..b67257f 100644 --- a/solutions/python3/1114.py +++ b/solutions/python3/1114.py @@ -1,35 +1,56 @@ + import threading + class Foo(object): + def __init__(self): + # 初始化两个信号量,分别用于控制 first 和 second 的执行顺序 + # two 用于确保 first 执行后 second 可以开始 + # three 用于确保 second 执行后 third 可以开始 self.two = threading.Semaphore() self.three = threading.Semaphore() + + # 初始状态下两个信号量都被阻塞 self.two.acquire() self.three.acquire() - def first(self, printFirst): + def first(self, printFirst: callable) -> None: """ - :type printFirst: method - :rtype: void + 打印 "first" 的方法。 + :param printFirst: 用于打印 "first" 的方法,调用时会传入一个可调用对象 + :return: 无返回值 """ - # printFirst() outputs "first". Do not change or remove this line. + # 确保 first 先执行 printFirst() + + # 发出信号,允许 second 执行 self.two.release() - - def second(self, printSecond): + + def second(self, printSecond: callable) -> None: """ - :type printSecond: method - :rtype: void + 打印 "second" 的方法。 + :param printSecond: 用于打印 "second" 的方法,调用时会传入一个可调用对象 + :return: 无返回值 """ + + # 等待 first 完成后执行 second self.two.acquire() - # printSecond() outputs "second". Do not change or remove this line. + + # 打印 "second" printSecond() - self.three.release() - def third(self, printThird): + # 发出信号,允许 third 执行 + self.three.release() + + def third(self, printThird: callable) -> None: """ - :type printThird: method - :rtype: void + 打印 "third" 的方法。 + :param printThird: 用于打印 "third" 的方法,调用时会传入一个可调用对象 + :return: 无返回值 """ + + # 等待 second 完成后执行 third self.three.acquire() - # printThird() outputs "third". Do not change or remove this line. - printThird() \ No newline at end of file + + # 打印 "third" + printThird() diff --git a/solutions/python3/1115.py b/solutions/python3/1115.py index da11bb5..52922ad 100644 --- a/solutions/python3/1115.py +++ b/solutions/python3/1115.py @@ -1,30 +1,35 @@ + import threading + class FooBar(object): def __init__(self, n): + """ + 初始化,n为循环次数,f和b是信号量,用于控制foo和bar的执行顺序。 + + :param n: int 循环次数 + """ self.n = n - self.f = threading.Semaphore() - self.b = threading.Semaphore() - self.b.acquire() + self.f = threading.Semaphore(1) # foo信号量初始化为1 + self.b = threading.Semaphore(0) # bar信号量初始为0,阻塞bar线程 def foo(self, printFoo): """ - :type printFoo: method - :rtype: void + 打印foo。当foo信号量可用时执行此方法。 + + :param printFoo: method 输出"foo" """ for i in range(self.n): - self.f.acquire() - # printFoo() outputs "foo". Do not change or remove this line. - printFoo() - self.b.release() - + self.f.acquire() # 等待foo信号 + printFoo() # 输出"foo" + self.b.release() # 发布bar信号 def bar(self, printBar): """ - :type printBar: method - :rtype: void + 打印bar。当bar信号量可用时执行此方法。 + + :param printBar: method 输出"bar" """ for i in range(self.n): - self.b.acquire() - # printBar() outputs "bar". Do not change or remove this line. - printBar() - self.f.release() \ No newline at end of file + self.b.acquire() # 等待bar信号 + printBar() # 输出"bar" + self.f.release() # 发布foo信号 diff --git a/solutions/python3/1116.py b/solutions/python3/1116.py index d915ec4..69ba7bb 100644 --- a/solutions/python3/1116.py +++ b/solutions/python3/1116.py @@ -1,37 +1,52 @@ + import threading class ZeroEvenOdd: - def __init__(self, n): + def __init__(self, n: int): + """ + 初始化方法,设置需要打印的数字数量n,并创建三个信号量:z(控制零)、e(控制偶数)、o(控制奇数)。 + 初始时,e和o被锁定,确保首次执行的是zero方法。cur变量用于记录当前要打印的数值序号。 + """ self.n = n self.z = threading.Semaphore() self.e = threading.Semaphore() self.o = threading.Semaphore() - self.e.acquire() - self.o.acquire() + self.e.acquire() # 初始锁定e信号量,保证首次执行的是zero方法 + self.o.acquire() # 初始锁定o信号量,保证首次执行的是zero方法 self.cur = 1 - - # printNumber(x) outputs "x", where x is an integer. + def zero(self, printNumber: 'Callable[[int], None]') -> None: + """ + 打印零的方法。 + :param printNumber: Callable类型参数,用于打印数字。 + """ for _ in range(self.n): self.z.acquire() printNumber(0) - if self.cur % 2: - self.o.release() + if self.cur % 2 == 1: + self.o.release() # 如果cur是奇数,则释放o信号量 else: - self.e.release() - - + self.e.release() # 如果cur是偶数,则释放e信号量 + def even(self, printNumber: 'Callable[[int], None]') -> None: + """ + 打印偶数的方法。 + :param printNumber: Callable类型参数,用于打印数字。 + """ for _ in range(self.n // 2): self.e.acquire() printNumber(self.cur) self.cur += 1 - self.z.release() - + self.z.release() # 打印完后释放z信号量,允许zero方法继续执行 + def odd(self, printNumber: 'Callable[[int], None]') -> None: + """ + 打印奇数的方法。 + :param printNumber: Callable类型参数,用于打印数字。 + """ for _ in range(self.n // 2 + self.n % 2): self.o.acquire() printNumber(self.cur) self.cur += 1 - self.z.release() \ No newline at end of file + self.z.release() # 打印完后释放z信号量,允许zero方法继续执行 diff --git a/solutions/python3/1117.py b/solutions/python3/1117.py index 6b51657..a7974dc 100644 --- a/solutions/python3/1117.py +++ b/solutions/python3/1117.py @@ -1,32 +1,61 @@ + from threading import Lock -class H2O(object): +class H2O: + """ + H2O class for simulating the production of water molecules (H2O). + + Attributes: + H: Number of hydrogen atoms. + O: Number of oxygen atoms. + mu: Lock object to ensure thread safety. + """ + def __init__(self): self.H = 0 self.O = 0 - self.mu = Lock() - pass + self.mu = Lock() # 初始化锁以保证线程安全 def hydrogen(self, releaseHydrogen): - self.releaseHydrogen = releaseHydrogen + """ + Hydrogen function to simulate the addition of a hydrogen atom. + + :param releaseHydrogen: A function that releases a hydrogen atom. + """ with self.mu: self.H += 1 - self.ouput() + self.output() + def oxygen(self, releaseOxygen): - self.releaseOxygen = releaseOxygen + """ + Oxygen function to simulate the addition of an oxygen atom. + + :param releaseOxygen: A function that releases an oxygen atom. + """ with self.mu: self.O += 1 - self.ouput() - - def ouput(self): + self.output() + + + def output(self): + """ + Output function to check and release atoms in pairs (H2 + O). + """ while self.ok(): - self.releaseHydrogen() - self.releaseHydrogen() + # 每次释放两个氢原子和一个氧原子形成水分子 + for _ in range(2): + self.releaseHydrogen() self.releaseOxygen() self.H -= 2 self.O -= 1 - + + def ok(self): - return self.H >= 2 and self.O >= 1 \ No newline at end of file + """ + Check if there are enough hydrogen and oxygen atoms to form a water molecule. + + :return: True if H >= 2 and O >= 1, otherwise False. + """ + return self.H >= 2 and self.O >= 1 diff --git a/solutions/python3/1118.py b/solutions/python3/1118.py index 94af693..0b456db 100644 --- a/solutions/python3/1118.py +++ b/solutions/python3/1118.py @@ -1,3 +1,10 @@ + class Solution: def numberOfDays(self, Y: int, M: int) -> int: - return 29 + {2: Y % (Y % 25 and 4 or 16) and -1}.get(M, ((M % 2) ^ (M > 7)) + 1) \ No newline at end of file + # 返回某年某月的天数,中文注释:计算给定年份和月份的总天数 + return 29 + {2: + # 如果是2月且不是闰年,则返回28天,英文注释:If it's February and not a leap year, return 28 days + Y % (Y % 25 and 4 or 16) and -1 + }.get(M, + # 根据月份判断是否为偶数月且不在7月之前,返回30或31天,英文注释:If the month is an even number but not before July, return 30 days; otherwise, return 31 days + ((M % 2) ^ (M > 7)) + 1) diff --git a/solutions/python3/1119.py b/solutions/python3/1119.py index 661e9bd..f257224 100644 --- a/solutions/python3/1119.py +++ b/solutions/python3/1119.py @@ -1,5 +1,10 @@ + class Solution: + # 中文注释:定义一个移除字符串中元音字母的方法 def removeVowels(self, S: str) -> str: + # 英文注释: Define a method to remove vowels from the given string return ''.join(filter(lambda x: x not in 'aeiou', S)) + + # 中文注释:等价的另一种实现方式 + # 英文注释: Another equivalent implementation using list comprehension return ''.join(c for c in S if c not in 'aeiou') - \ No newline at end of file diff --git a/solutions/python3/112.py b/solutions/python3/112.py index d8e613d..cedf682 100644 --- a/solutions/python3/112.py +++ b/solutions/python3/112.py @@ -1,18 +1,31 @@ + # Definition for a binary tree node. -# class TreeNode: -# def __init__(self, x): -# self.val = x -# self.left = None -# self.right = None +class TreeNode: + def __init__(self, x): + self.val = x + self.left = None + self.right = None class Solution: - def hasPathSum(self, root, sum): + # 检查从根节点到叶子节点的路径和是否等于给定值sum + def hasPathSum(self, root: 'TreeNode', sum: int) -> bool: """ :type root: TreeNode :type sum: int :rtype: bool + + Check if there is a path from the root to any leaf node where the sum of values equals the given sum. """ - if not root: return False - sum-=root.val - if not root.left and not root.right and sum==0: return True - return self.hasPathSum(root.left,sum) or self.hasPathSum(root.right,sum) \ No newline at end of file + # 如果根节点为空,返回False + if not root: + return False + + # 减去当前节点的值 + sum -= root.val + + # 如果到达叶子节点且路径和等于0,则找到符合条件的路径 + if not root.left and not root.right and sum == 0: + return True + + # 递归检查左子树或右子树 + return self.hasPathSum(root.left, sum) or self.hasPathSum(root.right, sum) diff --git a/solutions/python3/1120.py b/solutions/python3/1120.py index 8699c90..e29f5da 100644 --- a/solutions/python3/1120.py +++ b/solutions/python3/1120.py @@ -1,16 +1,40 @@ + # Definition for a binary tree node. -# class TreeNode: -# def __init__(self, x): -# self.val = x -# self.left = None -# self.right = None +class TreeNode: + def __init__(self, x): + self.val = x + self.left = None + self.right = None class Solution: - def maximumAverageSubtree(self, node, parent = None): - if not node: + """ + 该类用于解决二叉树子树平均值最大问题。 + """ + + def maximumAverageSubtree(self, node: TreeNode, parent=None) -> float: + """ + 计算以给定节点为中心的最大子树平均值。 + + 参数: + node (TreeNode): 当前处理的节点 + parent (TreeNode): 父节点,用于避免重复计算 + + 返回: + float: 最大子树平均值 + """ + + # 如果当前节点为空,则返回0, 0, 0 + if not node: return 0, 0, 0 + + # 递归处理左子树 lCnt, lSum, lAvg = self.maximumAverageSubtree(node.left, node) + + # 递归处理右子树 rCnt, rSum, rAvg = self.maximumAverageSubtree(node.right, node) - ret = max((node.val + lSum + rSum) / (lCnt + rCnt + 1), lAvg, rAvg) - return (lCnt + rCnt + 1, lSum + rSum + node.val, ret) if parent else ret - \ No newline at end of file + + # 计算当前节点为中心的最大平均值 + ret = max((node.val + lSum + rSum) / (lCnt + rCnt + 1), lAvg, rAvg) + + # 如果父节点为空,返回最大子树平均值;否则返回节点计数、总和和最大平均值元组 + return (lCnt + rCnt + 1, lSum + rSum + node.val, ret) if parent is None else ret diff --git a/solutions/python3/1121.py b/solutions/python3/1121.py index 1af1cf4..87999b2 100644 --- a/solutions/python3/1121.py +++ b/solutions/python3/1121.py @@ -1,3 +1,10 @@ + class Solution: + # 判断给定的序列是否可以分割成至少K个连续子序列,每个子序列包含相同的元素 + def canDivideIntoSubsequences(self, nums: List[int], K: int) -> bool: - return K * max(collections.Counter(nums).values()) <= len(nums) \ No newline at end of file + # 计算每个数字出现的最大次数 + max_count = max(collections.Counter(nums).values()) + + # 检查是否可以分割成至少K个子序列 + return K * max_count <= len(nums) diff --git a/solutions/python3/1122.py b/solutions/python3/1122.py index c3a0b40..3bc0471 100644 --- a/solutions/python3/1122.py +++ b/solutions/python3/1122.py @@ -1,3 +1,6 @@ + class Solution: + # 定义相对排序数组方法,接收两个整数列表作为输入并返回一个新列表 def relativeSortArray(self, arr1: List[int], arr2: List[int]) -> List[int]: - return sorted(arr1, key = lambda x: arr2.index(x) if x in arr2 else len(arr2) + x) \ No newline at end of file + # 对arr1进行排序,key函数根据arr2中元素的索引位置或不在arr2中的情况下使用len(arr2) + x作为键值 + return sorted(arr1, key=lambda x: arr2.index(x) if x in arr2 else len(arr2) + x) diff --git a/solutions/python3/1123.py b/solutions/python3/1123.py index 2b9d721..924c618 100644 --- a/solutions/python3/1123.py +++ b/solutions/python3/1123.py @@ -1,22 +1,30 @@ + # Definition for a binary tree node. -# class TreeNode: -# def __init__(self, x): -# self.val = x -# self.left = None -# self.right = None +class TreeNode: + def __init__(self, x): + self.val = x + self.left = None + self.right = None class Solution: + # 找到最深叶子节点的最近公共祖先 def lcaDeepestLeaves(self, root: TreeNode) -> TreeNode: + # 辅助函数,返回子树的最大深度和该最大深度下的最近公共祖先 def helper(root): if not root: - return 0, None - d1, lca1 = helper(root.left) - d2, lca2 = helper(root.right) - if d1 > d2: - node = lca1 + return 0, None # 空节点时,深度为0,公共祖先是None + + d1, lca1 = helper(root.left) # 左子树的深度与最近公共祖先 + d2, lca2 = helper(root.right) # 右子树的深度与最近公共祖先 + + if d1 > d2: # 比较左右子树的深度 + node = lca1 # 如果左子树更深,则当前节点为左子树最深叶子结点的最近公共祖先 elif d1 < d2: - node = lca2 - else: + node = lca2 # 右子树更深,右子树的情况同理 + else: # 深度相同,说明当前节点就是最深叶子节点的最近公共祖先 node = root - return max(d1, d2) + 1, node - return helper(root)[1] \ No newline at end of file + + return max(d1, d2) + 1, node # 返回较大深度加1及对应的最近公共祖先 + + # 调用辅助函数,并返回结果中的最近公共祖先 + return helper(root)[1] diff --git a/solutions/python3/1124.py b/solutions/python3/1124.py index 137845b..96c4b13 100644 --- a/solutions/python3/1124.py +++ b/solutions/python3/1124.py @@ -1,13 +1,29 @@ + class Solution: def longestWPI(self, hours: List[int]) -> int: + """ + 初始化结果和当前得分,以及一个字典用于记录分数出现的最早索引。 + + :param hours: 工作小时数列表 + :return: 最长有效工作时间间隔 + """ res = score = 0 seen = {} + + # 遍历每个工作小时数 for i, h in enumerate(hours): - score += h > 8 - score -= h < 9 + # 更新当前得分:加班加1,减班减1 + score += 1 if h > 8 else -1 + + # 如果当前得分为正,则更新最长有效间隔 if score > 0: res = i + 1 + + # 记录当前分数首次出现的索引 seen.setdefault(score, i) + + # 更新最长有效间隔:若当前得分-1在字典中存在,说明有一段得分为正 if score - 1 in seen: res = max(res, i - seen[score - 1]) - return res \ No newline at end of file + + return res diff --git a/solutions/python3/1125.py b/solutions/python3/1125.py index be09dc9..6bc9f66 100644 --- a/solutions/python3/1125.py +++ b/solutions/python3/1125.py @@ -1,16 +1,36 @@ + class Solution: def smallestSufficientTeam(self, req_skills: List[str], people: List[List[str]]) -> List[int]: - n, m = len(req_skills), len(people) - key = {v: i for i, v in enumerate(req_skills)} - dp = {0: []} + """ + 解决问题:给定一系列需求技能和一些人员,每名人员拥有一部分技能。 + 找出最少人数的团队,使得该团队拥有所有所需技能。 + + 参数: + - req_skills: 列表,表示所需的所有技能 + - people: 列表,每个元素是列表类型,表示每人掌握的技能集 + + 返回值: + - 返回一个整数列表,表示组成最小需求团队的人员索引集合 + """ + + n, m = len(req_skills), len(people) # 总需求数量和人数 + + key = {v: i for i, v in enumerate(req_skills)} # 技能到索引的映射,提高查找效率 + dp = {0: []} # 动态规划表初始化,key为技能集,value为对应人员集合 + for i, p in enumerate(people): - his_skill = 0 + his_skill = 0 # 当前人的技能状态表示 + for skill in p: - if skill in key: - his_skill |= 1 << key[skill] + if skill in key: # 只考虑当前人已掌握的需求技能 + his_skill |= 1 << key[skill] # 使用位运算更新技能状态 + for skill_set, need in list(dp.items()): - with_him = skill_set | his_skill - if with_him == skill_set: continue + with_him = skill_set | his_skill # 包含当前人的技能集合 + + if with_him == skill_set: continue # 若包含他后技能集不变则跳过 if with_him not in dp or len(dp[with_him]) > len(need) + 1: + # 更新dp表,若新方案比旧方案更优或未记录则更新 dp[with_him] = need + [i] - return dp[(1 << n) - 1] \ No newline at end of file + + return dp[(1 << n) - 1] # 返回拥有所有技能的最少人员组合 diff --git a/solutions/python3/1128.py b/solutions/python3/1128.py index 05b67b6..534d03d 100644 --- a/solutions/python3/1128.py +++ b/solutions/python3/1128.py @@ -1,3 +1,13 @@ + class Solution: + # 定义一个方法来计算等价的多米诺骨牌对数 + def numEquivDominoPairs(self, dominoes: List[List[int]]) -> int: - return sum(v * (v - 1) // 2 for v in collections.Counter(tuple(sorted(d)) for d in dominoes).values()) \ No newline at end of file + # 使用collections.Counter统计每个排序后的多米诺骨牌出现次数 + from collections import Counter + + # 对每一个多米诺骨牌进行排序,并转化为元组形式便于计数 + count = Counter(tuple(sorted(d)) for d in dominoes) + + # 计算等价的多米诺骨牌对数:v * (v - 1) // 2 是组合数学中的计算公式,用于计算v个元素两两组合的数量 + return sum(v * (v - 1) // 2 for v in count.values()) diff --git a/solutions/python3/1129.py b/solutions/python3/1129.py index 2400ec5..48b038f 100644 --- a/solutions/python3/1129.py +++ b/solutions/python3/1129.py @@ -1,18 +1,30 @@ + class Solution: def shortestAlternatingPaths(self, n: int, red_edges: List[List[int]], blue_edges: List[List[int]]) -> List[int]: + # 深度优先搜索,从当前节点i和颜色标记mod出发进行搜索 + # mod 0 表示红色边,1表示蓝色边 def dfs(i, mod, cnt): res[i][mod] = cnt for v in edge[i][mod]: if cnt < res[v][1 - mod]: dfs(v, 1 - mod, cnt + 1) + # 初始化结果数组和邻接表 res = [[float('inf'), float('inf')] for _ in range(n)] edge = [[[], []] for _ in range(n)] + + # 填充红色边的邻接表 for u, v in red_edges: edge[u][0].append(v) + + # 填充蓝色边的邻接表 for u, v in blue_edges: edge[u][1].append(v) + + # 从起始节点进行两次深度优先搜索,一次红色起点,一次蓝色起点 dfs(0, 0, 0) dfs(0, 1, 0) - return [x if x != float('inf') else -1 for x in map(min, res)] \ No newline at end of file + + # 返回结果数组中最小值或-1(表示不可达) + return [x if x != float('inf') else -1 for x in map(min, res)] diff --git a/solutions/python3/113.py b/solutions/python3/113.py index 2e3c1af..a86658b 100644 --- a/solutions/python3/113.py +++ b/solutions/python3/113.py @@ -1,21 +1,34 @@ + # Definition for a binary tree node. -# class TreeNode: -# def __init__(self, x): -# self.val = x -# self.left = None -# self.right = None +class TreeNode: + def __init__(self, x): + self.val = x + self.left = None + self.right = None class Solution: - def pathSum(self, root, sum): + # 查找二叉树中所有满足路径和等于给定值的路径 + def pathSum(self, root: 'TreeNode', sum: int) -> 'List[List[int]]': """ :type root: TreeNode :type sum: int :rtype: List[List[int]] """ - def traverse(node, q, residue, res = []): + + # 递归函数,用于遍历树并查找所有路径和等于给定值的路径 + def traverse(node, q, residue): if node: - if not node.left and not node.right and residue + node.val == sum: res.append(q + [node.val]) - traverse(node.left, q + [node.val], residue + node.val) - traverse(node.right, q + [node.val], residue + node.val) - return res - return traverse(root, [], 0) \ No newline at end of file + # 如果当前节点是叶子节点且路径和等于目标值,则将当前路径加入结果中 + if not node.left and not node.right and residue + node.val == sum: + return [q + [node.val]] + else: + # 递归遍历左子树和右子树,累加当前节点的值到路径中 + left_paths = traverse(node.left, q + [node.val], residue + node.val) + right_paths = traverse(node.right, q + [node.val], residue + node.val) + return left_paths + right_paths + else: + # 如果当前节点为空,返回空列表 + return [] + + # 从根节点开始遍历树并查找所有路径和等于给定值的路径 + return traverse(root, [], 0) diff --git a/solutions/python3/1130.py b/solutions/python3/1130.py index 264ea55..69646af 100644 --- a/solutions/python3/1130.py +++ b/solutions/python3/1130.py @@ -1,12 +1,26 @@ + class Solution: + # 定义一个类,用于解决从叶子节点值的最小乘积问题 + def mctFromLeafValues(self, A: List[int]) -> int: + # 初始化结果变量res为0,数组A长度为n res, n = 0, len(A) + + # 使用一个栈来辅助计算 stack = [float('inf')] + + # 遍历输入数组A中的每个元素a for a in A: + # 当栈顶元素小于当前元素时,进行弹出操作并累加乘积到结果中 while stack[-1] <= a: mid = stack.pop() res += mid * min(stack[-1], a) + + # 将当前元素压入栈中 stack.append(a) - while len(stack) >2: + + # 当栈中剩余两个以上元素时,继续计算乘积并累加到结果中 + while len(stack) > 2: res += stack.pop() * stack[-1] - return res \ No newline at end of file + + return res # 返回最终的结果 diff --git a/solutions/python3/1131.py b/solutions/python3/1131.py index a235703..ff663d4 100644 --- a/solutions/python3/1131.py +++ b/solutions/python3/1131.py @@ -1,14 +1,27 @@ + class Solution: + # 该方法用于计算两个数组中的最大绝对差值表达式结果 def maxAbsValExpr(self, arr1: List[int], arr2: List[int]) -> int: - l1, l2 ,l3, l4 = [], [], [], [] + + l1, l2, l3, l4 = [], [], [], [] # 初始化四个列表,分别存储不同的线性组合 + for i in range(len(arr1)): - l1 += [arr1[i]+arr2[i]+i] - l2 += [arr1[i]-arr2[i]+i] - l3 += [-arr1[i]+arr2[i]+i] - l4 += [-arr1[i]-arr2[i]+i] - res = [] - res += [max(l1)-min(l1)] - res += [max(l2) -min(l2)] - res += [max(l3)-min(l3)] - res += [max(l4)-min(l4)] - return max(res) \ No newline at end of file + # 计算第一种线性组合并添加到l1 + l1.append(arr1[i] + arr2[i] + i) + # 计算第二种线性组合并添加到l2 + l2.append(arr1[i] - arr2[i] + i) + # 计算第三种线性组合并添加到l3 + l3.append(-arr1[i] + arr2[i] + i) + # 计算第四种线性组合并添加到l4 + l4.append(-arr1[i] - arr2[i] + i) + + res = [] # 初始化结果列表 + + # 将每个列表中的最大值与最小值之差添加到结果列表中 + res.append(max(l1) - min(l1)) + res.append(max(l2) - min(l2)) + res.append(max(l3) - min(l3)) + res.append(max(l4) - min(l4)) + + # 返回结果列表中的最大值作为最终答案 + return max(res) diff --git a/solutions/python3/1133.py b/solutions/python3/1133.py index 9bab360..3a1063c 100644 --- a/solutions/python3/1133.py +++ b/solutions/python3/1133.py @@ -1,6 +1,13 @@ + class Solution: + # 定义一个类来解决寻找数组中最大唯一数字的问题 + def largestUniqueNumber(self, A: List[int]) -> int: + # 使用Counter计算每个元素的出现次数 cnt = collections.Counter(A) + + # 找出所有只出现一次的元素,并进行排序 a = sorted(k for k, v in cnt.items() if v == 1) + + # 如果有符合条件的元素,返回最大的那个;否则返回-1 return a[-1] if a else -1 - \ No newline at end of file diff --git a/solutions/python3/1134.py b/solutions/python3/1134.py index c5e5eed..f7b8608 100644 --- a/solutions/python3/1134.py +++ b/solutions/python3/1134.py @@ -1,9 +1,16 @@ + class Solution: def isArmstrong(self, N: int) -> bool: - ns = [(int(c), int(c)) for c in str(N)] - sm = sum(a for a, b in ns) + # 将数字N转换为列表ns,其中每个元素为一个元组(当前位的值,该位的幂次) + ns = [(int(c), 1) for c in str(N)] + + # 计算所有首位数之和 + sm = sum(a for a, _ in ns) + + # 当总和小于N时,更新ns中的数值并重新计算sm,直到sm >= N while sm < N: - ns = [(a * b, b) for a, b in ns] - sm = sum(a for a, b in ns) + ns = [(a ** b, b) for a, b in ns] # 更新每个数的幂次,并乘以原来的值 + sm = sum(a for a, _ in ns) + + # 检查更新后的总和是否等于N,是则为阿姆斯特朗数 return sm == N - \ No newline at end of file diff --git a/solutions/python3/1135.py b/solutions/python3/1135.py index d1d1d83..3223614 100644 --- a/solutions/python3/1135.py +++ b/solutions/python3/1135.py @@ -1,20 +1,39 @@ + class Solution: + # 定义一个类来解决最小成本问题 + def minimumCost(self, N: int, connections: List[List[int]]) -> int: + # 初始化优先队列,起点城市成本为0 heap = [(0, 1)] + + # 记录哪些城市已经被访问过 visited = [0] * (N + 1) + + # 计算结果 res = 0 + + # 构建图结构 graph = [[] for _ in range(N + 1)] for a, b, c in connections: graph[a].append([b, c]) graph[b].append([a, c]) + + # 使用优先队列进行遍历 while heap: cost, city = heapq.heappop(heap) - if visited[city]: continue + + # 如果该城市已被访问,则跳过 + if visited[city]: + continue + + # 标记已访问的城市,并将成本累加到结果中 visited[city] = 1 res += cost + + # 将未访问的邻居城市和对应的成本加入优先队列 for nCity, nCost in graph[city]: if not visited[nCity]: heapq.heappush(heap, (nCost, nCity)) + + # 检查所有城市是否都被访问过,返回结果或-1 return res if all(visited[1:]) else -1 - - \ No newline at end of file diff --git a/solutions/python3/1136.py b/solutions/python3/1136.py index c0a5a43..49eea6d 100644 --- a/solutions/python3/1136.py +++ b/solutions/python3/1136.py @@ -1,3 +1,4 @@ + class Solution: def minimumSemesters(self, N: int, relations: List[List[int]]) -> int: """ @@ -5,29 +6,46 @@ def minimumSemesters(self, N: int, relations: List[List[int]]) -> int: :type relations: List[List[int]] :rtype: int """ + + # 如果只有一个学期,直接返回1 if N == 1: return 1 - graph = collections.defaultdict(list) + + from collections import defaultdict + + # 构建有向图表示先修课程关系 + graph = defaultdict(list) for p, q in relations: graph[q-1].append(p-1) - def need_semesters(n): - if dp[n] > 0: # node was visited + def need_semesters(n: int) -> int: + """ + :param n: node index + :return: minimum semesters needed to complete all courses starting from node n + """ + if dp[n] > 0: # 节点已被访问过 return dp[n] - if dp[n] == -1: # node is being visited, there is a cycle! + if dp[n] == -1: # 正在访问该节点,存在环! return -1 - dp[n] = -1 # start visiting the node + + # 标记当前节点为正在访问状态 + dp[n] = -1 res = 0 for p in graph[n]: a = need_semesters(p) if a == -1: return -1 res = max(res, a) + + # 计算完成所有课程需要的最短学期数,并保存到dp数组中 dp[n] = res + 1 return dp[n] + # 初始化dp数组,用于记录节点状态和所需学期数 dp = [0]*N + for n in range(N): if need_semesters(n) == -1: return -1 - return max(dp) \ No newline at end of file + + return max(dp) diff --git a/solutions/python3/1137.py b/solutions/python3/1137.py index 44457ae..f796005 100644 --- a/solutions/python3/1137.py +++ b/solutions/python3/1137.py @@ -1,7 +1,14 @@ + class Solution: + # 计算第n个tribonacci数,采用迭代方式优化空间复杂度 def tribonacci(self, n: int) -> int: + # 初始化前三个tribonacci数为0, 1, 1 t0, t1, t2 = 0, 1, 1 + + # 迭代计算第n个tribonacci数 for _ in range(n): + # 更新t0, t1, t2的值,准备进行下一次迭代 t0, t1, t2 = t1, t2, t0 + t1 + t2 + + # 返回第n个tribonacci数 return t0 - \ No newline at end of file diff --git a/solutions/python3/1138.py b/solutions/python3/1138.py index 87bb56a..928db96 100644 --- a/solutions/python3/1138.py +++ b/solutions/python3/1138.py @@ -1,18 +1,25 @@ + class Solution: def alphabetBoardPath(self, target: str) -> str: + # 创建字母与坐标映射,en:创建字母到坐标映射 ind = {s: [i // 5, i % 5] for i, s in enumerate(string.ascii_lowercase)} - x = y = 0 - res = "" + + x = y = 0 # 初始化当前位置,en:初始化当前位置 + res = "" # 初始化结果字符串,en:初始化结果字符串 + for c in target: - xx, yy = ind[c] - if yy < y: - res += 'L' * (y - yy) - if xx > x: - res += 'D' * (xx - x) - if xx < x: - res += 'U' * (x - xx) - if yy > y: - res += 'R' * (yy - y) - res += '!' - x, y = xx, yy - return res \ No newline at end of file + xx, yy = ind[c] # 获取目标字母的坐标,en:获取目标字母的坐标 + + if yy < y: # 如果目标位置在当前列左侧 + res += 'L' * (y - yy) # 左移操作 + if xx > x: # 如果目标行号大于当前行号 + res += 'D' * (xx - x) # 下移操作 + if xx < x: # 如果目标行号小于当前行号 + res += 'U' * (x - xx) # 上移操作 + if yy > y: # 如果目标列号大于当前列号 + res += 'R' * (yy - y) # 右移操作 + + res += '!' # 到达目标后移动到下一个字符,en:到达目标后移动到下一个字符 + x, y = xx, yy # 更新当前位置坐标,en:更新当前位置坐标 + + return res # 返回结果字符串,en:返回结果字符串 diff --git a/solutions/python3/1139.py b/solutions/python3/1139.py index f10e2d2..0c86d77 100644 --- a/solutions/python3/1139.py +++ b/solutions/python3/1139.py @@ -1,17 +1,33 @@ + class Solution: def largest1BorderedSquare(self, A: List[List[int]]) -> int: - m, n = len(A), len(A[0]) - res = 0 - top, left = [a[:] for a in A], [a[:] for a in A] + """ + 分析: + 这个问题要求找到一个最大的只由1组成的正方形,并且该正方形的一边必须是其边界。 + 通过构建两个辅助数组top和left来记录每个位置上方和左方连续1的数量,从而可以快速判断任意大小的正方形是否满足条件。 + + :param A: List[List[int]] - 输入的二维数组 + :return: int - 最大只由1组成的正方形的面积 + """ + m, n = len(A), len(A[0]) # 获取矩阵的行数和列数 + res = 0 # 初始化结果,用于记录最大正方形边长 + + top, left = [a[:] for a in A], [a[:] for a in A] # 创建辅助数组top和left进行动态规划预处理 + + # 动态规划填充top数组 for i in range(m): for j in range(n): if A[i][j]: if i: top[i][j] = top[i - 1][j] + 1 if j: left[i][j] = left[i][j - 1] + 1 + + # 倒序遍历可能的正方形边长r for r in range(min(m, n), 0, -1): + # 检查所有可能的左上角位置(i,j) for i in range(m - r + 1): for j in range(n - r + 1): if min(top[i + r - 1][j], top[i + r - 1][j + r - 1], left[i] [j + r - 1], left[i + r - 1][j + r - 1]) >= r: - return r * r - return 0 \ No newline at end of file + return r * r # 找到符合条件的正方形,直接返回其面积 + + return 0 # 如果没有找到满足条件的正方形,则返回0 diff --git a/solutions/python3/114.py b/solutions/python3/114.py index 7d6b4c4..bf9c383 100644 --- a/solutions/python3/114.py +++ b/solutions/python3/114.py @@ -1,19 +1,32 @@ + # Definition for a binary tree node. -# class TreeNode: -# def __init__(self, x): -# self.val = x -# self.left = None -# self.right = None +class TreeNode: + def __init__(self, x): + self.val = x + self.left = None + self.right = None class Solution: + """ + 层序遍历二叉树,将每个节点的左子树移到其右子树,并断开左子树链接。 + + :type root: TreeNode + :rtype: 无返回值,直接在原树上修改 + + 中文注释: + - 定义一个辅助函数 traverse,用于递归遍历节点 + - 如果当前节点为空,则直接返回 + - 递归调用 traverse 函数处理左子树和右子树 + - 将当前节点的左子树移到右子树,并断开左子树链接 + - 返回调整后的最右侧节点 + """ def flatten(self, root): - """ - :type root: TreeNode - :rtype: void Do not return anything, modify root in-place instead. - """ + # 中文注释:开始遍历操作,修改原树结构 def traverse(node): - if not node: return - left, right = traverse(node.left), traverse(node.right) - if node.left: left.right, node.right, node.left = node.right, node.left, None - return right if right else left if left else node - traverse(root) \ No newline at end of file + if not node: return None # 如果当前节点为空,则返回None + left, right = traverse(node.left), traverse(node.right) # 递归处理左右子树 + if node.left: + node.right, node.left = node.left, None # 将左子树移到右子树,断开原左子树链接 + return right if right else left if left else node # 返回调整后的最右侧节点 + + traverse(root) # 开始遍历根节点 diff --git a/solutions/python3/1140.py b/solutions/python3/1140.py index 89ed5a9..d90690e 100644 --- a/solutions/python3/1140.py +++ b/solutions/python3/1140.py @@ -1,11 +1,24 @@ + class Solution: + # 定义石子游戏II的解决方案类 + def stoneGameII(self, A: List[int]) -> int: N = len(A) + + # 从后向前累加数组元素,使得A[i]表示从前i个元素开始可以得到的最大分数和 for i in range(N - 2, -1, -1): A[i] += A[i + 1] + from functools import lru_cache + @lru_cache(None) def dp(i, m): - if i + 2 * m >= N: return A[i] + # 如果当前索引加上m的两倍已经超过数组长度,直接返回当前累积值 + if i + 2 * m >= N: + return A[i] + + # 计算以i为起点,选择不同步长x(1到2*m)能获得的最大分数,并取最小值减去当前累加和作为结果 return A[i] - min(dp(i + x, max(m, x)) for x in range(1, 2 * m + 1)) - return dp(0, 1) \ No newline at end of file + + # 调用动态规划函数从索引0开始,初始步长为1 + return dp(0, 1) diff --git a/solutions/python3/1143.py b/solutions/python3/1143.py index 9b3a45a..3e3532f 100644 --- a/solutions/python3/1143.py +++ b/solutions/python3/1143.py @@ -1,8 +1,21 @@ + class Solution: + # 定义一个类来解决最长公共子序列问题 + def longestCommonSubsequence(self, a: str, b: str) -> int: m, n = len(a), len(b) + # 初始化动态规划表,大小为 (m+1) x (n+1),初始值为 0 dp = [[0 for j in range(n + 1)] for i in range(m + 1)] + + # 遍历字符串 a 和 b 的每个字符 for i in range(1, m + 1): for j in range(1, n + 1): - dp[i][j] = dp[i - 1][j - 1] + 1 if a[i - 1] == b[j - 1] else max(dp[i][j - 1], dp[i - 1][j]) - return dp[-1][-1] \ No newline at end of file + # 如果当前字符相同,则dp[i][j] = dp[i-1][j-1] + 1 + if a[i - 1] == b[j - 1]: + dp[i][j] = dp[i - 1][j - 1] + 1 + else: + # 否则,dp[i][j] 取上一状态的最大值 + dp[i][j] = max(dp[i][j - 1], dp[i - 1][j]) + + # 返回动态规划表右下角的值,即最长公共子序列的长度 + return dp[-1][-1] diff --git a/solutions/python3/1144.py b/solutions/python3/1144.py index 6621aee..7a10345 100644 --- a/solutions/python3/1144.py +++ b/solutions/python3/1144.py @@ -1,4 +1,10 @@ + class Solution: def movesToMakeZigzag(self, N: List[int]) -> int: + # 计算每个元素需要的移动次数使其变为zigzag模式 + # 中文注释:计算每个元素需要的移动次数使其变为zigzag模式 moves = [max(0, N[i] - min(N[i-1:i] + N[i+1:i+2]) + 1) for i in range(len(N))] - return min(sum(moves[::2]), sum(moves[1::2])) \ No newline at end of file + + # 返回使整个数组成为zigzag模式所需的最小移动次数 + # 中文注释:返回使整个数组成为zigzag模式所需的最小移动次数 + return min(sum(moves[::2]), sum(moves[1::2])) diff --git a/solutions/python3/1145.py b/solutions/python3/1145.py index 2b5104d..078d2ff 100644 --- a/solutions/python3/1145.py +++ b/solutions/python3/1145.py @@ -1,17 +1,36 @@ + # Definition for a binary tree node. -# class TreeNode: -# def __init__(self, x): -# self.val = x -# self.left = None -# self.right = None +class TreeNode: + def __init__(self, x): + self.val = x + self.left = None + self.right = None class Solution: + """ + 判断在二叉树中是否可以进行一次操作使得节点数量大于对手,从而赢得游戏。 + 传入参数包括:根节点 root、节点总数 n 和特定目标节点值 x。 + + 该方法主要逻辑如下: + - 通过递归计算每个子树的节点数 + - 找到目标节点x所在的子树,并记录左右子树的节点数量c[0]和c[1] + - 检查剩余部分(非x所在子树)的节点数是否大于等于最大子树节点数加一,以赢得游戏 + """ + def btreeGameWinningMove(self, root: TreeNode, n: int, x: int) -> bool: - c = [0, 0] + c = [0, 0] # 用于记录目标节点x所在子树的左右子树节点数量 + def count(node): - if not node: return 0 + if not node: + return 0 l, r = count(node.left), count(node.right) if node.val == x: c[0], c[1] = l, r return l + r + 1 - return count(root) // 2 < max(max(c), n - sum(c) - 1) \ No newline at end of file + + # 计算整个树的节点数,同时记录目标子树的信息 + total_nodes = count(root) + + # 判断是否可以通过增加一个节点赢得游戏 + # 需要剩余部分(非x所在子树)大于等于最大子树加一 + return total_nodes // 2 < max(max(c), n - sum(c) - 1) diff --git a/solutions/python3/1146.py b/solutions/python3/1146.py index fc74acc..d60d358 100644 --- a/solutions/python3/1146.py +++ b/solutions/python3/1146.py @@ -1,23 +1,52 @@ + class SnapshotArray: def __init__(self, length: int): - self.s = 0 - self.arr = [[[0, 0]] for i in range(length)] + """ + 初始化 SnapshotArray 类。 + + 参数: + - length:数组长度。 + """ + self.s = 0 # 当前快照序列号 + self.arr = [[[0, 0]] for _ in range(length)] # 数组初始化,每个位置为一个列表,初始值 [时间戳, 值] def set(self, index: int, val: int) -> None: - if self.s == self.arr[index][-1][0]: - self.arr[index][-1][1] = val + """ + 设置指定索引在当前快照下的值。 + + 参数: + - index:要设置的索引。 + - val:要设置的新值。 + """ + if self.s == self.arr[index][-1][0]: # 检查新值是否与最近一次快照时间戳相同 + self.arr[index][-1][1] = val # 更新现有列表项 else: - self.arr[index].append([self.s, val]) + self.arr[index].append([self.s, val]) # 添加新列表项 def snap(self) -> int: + """ + 创建并返回一个新的快照序列号。 + + 返回: + - 新的快照序列号。 + """ self.s += 1 return self.s - 1 def get(self, index: int, snap_id: int) -> int: - i = bisect.bisect_left(self.arr[index], [snap_id]) + """ + 根据索引和快照ID获取值。 + + 参数: + - index:要查询的索引。 + - snap_id:目标快照ID。 + + 返回: + - 目标快照下的值。 + """ + i = bisect.bisect_left(self.arr[index], [snap_id]) # 使用二分查找定位到最接近快照id的位置 if i < len(self.arr[index]): if self.arr[index][i][0] > snap_id: - i -= 1 - return self.arr[index][i][1] - return self.arr[index][-1][1] \ No newline at end of file + i -= 1 # 如果找到位置的值大于目标id,说明实际值在前一个位置 + return self.arr[index][i][1] # 返回对应快照下的值 diff --git a/solutions/python3/1147.py b/solutions/python3/1147.py index 238549e..9dfd915 100644 --- a/solutions/python3/1147.py +++ b/solutions/python3/1147.py @@ -1,8 +1,19 @@ + class Solution: def longestDecomposition(self, S: str) -> int: + # 初始化结果、左子串和右子串为空字符串 res, l, r = 0, "", "" - for i, j in zip(S, S[::-1]): - l, r = l + i, j + r + + # 双指针遍历,一个从前往后,一个从后往前 + for i, j in zip(S, reversed(S)): + # 动态构建左右子串 + l += i + r = j + r + + # 如果左右子串相等,则找到了一个回文分割点 if l == r: - res, l, r = res + 1, "", "" - return res \ No newline at end of file + res += 1 + # 清空左右子串,准备下次比较 + l, r = "", "" + + return res diff --git a/solutions/python3/115.py b/solutions/python3/115.py index cf3243d..b53c0af 100644 --- a/solutions/python3/115.py +++ b/solutions/python3/115.py @@ -1,8 +1,25 @@ + class Solution: - def numDistinct(self, s, t): - chars, index, dp = set(t), collections.defaultdict(list), [0] * len(t) - for i, c in enumerate(t): index[c] = [i] + index[c] + # 定义一个类来解决问题 + + def numDistinct(self, s: str, t: str) -> int: + # 构造一个集合存储字符串t中的字符,用于快速查找 + chars = set(t) + + # 使用defaultdict来存储每个字符在字符串t中出现的所有索引位置 + index = collections.defaultdict(list) + for i, c in enumerate(t): + index[c].append(i) + + # 动态规划数组初始化为0,长度等于字符串t的长度 + dp = [0] * len(t) + + # 遍历字符串s中的每个字符 for c in s: if c in chars: - for i in index[c]: dp[i] += dp[i - 1] if i > 0 else 1 - return dp[-1] \ No newline at end of file + # 如果当前字符c在集合chars中,则更新dp数组 + for i in index[c]: + dp[i] += dp[i - 1] if i > 0 else 1 + + # 返回最终结果,即最后一个元素的值 + return dp[-1] diff --git a/solutions/python3/1150.py b/solutions/python3/1150.py index 651810f..cfb93fc 100644 --- a/solutions/python3/1150.py +++ b/solutions/python3/1150.py @@ -1,4 +1,7 @@ + class Solution: + # 判断目标元素在列表中出现次数是否超过总长度的一半 + def isMajorityElement(self, nums: List[int], target: int) -> bool: + # 使用count方法统计目标值出现的次数,如果大于列表长度的一半则返回True return nums.count(target) > len(nums) // 2 - \ No newline at end of file diff --git a/solutions/python3/1151.py b/solutions/python3/1151.py index a86715e..afd08b6 100644 --- a/solutions/python3/1151.py +++ b/solutions/python3/1151.py @@ -1,10 +1,17 @@ + class Solution: + # 定义一个方法,计算将数组中所有1移至左侧所需的最小交换次数 def minSwaps(self, data: List[int]) -> int: - l = data.count(1) - mn = cur = data[:l].count(0) + + l = data.count(1) # 统计数据中1的总数 + mn = cur = data[:l].count(0) # 初始化当前窗口内0的数量 + for i in range(l, len(data)): + # 滑动窗口更新:增加新元素并移除旧元素的影响 cur += not data[i] cur -= not data[i - l] + + # 更新最小交换次数 mn = min(mn, cur) - return mn - \ No newline at end of file + + return mn # 返回最小交换次数 diff --git a/solutions/python3/1152.py b/solutions/python3/1152.py index 3531951..25b9f12 100644 --- a/solutions/python3/1152.py +++ b/solutions/python3/1152.py @@ -1,10 +1,27 @@ + class Solution: + # 定义Solution类 + def mostVisitedPattern(self, username: List[str], timestamp: List[int], website: List[str]) -> List[str]: + import collections + from itertools import combinations + + # 使用defaultdict存储每个用户的浏览网站列表 dp = collections.defaultdict(list) + + # 使用Counter统计访问模式的出现次数 count = collections.Counter() + + # 将timestamp, username, website按时间排序后遍历填充dp和count for t, u, w in sorted(zip(timestamp, username, website)): dp[u].append(w) + + # 统计每个用户的3个网站组合出现的频率 for u in dp: - count += collections.Counter(set(seq for seq in itertools.combinations(dp[u], 3))) + count += collections.Counter(set(combinations(dp[u], 3))) + + # 找到访问模式中最大的访问次数 target = max(count.values()) - return min(list(k) for k in count if count[k] == target) \ No newline at end of file + + # 返回访问次数最多的3个网站组合,取字典键值最小的一个 + return min(list(k) for k in count if count[k] == target) diff --git a/solutions/python3/1153.py b/solutions/python3/1153.py index fa5cbe3..37540b2 100644 --- a/solutions/python3/1153.py +++ b/solutions/python3/1153.py @@ -1,8 +1,22 @@ + class Solution: def canConvert(self, s1: str, s2: str) -> bool: - if s1 == s2: return True + """ + 判断s1是否可以通过重新排列字母变成s2 + + 英文注释:Determine if s1 can be rearranged to form s2. + """ + + # 如果两个字符串相同,直接返回True + if s1 == s2: + return True + dp = {} + + # 使用字典记录s1中的字符及其对应在s2中的位置 for i, j in zip(s1, s2): if dp.setdefault(i, j) != j: return False - return len(set(s2)) < 26 \ No newline at end of file + + # 如果s2中所有字符都不同,则可以转换,因为最多只有26个小写字母 + return len(set(s2)) < 26 diff --git a/solutions/python3/1154.py b/solutions/python3/1154.py index 4434ec1..06c1dad 100644 --- a/solutions/python3/1154.py +++ b/solutions/python3/1154.py @@ -1,10 +1,35 @@ + class Solution: + # 定义一个类,用于解析日期 + def dayOfYear(self, date: str) -> int: + """ + 计算给定日期在一年中的第几天 + + 参数: + date (str): 格式为 'YYYY-MM-DD' 的字符串 + + 返回: + int: 给定日期在一年中的天数 + """ + cnt = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31] + # 定义一个列表,存储每个月的天数 + y, m, d = map(int, date.split('-')) + # 将日期字符串按 '-' 分割,并转换为整数 + days = sum(cnt[:m - 1]) + d + # 计算给定月份前的所有月份总天数加上当天的天数 + if m > 2: - if y % 400 == 0: days += 1 - if y % 100 == 0: return days - if y % 4 == 0: days += 1 - return days \ No newline at end of file + # 如果月份大于2月,需要考虑闰年情况 + + if y % 400 == 0: + days += 1 # 闰年,2月有29天 + elif y % 100 == 0: + return days # 能被100整除但不能被400整除的年份不是闰年 + elif y % 4 == 0: + days += 1 # 闰年,2月有29天 + + return days diff --git a/solutions/python3/1155.py b/solutions/python3/1155.py index 7eeb723..6eb40d1 100644 --- a/solutions/python3/1155.py +++ b/solutions/python3/1155.py @@ -1,12 +1,21 @@ + class Solution: def numRollsToTarget(self, d: int, f: int, target: int) -> int: + # 定义取模常数 mod = 10 ** 9 + 7 - dp = [[0 for j in range(target + 1)] for i in range(d + 1)] + + # 初始化动态规划表,dp[i][j] 表示使用 i 个骰子达到和为 j 的方法数 + dp = [[0 for _ in range(target + 1)] for _ in range(d + 1)] + + # 初始状态:0 个骰子得到和为 0 的唯一方法是空操作 dp[0][0] = 1 - for i in range(d): - for ff in range(1, f + 1): - for sm in range(target): - if sm + ff <= target: - dp[i + 1][sm + ff] += dp[i][sm] - dp[i + 1][sm + ff] %= mod - return dp[d][target] \ No newline at end of file + + # 动态规划填充过程 + for num_dice in range(1, d + 1): + for face_value in range(1, f + 1): + for sum_val in range(target - face_value + 1): # 避免越界操作 + dp[num_dice][sum_val + face_value] += dp[num_dice - 1][sum_val] + dp[num_dice][sum_val + face_value] %= mod + + # 返回结果:使用 d 个骰子达到和为 target 的方法数 + return dp[d][target] diff --git a/solutions/python3/1156.py b/solutions/python3/1156.py index 99c2dd4..7556427 100644 --- a/solutions/python3/1156.py +++ b/solutions/python3/1156.py @@ -1,9 +1,27 @@ + class Solution: def maxRepOpt1(self, S: str) -> int: + """ + 分析字符串S,找到最长的可以替换一个字符后的连续相同字符子串长度。 + + 中文注释:分析字符串S,找到最长的可以替换一个字符后的连续相同字符子串长度。 + """ + import itertools + from collections import Counter + + # 使用groupby对字符串进行分组,并计算每个字母的连续出现次数 A = [[c, len(list(g))] for c, g in itertools.groupby(S)] - count = collections.Counter(S) + + # 计算每个字母在S中出现的总次数 + count = Counter(S) + + # 初始化结果为第一个分组的最小替换长度 res = max(min(k + 1, count[c]) for c, k in A) + + # 遍历A,检查是否可以通过替换一个字符来增加连续相同字符子串的长度 for i in range(1, len(A) - 1): if A[i - 1][0] == A[i + 1][0] and A[i][1] == 1: + # 如果当前分组中间仅有一个字符,并且前后两组字符相同,则考虑替换该单个字符 res = max(res, min(A[i - 1][1] + A[i + 1][1] + 1, count[A[i + 1][0]])) - return res \ No newline at end of file + + return res diff --git a/solutions/python3/1157.py b/solutions/python3/1157.py index 76e670e..c0337e1 100644 --- a/solutions/python3/1157.py +++ b/solutions/python3/1157.py @@ -1,17 +1,39 @@ + +from collections import defaultdict +import bisect + class MajorityChecker: def __init__(self, arr: List[int]): - self.dp = collections.defaultdict(list) + """ + 初始化数据结构,统计每个元素在数组中的位置,并按出现频率排序。 + + Parameters: + arr (List[int]): 输入的整数列表 + """ + self.dp = defaultdict(list) for i, v in enumerate(arr): self.dp[v].append(i) - self.occur = sorted([(len(v), k) for k, v in self.dp.items()], reverse = True) - + # 按出现频率从高到低排序 + self.occur = sorted([(len(v), k) for k, v in self.dp.items()], reverse=True) + def query(self, left: int, right: int, threshold: int) -> int: + """ + 查询指定范围内出现次数超过阈值的多数元素。 + + Parameters: + left (int): 范围左边界 + right (int): 范围右边界 + threshold (int): 阈值 + + Returns: + int: 返回范围内的多数元素,如果不存在则返回-1 + """ for o, v in self.occur: - if o < threshold: break + if o < threshold: break # 如果当前元素出现次数小于阈值,则直接跳出循环 l = self.dp[v] - low = bisect.bisect_left(l, left) - high = bisect.bisect_right(l, right) - if high - low >= threshold: + low = bisect.bisect_left(l, left) # 查找左边界 + high = bisect.bisect_right(l, right) # 查找右边界 + if high - low >= threshold: # 判断范围内的元素数量是否满足阈值条件 return v - return -1 \ No newline at end of file + return -1 diff --git a/solutions/python3/116.py b/solutions/python3/116.py index afbb51c..7f7b254 100644 --- a/solutions/python3/116.py +++ b/solutions/python3/116.py @@ -1,16 +1,33 @@ + class Solution: def connect(self, root: "Node") -> "Node": + """ + 连接二叉树中的节点,每个节点需指向其下一个右侧节点。 + + 参数: + root (Node): 二叉树的根节点 + + 返回值: + Node: 修改后的根节点 + """ if root == None: return root + + # 使用队列进行层次遍历,并记录上一个处理的节点及其层级位置 q, prev = [(root, 1)], None while q: curr, pos = q.pop(0) + + # 如果当前节点不是第一个处理的节点,则连接prev和当前节点 if prev != None and prev[1] == pos: prev[0].next = curr + prev = [curr, pos] + + # 将左右子节点及其层级位置加入队列 if curr.left: q.append((curr.left, pos + 1)) if curr.right: q.append((curr.right, pos + 1)) + return root - diff --git a/solutions/python3/1160.py b/solutions/python3/1160.py index ff3d005..002835e 100644 --- a/solutions/python3/1160.py +++ b/solutions/python3/1160.py @@ -1,4 +1,12 @@ + from collections import Counter as cnt + +# 中文注释:定义一个解决方案类,用于计算在给定字符中能组成的单词长度之和 class Solution: + # 英文注释: Define a solution class to calculate the sum of lengths of words that can be formed using given characters + def countCharacters(self, words: List[str], chars: str) -> int: - return sum(not cnt(w) - cnt(chars) and len(w) for w in words) \ No newline at end of file + # 中文注释:遍历每个单词,判断是否可以用给定字符组成该单词 + # 英文注释: Iterate through each word and check if it can be formed using the given characters + + return sum(not cnt(w) - cnt(chars) and len(w) for w in words) diff --git a/solutions/python3/1161.py b/solutions/python3/1161.py index 6df0108..c9ddbff 100644 --- a/solutions/python3/1161.py +++ b/solutions/python3/1161.py @@ -1,15 +1,30 @@ + # Definition for a binary tree node. -# class TreeNode: -# def __init__(self, x): -# self.val = x -# self.left = None -# self.right = None +class TreeNode: + def __init__(self, x): + self.val = x + self.left = None + self.right = None class Solution: + """ + 该类用于解决二叉树层次遍历的问题,目标是找到层次和最大的那一层。 + """ + def maxLevelSum(self, root: TreeNode) -> int: + # 初始化层级列表、当前层数l和队列q levels, l, q = [], 1, [root] + + # 当队列不为空时进行循环 while q: + # 计算当前层节点值之和,并记录该层及其层级号 levels.append([sum(node.val for node in q), l]) + + # 层数加一 l += 1 + + # 更新队列为下一层的节点列表 q = [child for node in q for child in (node.left, node.right) if child] - return sorted(levels, key = lambda x: (x[0], -x[1]))[-1][1] \ No newline at end of file + + # 对层级和进行排序,取最大值所在的层数 + return sorted(levels, key=lambda x: (x[0], -x[1]))[-1][1] diff --git a/solutions/python3/1162.py b/solutions/python3/1162.py index 9d9bcb0..e793f6c 100644 --- a/solutions/python3/1162.py +++ b/solutions/python3/1162.py @@ -1,17 +1,36 @@ + class Solution: def maxDistance(self, grid: List[List[int]]) -> int: + """ + 这个方法用来计算给定网格中两个最近陆地格子之间的最大距离。 + + :param grid: 网格,由 0 和 1 组成的二维列表 + :return: 返回两个最近陆地格子之间的最大距离 + + 思路: + 1. 使用队列进行广度优先搜索(BFS)。 + 2. 初始化一个队列 q,包含所有初始为 1 的位置坐标。 + 3. 每次从队列中取出一个元素,检查其四个方向的邻居节点。 + 4. 如果邻居是海洋(0),将其标记为陆地(1),并加入队列 Q。 + 5. 更新距离 d,并将当前队列 q 替换为新队列 Q。 + 6. 当所有位置都被访问后,返回最大距离 d。 + """ n = len(grid) + # 初始化队列 q,包含所有初始为 1 的位置坐标 q = [[i, j] for i in range(n) for j in range(n) if grid[i][j]] + d = -1 + # 当队列不为空且未访问完所有节点时 while q and len(q) != n ** 2: Q = [] for i, j in q: + # 检查四个方向的邻居节点 for x, y in (i - 1, j), (i + 1, j), (i, j - 1), (i, j + 1): - if 0 <= x < n > y >= 0 and not grid[x][y]: + if 0 <= x < n and 0 <= y < n and not grid[x][y]: + # 如果邻居是海洋,将其标记为陆地并加入队列 Q grid[x][y] = 1 Q.append([x, y]) q = Q d += 1 + return d - - \ No newline at end of file diff --git a/solutions/python3/1163.py b/solutions/python3/1163.py index 0e2ebc6..80de52d 100644 --- a/solutions/python3/1163.py +++ b/solutions/python3/1163.py @@ -1,7 +1,15 @@ + class Solution: + # 定义一个类来解决字符串相关的问题 + def lastSubstring(self, s: str) -> str: + # 初始化结果变量,用于存储最长子串 result = "" + + # 遍历字符串的每一个字符作为起始位置 for i in range(len(s)): + # 从当前索引i开始,获取后续的所有子串,并与result进行比较取最大值 result = max(result, s[i:]) + + # 返回最终找到的最大子串 return result - \ No newline at end of file diff --git a/solutions/python3/1165.py b/solutions/python3/1165.py index e630b8d..ffdbc3e 100644 --- a/solutions/python3/1165.py +++ b/solutions/python3/1165.py @@ -1,3 +1,7 @@ + class Solution: + # 计算在键盘k上按下单词word中的每个字符所需的总时间 + def calculateTime(self, k: str, word: str) -> int: - return sum(abs(k.index(a) - k.index(b)) for a, b in zip(k[0] + word, word)) \ No newline at end of file + # 使用zip将k的首字符与word的每个字符配对,计算相邻字符在键盘上的距离之和 + return sum(abs(k.index(a) - k.index(b)) for a, b in zip(k[0] + word, word)) diff --git a/solutions/python3/1166.py b/solutions/python3/1166.py index ce21f9f..6f00786 100644 --- a/solutions/python3/1166.py +++ b/solutions/python3/1166.py @@ -1,14 +1,19 @@ + class FileSystem: def __init__(self): + # 初始化文件系统,根目录的值设为-1 self.d = {"" : -1} def create(self, path: str, value: int) -> bool: + # 获取路径的父路径 parent = path[:path.rfind('/')] + # 如果存在父路径且当前路径不在字典中,则创建该路径并赋值 if parent in self.d and path not in self.d: self.d[path] = value return True return False def get(self, path: str) -> int: - return self.d.get(path, -1) \ No newline at end of file + # 根据路径获取对应的值,不存在则返回-1 + return self.d.get(path, -1) diff --git a/solutions/python3/1167.py b/solutions/python3/1167.py index 8ad4e05..395c158 100644 --- a/solutions/python3/1167.py +++ b/solutions/python3/1167.py @@ -1,10 +1,16 @@ + class Solution: def connectSticks(self, sticks: List[int]) -> int: - heapq.heapify(sticks) - res = 0 + # 使用堆来优化合并操作,中英文注释 + heapq.heapify(sticks) # 将列表转换为最小堆 + res = 0 # 记录代价 + + # 当堆中还有两个或以上元素时循环 while len(sticks) != 1: + # 弹出两个最小的棍子 new = heapq.heappop(sticks) + heapq.heappop(sticks) + # 合并后的棍子加入堆中,并累加代价 res += new heapq.heappush(sticks, new) - return res - \ No newline at end of file + + return res # 返回最终的合并代价 diff --git a/solutions/python3/1168.py b/solutions/python3/1168.py index 1a5c0b3..5612072 100644 --- a/solutions/python3/1168.py +++ b/solutions/python3/1168.py @@ -1,24 +1,33 @@ + class Solution: + # 定义一个解决方案类 + def minCostToSupplyWater(self, n: int, wells, pipes) -> int: + # 将管道成本按升序排序,并将水井的成本添加到排序中,每个水井看作是从虚拟节点0连向其编号的边 q = sorted([[w, u, v] for u, v, w in pipes] + [[w, 0, i+1] for i, w in enumerate(wells)]) + + # 初始化并查集 uf = [i for i in range(n+1)] res = count = 0 + # 并查集查找函数,返回节点的根,并进行路径压缩 def find(x): if (x != uf[x]): uf[x] = find(uf[x]) return uf[x] - + + # 并查集合并函数,将两个集合合并 def union(x, y): uf[x] = y + # 遍历排序后的边,构建最小生成树 for w, u, v in q: rA, rB = find(u), find(v) if rA == rB: - continue - union(rA, rB) + continue # 如果两个节点已经属于同一个集合,则跳过这次操作 + union(rA, rB) # 否则,合并这两个节点所在的集合,并将成本累加到结果中 res += w count += 1 - if count == n: + if count == n: # 当构建的生成树包含所有n个节点时,返回最终的成本 return res - return res \ No newline at end of file + return res # 如果未形成完整的生成树,则返回当前累加的结果 diff --git a/solutions/python3/1169.py b/solutions/python3/1169.py index d445add..0900020 100644 --- a/solutions/python3/1169.py +++ b/solutions/python3/1169.py @@ -1,17 +1,27 @@ + +from collections import defaultdict + class Solution: def invalidTransactions(self, transactions: List[str]) -> List[str]: - last = collections.defaultdict(list) - ret = set() - for n, t, a, c in sorted([t.split(',') for t in transactions], key = lambda x: int(x[1])): - if int(a) > 1000: - ret.add(','.join([n, t, a, c])) - if n in last: - for tt, aa, cc in last[n][::-1]: - if int(t) - int(tt) > 60: - break - if cc != c: - ret.add(','.join([n, tt, aa, cc])) - ret.add(','.join([n, t, a, c])) - last[n].append([t, a, c]) + # 使用字典存储每个名字的交易记录,键为名字,值为按时间排序的列表 + last = defaultdict(list) + ret = set() # 存储不合法的交易记录 + + # 按时间排序处理每笔交易 + for name, time, amount, city in sorted([t.split(',') for t in transactions], key=lambda x: int(x[1])): + if int(amount) > 1000: + ret.add(','.join([name, time, amount, city])) # 如果金额大于1000,标记交易为不合法 + + # 检查最近一笔交易是否超过60分钟 + if name in last: + for t, a, c in last[name][::-1]: + if int(time) - int(t) > 60: + break # 如果时间差超过60分钟,停止检查 + if city != c: # 如果城市不同,标记交易为不合法 + ret.add(','.join([name, t, a, c])) + ret.add(','.join([name, time, amount, city])) + + # 将当前交易记录加入到字典中 + last[name].append([time, amount, city]) + return list(ret) - \ No newline at end of file diff --git a/solutions/python3/117.py b/solutions/python3/117.py index ed95a99..8d87b9c 100644 --- a/solutions/python3/117.py +++ b/solutions/python3/117.py @@ -1,19 +1,28 @@ + class Solution: def connect(self, root: "Node") -> "Node": + # 使用虚拟节点简化链表操作,便于连接子节点 dummy = Node(-1, None, None, None) - tmp = dummy - res = root + + tmp = dummy # 暂存节点用于构建next指针 + res = root # 原始根节点 + while root: + # 遍历当前层的所有节点 while root: - if root.left: - tmp.next = root.left - tmp = tmp.next - if root.right: - tmp.next = root.right - tmp = tmp.next - root = root.next - root = dummy.next - tmp = dummy - dummy.next = None + if root.left: # 如果当前节点有左子节点 + tmp.next = root.left # 将虚拟节点的下一个指向左子节点 + tmp = tmp.next # 更新tmp到新的节点上 + + if root.right: # 如果当前节点有右子节点 + tmp.next = root.right # 将虚拟节点的下一个指向右子节点 + tmp = tmp.next # 更新tmp到新的节点上 + + root = root.next # 移动到下一节点 + + # 遍历下一层 + root = dummy.next # 从下一层的第一个节点开始 + tmp = dummy # 重置tmp为虚拟头结点 + dummy.next = None # 清空虚拟节点的next指针,准备下一次循环 - return res + return res # 返回原始根节点 diff --git a/solutions/python3/1170.py b/solutions/python3/1170.py index 3ab89dc..e21dcd0 100644 --- a/solutions/python3/1170.py +++ b/solutions/python3/1170.py @@ -1,5 +1,9 @@ + class Solution: + # 定义一个方法来计算每个单词的最小字符频率 def numSmallerByFrequency(self, queries: List[str], words: List[str]) -> List[int]: + # 对words列表中的每个字符串,找到其中出现次数最多的最小字符,并将这些值排序后存储到f中 f = sorted(w.count(min(w)) for w in words) + + # 遍历queries列表中的每个查询字符串q,计算其最小频率,并返回比它大的f的元素个数 return [len(f) - bisect.bisect(f, q.count(min(q))) for q in queries] - \ No newline at end of file diff --git a/solutions/python3/1172.py b/solutions/python3/1172.py index f0dc1f4..df401f2 100644 --- a/solutions/python3/1172.py +++ b/solutions/python3/1172.py @@ -1,40 +1,64 @@ + class DinnerPlates: def __init__(self, capacity: int): + """ + 初始化餐盘类,设置每个栈的容量capacity,并初始化空列表用于存储各个栈和可push与pop的栈索引。 + + :param capacity: 每个栈的最大容量 + """ self.c = capacity self.stacks = [] - self.l = [] # pushable - self.r = [] # poppable - + self.l = [] # 可push的栈索引堆 + self.r = [] # 可pop的栈索引堆 + def push(self, val: int) -> None: + """ + 向可用栈中push值val。 + + :param val: 要插入的整数值 + """ if not self.l: - # if the rightmost is empty, clear it from self.r + # 如果当前没有可push的栈,则从右向左检查是否有空栈,如果存在则清空并记录为poppable。 while self.r and not self.stacks[-self.r[0]]: heapq.heappop(self.r) i = 0 if not self.r else -self.r[0] + 1 self.stacks.append([val]) heapq.heappush(self.r, -i) + # 如果当前栈容量未满,则记录为可push的栈。 if len(self.stacks[i]) < self.c: heapq.heappush(self.l, i) else: i = self.l[0] - # new poppable + # 尝试从可push的最左侧栈插入元素 if not self.stacks[i]: - heapq.heappush(self.r, -i) + heapq.heappush(self.r, -i) # 如果该栈为空,则将索引记录为可pop的。 self.stacks[i].append(val) + # 如果当前栈已满,则更新可push的栈索引堆 if len(self.stacks[i]) == self.c: heapq.heappop(self.l) - + def pop(self) -> int: + """ + 从当前栈中pop最上层元素,如果无可用栈则返回-1。 + + :return: 被弹出的整数值,或-1表示没有可弹出的栈 + """ while self.r and not self.stacks[-self.r[0]]: heapq.heappop(self.r) return self.popAtStack(-self.r[0]) if self.r else -1 def popAtStack(self, index: int) -> int: + """ + 从指定栈index中pop最上层元素。 + + :param index: 要操作的栈索引 + :return: 被弹出的整数值,若该索引无效或为空,则返回-1。 + """ if index < len(self.stacks) and self.stacks[index]: ret = self.stacks[index].pop() + # 如果当前栈仍有元素可push,则更新可push的栈索引堆 if len(self.stacks[index]) == self.c - 1: heapq.heappush(self.l, index) return ret return -1 - \ No newline at end of file diff --git a/solutions/python3/1175.py b/solutions/python3/1175.py index 2f67570..f1a8b46 100644 --- a/solutions/python3/1175.py +++ b/solutions/python3/1175.py @@ -1,6 +1,13 @@ + class Solution: + # 定义一个类来解决排列问题 + def numPrimeArrangements(self, n: int) -> int: - primes = [2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,79,83,89,97] + # primes 是一个包含所有小于100的质数列表 + primes = [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97] + + # 使用二分查找确定不大于 n 的质数数量 cnt = bisect.bisect(primes, n) + + # 计算质数和非质数的排列组合数,并取模 (10 ** 9 + 7) return math.factorial(cnt) * math.factorial(n - cnt) % (10 ** 9 + 7) - \ No newline at end of file diff --git a/solutions/python3/1176.py b/solutions/python3/1176.py index 916f745..5760d57 100644 --- a/solutions/python3/1176.py +++ b/solutions/python3/1176.py @@ -1,9 +1,30 @@ + class Solution: + # 定义一个类来解决饮食计划表现问题 + def dietPlanPerformance(self, calories: List[int], k: int, lower: int, upper: int) -> int: + # 初始化滑动窗口的总热量和初始得分 sm = sum(calories[:k]) points = (sm > upper) - (sm < lower) + + # 遍历剩余的天数,更新滑动窗口内的总热量并计算得分变化 for i in range(k, len(calories)): sm += calories[i] - calories[i - k] points += (sm > upper) - (sm < lower) + + return points # 返回最终的得分 + + + +class Solution: + # 定义一个类来解决饮食计划表现问题 + + def dietPlanPerformance(self, calories: List[int], k: int, lower: int, upper: int) -> int: + sm = sum(calories[:k]) + points = (sm > upper) - (sm < lower) + + for i in range(k, len(calories)): + sm += calories[i] - calories[i - k] + points += (sm > upper) - (sm < lower) + return points - \ No newline at end of file diff --git a/solutions/python3/1177.py b/solutions/python3/1177.py index b7357a9..1aca9a7 100644 --- a/solutions/python3/1177.py +++ b/solutions/python3/1177.py @@ -1,12 +1,21 @@ + class Solution: + # 初始化计数器列表,用于记录每个子串的字符出现次数 def canMakePaliQueries(self, s: str, queries: List[List[int]]) -> List[bool]: cnts = [{}] + + # 遍历字符串s,构建每个位置的字符计数字典 for i, c in enumerate(s): cnts.append(dict(cnts[-1])) cnts[-1][c] = cnts[-1].get(c, 0) + 1 + res = [] + + # 遍历queries,检查每个子串是否可以通过修改最多k次字符变成回文 for i, j, k in queries: - res.append(sum((v - cnts[i].get(k, 0)) % 2 for k, v in cnts[j + 1].items()) - k * 2 <= 1) - return res + # 计算在j+1位置的计数器中,与i位置计数器差异的字符次数,并减去k*2 + count_diff = sum((v - cnts[i].get(k, 0)) % 2 for k, v in cnts[j + 1].items()) - k * 2 + # 如果结果小于等于1,则可以变成回文,否则不能 + res.append(count_diff <= 1) - \ No newline at end of file + return res diff --git a/solutions/python3/1178.py b/solutions/python3/1178.py index 999ce13..bd81996 100644 --- a/solutions/python3/1178.py +++ b/solutions/python3/1178.py @@ -1,5 +1,33 @@ + from itertools import combinations as cb + class Solution: + """ + 该类用于解决寻找有效单词数量的问题。 + """ + def findNumOfValidWords(self, words: List[str], puzzles: List[str]) -> List[int]: - cnt = collections.Counter(''.join(sorted(set(w))) for w in words) - return [sum(cnt[''.join(sorted(s + (p[0], )))] for l in range(len(p)) for s in cb(p[1:], l)) for p in puzzles] \ No newline at end of file + """ + 计算给定谜题中有效单词的数量。 + + 参数: + words (List[str]): 一个包含单词的列表。 + puzzles (List[str]): 一个包含谜题字符串的列表,每个谜题字符串由多个字符组成。 + + 返回: + List[int]: 每个谜题的有效单词数量列表。 + """ + from collections import Counter + + # 统计每个单词经过排序和去重后的频率 + cnt = Counter(''.join(sorted(set(w))) for w in words) + + # 计算每个谜题中的有效单词数量 + return [ + sum( + cnt[''.join(sorted(s + (p[0], )))] + for l in range(len(p)) + for s in cb(p[1:], l) + ) + for p in puzzles + ] diff --git a/solutions/python3/118.py b/solutions/python3/118.py index a8d7e7e..6ac2788 100644 --- a/solutions/python3/118.py +++ b/solutions/python3/118.py @@ -1,6 +1,18 @@ + class Solution: + # 定义一个生成杨辉三角的方法 def generate(self, numRows: int) -> List[List[int]]: + # 初始结果列表,如果numRows为正,则包含首行[1],否则为空 res = numRows and [[1]] or [] - for _ in range(numRows-1): - res.append([1] + [a + b for a, b in zip(res[-1], res[-1][1:])] + [1]) - return res \ No newline at end of file + + # 从第二行开始遍历至第numRows-1行 + for _ in range(numRows - 1): + # 每一行的第一个和最后一个元素固定为1 + row = [1] + \ + # 计算当前行的中间元素,通过前一行相邻元素之和得到 + [a + b for a, b in zip(res[-1], res[-1][1:])] + \ + [1] + # 将计算出的新行添加到结果列表中 + res.append(row) + + return res diff --git a/solutions/python3/1180.py b/solutions/python3/1180.py index 66ebb77..5c10d51 100644 --- a/solutions/python3/1180.py +++ b/solutions/python3/1180.py @@ -1,15 +1,28 @@ + class Solution: def countLetters(self, S: str) -> int: - cnt = collections.Counter() - i = res = 0 - for j, c in enumerate(S): - cnt[c] += 1 - while len(cnt) > 1: - cnt[S[i]] -= 1 - if not cnt[S[i]]: + """ + 计算字符串S中,满足条件的连续子串数量。 + + :param S: 输入的字符串 + :return: 满足条件的连续子串的数量 + + 例如:输入 "aaaba",输出为 8。解释:"aaa", "aa", "a", "a", "ba", "b" + """ + from collections import Counter + + cnt = Counter() # 使用Counter来统计字符出现次数 + i = res = 0 # 初始化索引i和结果res + + for j, c in enumerate(S): # 遍历字符串S的每个字符及其索引 + cnt[c] += 1 # 更新当前字符计数 + + while len(cnt) > 1: # 当出现多个不同的字符时,调整起始位置i + cnt[S[i]] -= 1 # 减少起始索引处字符的计数 + if not cnt[S[i]]: # 如果该字符计数为0,则移除它 cnt.pop(S[i]) - i += 1 - res += j - i + 1 + i += 1 # 起始位置i右移 + + res += j - i + 1 # 累加满足条件的子串数量 + return res - - \ No newline at end of file diff --git a/solutions/python3/1181.py b/solutions/python3/1181.py index df2b14d..205e876 100644 --- a/solutions/python3/1181.py +++ b/solutions/python3/1181.py @@ -1,16 +1,32 @@ + class Solution: + # 定义一个类来解决拼接谜题问题 + def beforeAndAfterPuzzles(self, phrases: List[str]) -> List[str]: + # 初始化结果列表 res = [] + + # 遍历每个短语对 for i in range(len(phrases)): for j in range(i + 1, len(phrases)): + # 获取第i个短语的最后一个单词 w1 = phrases[i].split()[-1] + # 获取第j个短语的第一个单词 w2 = phrases[j].split()[0] + + # 如果两个相邻短语可以拼接 if w1 == w2: + # 拼接并添加到结果中 r = phrases[i] + ' ' + ' '.join(phrases[j].split()[1:]) res.append(r.rstrip()) + + # 交换i和j的角色,再次检查拼接可能性 w1 = phrases[j].split()[-1] w2 = phrases[i].split()[0] + if w1 == w2: r = phrases[j] + ' ' + ' '.join(phrases[i].split()[1:]) res.append(r.rstrip()) - return sorted(set(res)) \ No newline at end of file + + # 去重并排序结果 + return sorted(set(res)) diff --git a/solutions/python3/1182.py b/solutions/python3/1182.py index 21b03f9..e75dc7b 100644 --- a/solutions/python3/1182.py +++ b/solutions/python3/1182.py @@ -1,8 +1,15 @@ + class Solution: def shortestDistanceColor(self, colors: List[int], queries: List[List[int]]) -> List[int]: + """ + 初始化距离数组,用于存储每个位置到最近颜色的距离。 + 1. left:从左向右遍历,计算每个位置到最近颜色的距离。 + 2. right:从右向左遍历,再次计算每个位置到最近颜色的距离,并合并结果。 + """ l1 = l2 = l3 = -1 + # 初始化距离数组left,存储到最近的三种颜色的距离 left = [[float('inf') for _ in range(3)] for __ in range(len(colors))] - res = [] + for i, c in enumerate(colors): if c == 1: l1 = i @@ -10,6 +17,8 @@ def shortestDistanceColor(self, colors: List[int], queries: List[List[int]]) -> l2 = i else: l3 = i + + # 更新left[i],如果当前颜色是1、2或3之一,则更新距离 if l1 != -1: left[i][0] = i - l1 if l2 != -1: @@ -17,8 +26,12 @@ def shortestDistanceColor(self, colors: List[int], queries: List[List[int]]) -> if l3 != -1: left[i][2] = i - l3 + # 重置位置索引,以便从右向左遍历 l1 = l2 = l3 = -1 + # 初始化距离数组right,存储到最近的三种颜色的距离 right = [[float('inf') for _ in range(3)] for __ in range(len(colors))] + + # 从右向左遍历colors列表,更新right数组 for i in range(len(colors) - 1, -1, -1): c = colors[i] if c == 1: @@ -27,17 +40,20 @@ def shortestDistanceColor(self, colors: List[int], queries: List[List[int]]) -> l2 = i else: l3 = i + + # 更新right[i],如果当前颜色是1、2或3之一,则更新距离 if l1 != -1: - right[i][0] = l1 - i + right[i][0] = l1 - i if l2 != -1: right[i][1] = l2 - i if l3 != -1: right[i][2] = l3 - i + + # 根据queries生成结果 + res = [] + for i, c in queries: + # 从left和right中选择最小距离,如果为inf则置为-1 res.append(min(left[i][c - 1], right[i][c - 1])) - return [c if c != float('inf') else -1 for c in res] - - - - \ No newline at end of file + return [c if c != float('inf') else -1 for c in res] diff --git a/solutions/python3/1184.py b/solutions/python3/1184.py index fdfaa56..1d48f25 100644 --- a/solutions/python3/1184.py +++ b/solutions/python3/1184.py @@ -1,3 +1,12 @@ + class Solution: + # 定义一个类,用于解决公交车站之间的距离问题 + def distanceBetweenBusStops(self, d: List[int], i: int, j: int) -> int: - return min(sum(d[min(i, j):max(i, j)]), sum(d[:min(i, j)] + d[max(i, j):])) \ No newline at end of file + # 计算两段路径的距离之和,并返回较小的那个值 + + # 中文注释:计算两个公交站点i和j之间较短的路径长度 + return min( + sum(d[min(i, j):max(i, j)]), # 从较小索引到较大索引之间的距离 + sum(d[:min(i, j)] + d[max(i, j):]) # 分段计算,包括两端 + ) diff --git a/solutions/python3/1185.py b/solutions/python3/1185.py index ac559ff..82dce85 100644 --- a/solutions/python3/1185.py +++ b/solutions/python3/1185.py @@ -1,4 +1,14 @@ + from datetime import date + +# Python 类定义示例,用于解决计算给定日期是星期几的问题 class Solution: def dayOfTheWeek(self, day: int, month: int, year: int) -> str: - return date(year, month, day).strftime("%A") \ No newline at end of file + """ + 计算并返回给定日期是星期几 + :param day: 日期中的日份 (int) + :param month: 日期中的月份 (int) + :param year: 日期中的年份 (int) + :return: 返回星期名称 (str),例如 'Monday', 'Tuesday' 等 + """ + return date(year, month, day).strftime("%A") diff --git a/solutions/python3/1186.py b/solutions/python3/1186.py index ba9416a..271f486 100644 --- a/solutions/python3/1186.py +++ b/solutions/python3/1186.py @@ -1,21 +1,43 @@ + class Solution: + # 定义一个辅助函数,计算累积和数组 + def cumSum(self, it): + """ + :param it: 可迭代对象,包含索引与数值对 + :return: 累积和数组 + """ + sm = mn = 0 + sums = [0] * len(arr) + for i, num in it: + sm += num + sums[i] = sm - mn + mn = min(mn, sm) + return sums + + # 计算最大子序列和 def maximumSum(self, arr: List[int]) -> int: - def cumSum(it): - sm = mn = 0 - sums = [0] * len(arr) - for i, num in it: - sm += num - sums[i] = sm - mn - mn = min(mn, sm) - return sums + """ + :param arr: 输入整数数组 + :return: 最大非连续子序列和 + + 思路:通过计算前缀最小累积和与后缀最小累积和,找到最大非连续子序列和。 + 前缀最小累积和用于处理正数的情况,后缀最小累积和用于处理负数情况。 + """ + + # 计算左半部分的累积和数组 + lSum = self.cumSum(enumerate(arr)) + + # 计算右半部分的累积和数组(逆序计算) + rSum = self.cumSum(reversed(list(enumerate(arr)))) - lSum = cumSum(enumerate(arr)) - rSum = cumSum(reversed(list(enumerate(arr)))) res = -float('inf') for i, num in enumerate(arr): if num >= 0: - cur = lSum[i] + rSum[i] - num + cur = lSum[i] + rSum[-i-1] - num else: - cur = lSum[i] + rSum[i] - 2 * num + cur = lSum[i] + rSum[-i-1] - 2 * num + res = max(res, cur) - return res if any(c >= 0 for c in arr) else max(arr) \ No newline at end of file + + # 如果数组中有非负数,则返回最大子序列和,否则返回数组中的最大值 + return res if any(c >= 0 for c in arr) else max(arr) diff --git a/solutions/python3/1187.py b/solutions/python3/1187.py index 8b102ea..2d63ba2 100644 --- a/solutions/python3/1187.py +++ b/solutions/python3/1187.py @@ -1,16 +1,35 @@ + class Solution: def makeArrayIncreasing(self, arr1: List[int], arr2: List[int]) -> int: - dp = {-1:0} - arr2.sort() + """ + arr1 和 arr2 是两个整数数组,我们需要对 arr1 进行操作使其变为严格递增序列。 + + Parameters: + - arr1: List[int] -- 第一个整数数组 + - arr2: List[int] -- 第二个整数数组 + + Returns: + int -- 返回将 arr1 变为严格递增序列所需的最小交换次数,如果无法变为递增序列则返回 -1。 + + 优化说明: + - 使用 `defaultdict` 存储动态规划状态,并利用 `bisect` 模块进行二分查找加速操作 + - 将 `arr2` 排序以提高后续二分查找效率 + """ + dp = {-1: 0} # 初始状态:-1 对应 0 次交换 + + arr2.sort() # 对 arr2 进行排序 + for i in arr1: - tmp = collections.defaultdict(lambda: float('inf')) + tmp = collections.defaultdict(lambda: float('inf')) # 初始化临时动态规划表 for key in dp: if i > key: - tmp[i] = min(tmp[i],dp[key]) - loc = bisect.bisect_right(arr2,key) + tmp[i] = min(tmp[i], dp[key]) # 当前元素直接继承上一状态的交换次数 + loc = bisect.bisect_right(arr2, key) # 找到 arr2 中大于当前值的位置 if loc < len(arr2): - tmp[arr2[loc]] = min(tmp[arr2[loc]],dp[key]+1) - dp = tmp + tmp[arr2[loc]] = min(tmp[arr2[loc]], dp[key] + 1) # 选择最优解更新临时表 + + dp = tmp # 更新动态规划状态 + if dp: - return min(dp.values()) - return -1 \ No newline at end of file + return min(dp.values()) # 返回最小的交换次数 + return -1 # 若无法变为递增序列则返回 -1 diff --git a/solutions/python3/1188.py b/solutions/python3/1188.py index ddf1203..b9c2ad1 100644 --- a/solutions/python3/1188.py +++ b/solutions/python3/1188.py @@ -1,20 +1,26 @@ + import threading +from collections import deque class BoundedBlockingQueue(object): + # 初始化阻塞队列,设置容量上限 def __init__(self, capacity: int): - self.pushing = threading.Semaphore(capacity) - self.pulling = threading.Semaphore(0) - self.queue = collections.deque() + self.pushing = threading.Semaphore(capacity) # 上限信号量 + self.pulling = threading.Semaphore(0) # 下限信号量 + self.queue = deque() # 队列 + # 入队操作,阻塞直到有空余空间 def enqueue(self, element: int) -> None: self.pushing.acquire() self.queue.append(element) self.pulling.release() - + + # 出队操作,阻塞直到有元素可取 def dequeue(self) -> int: self.pulling.acquire() self.pushing.release() return self.queue.popleft() + # 返回当前队列大小 def size(self) -> int: - return len(self.queue) \ No newline at end of file + return len(self.queue) diff --git a/solutions/python3/1189.py b/solutions/python3/1189.py index 26b01f6..2dfb726 100644 --- a/solutions/python3/1189.py +++ b/solutions/python3/1189.py @@ -1,3 +1,7 @@ + class Solution: - def maxNumberOfBalloons(self, t: str) -> int: - return min(t.count(c) // 'balloon'.count(c) for c in 'balon') \ No newline at end of file + # 定义一个方法来计算字符串中最多可以组成多少个"balloon" + + def maxNumberOfBalloons(self, text: str) -> int: + # 计算文本中每个关键字符出现的次数,并除以"balloon"中对应字符的数量 + return min(text.count(c) // 'balloon'.count(c) for c in 'ballo') diff --git a/solutions/python3/119.py b/solutions/python3/119.py index d3cb039..df95c09 100644 --- a/solutions/python3/119.py +++ b/solutions/python3/119.py @@ -1,3 +1,11 @@ + class Solution: + # 获取第 rowIndex 行的杨辉三角形行,使用递归实现 def getRow(self, rowIndex: int, row = [1]) -> List[int]: - return self.getRow(rowIndex - 1, [a + b for a, b in zip([0] + row, row + [0])]) if rowIndex else row \ No newline at end of file + # 如果当前层级为 0,则直接返回初始行 [1] + if not rowIndex: + return row + + # 否则,通过计算上一行的相邻元素和生成新行 + # 在列表推导式中使用 zip 函数将两个扩展后的列表合并,并进行累加操作 + return self.getRow(rowIndex - 1, [a + b for a, b in zip([0] + row, row + [0])]) diff --git a/solutions/python3/1190.py b/solutions/python3/1190.py index 15b2092..4e34690 100644 --- a/solutions/python3/1190.py +++ b/solutions/python3/1190.py @@ -1,12 +1,22 @@ + class Solution: + # 定义一个类来解决问题 + def reverseParentheses(self, s: str) -> str: - stack = [''] + # 实现翻转括号内的子字符串的方法 + + stack = [''] # 初始化栈,用于存储当前层的字符串片段 + for c in s: if c == '(': + # 遇到左括号时,将新的空字符串加入栈中 stack.append('') elif c == ')': + # 遇到右括号时,取出栈顶元素并翻转其内容添加回上一层的字符串片段中 add = stack.pop()[::-1] stack[-1] += add else: + # 如果是普通字符,则直接追加到当前层的字符串片段中 stack[-1] += c - return stack.pop() \ No newline at end of file + + return stack.pop() # 最终返回结果字符串 diff --git a/solutions/python3/1191.py b/solutions/python3/1191.py index 74b4bed..32d216b 100644 --- a/solutions/python3/1191.py +++ b/solutions/python3/1191.py @@ -1,8 +1,16 @@ + class Solution: - def kConcatenationMaxSum(self, arr: List[int], k: int, mod = 10 ** 9 + 7) -> int: - def Kadane(arr, res = 0, cur = 0): - for num in arr: - cur = max(num, num + cur) - res = max(res, cur) - return res - return ((k - 2) * max(sum(arr), 0) + Kadane(arr * 2) ) % mod if k > 1 else Kadane(arr) % mod \ No newline at end of file + # 定义一个求最大子数组和的Kadane算法函数 + def Kadane(self, arr, res=0, cur=0): + # 遍历数组中的每个元素 + for num in arr: + # 更新当前子数组的最大值 + cur = max(num, num + cur) + # 记录到目前为止找到的全局最大子数组和 + res = max(res, cur) + return res + + def kConcatenationMaxSum(self, arr: List[int], k: int, mod=10 ** 9 + 7) -> int: + # 如果k大于1,则将数组拼接两次并计算Kadane最大子数组和 + # 同时考虑到连续k次拼接的情况,先计算出数组元素的总和,并取其中较大的值 + return ((k - 2) * max(sum(arr), 0) + self.Kadane(arr * 2)) % mod if k > 1 else self.Kadane(arr) % mod diff --git a/solutions/python3/1196.py b/solutions/python3/1196.py index 54a847a..e6fac4b 100644 --- a/solutions/python3/1196.py +++ b/solutions/python3/1196.py @@ -1,3 +1,12 @@ + class Solution: + # 定义一个方法,计算最多可以装入多少个苹果 def maxNumberOfApples(self, arr: List[int]) -> int: - return bisect.bisect(list(itertools.accumulate(sorted(arr))), 5000) \ No newline at end of file + # 对苹果重量列表进行排序 + sorted_arr = sorted(arr) + + # 使用 accumulate 函数生成累加和的列表 + cum_sum = list(itertools.accumulate(sorted_arr)) + + # 使用 bisect 函数在累加和列表中查找第一个大于5000的位置索引,即最多可以装入多少个苹果 + return bisect.bisect(cum_sum, 5000) diff --git a/solutions/python3/1197.py b/solutions/python3/1197.py index 9fc3d25..f245092 100644 --- a/solutions/python3/1197.py +++ b/solutions/python3/1197.py @@ -1,11 +1,39 @@ + from functools import lru_cache + class Solution: def minKnightMoves(self, x: int, y: int) -> int: + """ + 计算跳马从原点移动到给定位置所需的最小步数。 + + Args: + x (int): 目标位置的x坐标 + y (int): 目标位置的y坐标 + + Returns: + int: 跳马到达目标位置所需的最小步数 + """ + @lru_cache(None) def dfs(i, j): + """ + 深度优先搜索辅助函数,计算从(x, y)移动到(0, 0)的最短路径。 + + Args: + i (int): 当前x坐标 + j (int): 当前y坐标 + + Returns: + int: 到达(0, 0)所需的步数 + """ if i == j == 0: + # 如果已经到达原点,返回0步 return 0 if i == 1 and j == 0 or j == 1 and i == 0: + # 如果距离为(1, 0)或(0, 1),无法一步到达原点,返回无穷大表示不可达 return float('inf') + # 尝试两个可能的跳跃方向,并取最小步数 return min(dfs(abs(i - 2), abs(j - 1)), dfs(abs(i - 1), abs(j - 2))) + 1 - return dfs(abs(x), abs(y)) \ No newline at end of file + + # 考虑到负坐标,转换为绝对值开始搜索 + return dfs(abs(x), abs(y)) diff --git a/solutions/python3/1198.py b/solutions/python3/1198.py index ce94114..8fe8adf 100644 --- a/solutions/python3/1198.py +++ b/solutions/python3/1198.py @@ -1,5 +1,13 @@ + from itertools import chain as chn from collections import Counter as cnt + class Solution: + # 寻找最小的共同元素 - 中文注释:寻找矩阵中所有行的最小公共元素 + def smallestCommonElement(self, mat: List[List[int]]) -> int: - return min([k for k, v in cnt(chn(*mat)).items() if v == len(mat)] or [-1]) \ No newline at end of file + # 使用Counter统计所有元素出现次数 - 中文注释:使用计数器统计所有元素出现的频率 + counts = cnt(chn(*mat)) + + # 找到出现次数等于矩阵行数的最小值 - 中文注释:找到出现次数等于矩阵行数的最小元素 + return min([k for k, v in counts.items() if v == len(mat)]) or -1 # 如果没有找到返回-1 - 英文注释: Return the smallest common element that appears in all rows, or -1 if no such element exists diff --git a/solutions/python3/1199.py b/solutions/python3/1199.py index c0b0733..0f924cb 100644 --- a/solutions/python3/1199.py +++ b/solutions/python3/1199.py @@ -1,7 +1,16 @@ + class Solution: def minBuildTime(self, A: List[int], split: int) -> int: + # 使用最小堆初始化工件列表 A heapq.heapify(A) + + # 当工件数量大于1时,不断进行合并操作 while len(A) > 1: + # 弹出两个最小的工件时间 x 和 y x, y = heapq.heappop(A), heapq.heappop(A) + + # 将新的工件时间 y + split 压入堆中 heapq.heappush(A, y + split) - return heapq.heappop(A) \ No newline at end of file + + # 最终返回剩余的单个工件的时间,即最小建造时间 + return heapq.heappop(A) diff --git a/solutions/python3/12.py b/solutions/python3/12.py index 23d445b..8b52676 100644 --- a/solutions/python3/12.py +++ b/solutions/python3/12.py @@ -1,10 +1,43 @@ + class Solution: - def intToRoman(self, num): + def intToRoman(self, num: int) -> str: + # 将千位数转换为罗马数字 s = "M" * (num // 1000) - s += "CM" if num % 1000 >= 900 else "D" *((num % 1000) // 500) - s += "CD" if num % 500 >= 400 and s[-2:] != "CM" else "C" * ((num % 500) // 100) if num % 500 < 400 else "" - s += "XC" if num % 100 >= 90 else "L" * ((num % 100) // 50) - s += "XL" if num % 50 >= 40 and s[-2:] != "XC" else "X" * ((num % 50) // 10) if num % 50 < 40 else "" - s += "IX" if num % 10 >= 9 else "V" * ((num % 10) // 5) - s += "IV" if num % 5 >= 4 and s[-2:] != "IX" else "I" * ((num % 5) // 1) if num % 5 < 4 else "" - return s \ No newline at end of file + + # 处理百位数,考虑特殊情况900和400 + if num % 1000 >= 900: + s += "CM" + else: + s += "D" * ((num % 1000) // 500) + + # 处理剩余的百位数,考虑特殊情况400和300 + if num % 500 >= 400 and s[-2:] != "CM": + s += "CD" + else: + s += "C" * ((num % 500) // 100) + + # 处理剩余的十位数,考虑特殊情况90和40 + if num % 100 >= 90: + s += "XC" + else: + s += "L" * ((num % 100) // 50) + + # 处理剩余的个位数,考虑特殊情况40和30 + if num % 50 >= 40 and s[-2:] != "XC": + s += "XL" + else: + s += "X" * ((num % 50) // 10) + + # 处理个位数,考虑特殊情况9和4 + if num % 10 >= 9: + s += "IX" + else: + s += "V" * ((num % 10) // 5) + + # 处理剩余的个位数,考虑特殊情况4 + if num % 5 >= 4 and s[-2:] != "IX": + s += "IV" + else: + s += "I" * (num % 5) + + return s diff --git a/solutions/python3/120.py b/solutions/python3/120.py index a5994ce..efd777e 100644 --- a/solutions/python3/120.py +++ b/solutions/python3/120.py @@ -1,15 +1,25 @@ + class Solution: + # 类用于解决最小路径和问题 + def minimumTotal(self, triangle): """ :type triangle: List[List[int]] :rtype: int """ - prev = None - for tri in triangle: + prev = None # 初始化前一层的节点值 + for tri in triangle: # 遍历三角形中的每一层 if prev: - for i, num in enumerate(tri): - if i >= len(prev): tri[i] += prev[i - 1] - elif i == 0: tri[i] += prev[0] - else: tri[i] += min(prev[i - 1], prev[i]) - prev = tri - return min(triangle[-1]) \ No newline at end of file + for i, num in enumerate(tri): # 遍历当前层的每个数字 + if i >= len(prev): + # 当前数字在上一层之后,只能从上一层左侧节点累加 + tri[i] += prev[i - 1] + elif i == 0: + # 当前数字为当前层第一个元素,则只可累加上一层首个元素值 + tri[i] += prev[0] + else: + # 取当前数字与上一层左侧和右侧最小值累加 + tri[i] += min(prev[i - 1], prev[i]) + prev = tri # 更新前一层为当前层 + + return min(triangle[-1]) # 返回最后一层中的最小值,即为路径和的最小值 diff --git a/solutions/python3/1200.py b/solutions/python3/1200.py index 456f512..503b42d 100644 --- a/solutions/python3/1200.py +++ b/solutions/python3/1200.py @@ -1,5 +1,11 @@ + class Solution: def minimumAbsDifference(self, arr: List[int]) -> List[List[int]]: + # 对数组进行排序,以确保相邻元素之间的差值最小化 arr.sort() + + # 计算相邻元素间的最小绝对差值 mn = min(b - a for a, b in zip(arr, arr[1:])) - return [[a, b] for a, b in zip(arr, arr[1:]) if b - a == mn] \ No newline at end of file + + # 返回所有具有该最小绝对差值的相邻元素对 + return [[a, b] for a, b in zip(arr, arr[1:]) if b - a == mn] diff --git a/solutions/python3/1201.py b/solutions/python3/1201.py index c257988..f205014 100644 --- a/solutions/python3/1201.py +++ b/solutions/python3/1201.py @@ -1,15 +1,27 @@ + class Solution: def nthUglyNumber(self, n: int, a: int, b: int, c: int) -> int: + + # 计算最大公约数 (Greatest Common Divisor) def gcd(a, b): return a if not b else gcd(b, a % b) - ab, ac, bc = a * b // gcd(a, b), a * c // gcd(a, c), b * c // gcd(b, c) + + # 计算a和b的最小公倍数 + ab = a * b // gcd(a, b) + # 计算a和c的最小公倍数 + ac = a * c // gcd(a, c) + # 计算b和c的最小公倍数 + bc = b * c // gcd(b, c) + # 计算ab、ac、bc的最小公倍数 abc = ab * c // gcd(ab, c) + + # 二分查找l到r范围内的第n个丑数 l, r = 1, 2 * 10 ** 9 while l < r: mid = (l + r) // 2 + # 计算mid包含a、b、c的倍数的数量,减去ab、ac、bc的倍数数量,加上abc的倍数数量 if mid // a + mid // b + mid // c - mid // ab - mid // ac - mid // bc + mid // abc < n: - l = mid + 1 + l = mid + 1 # 调整左边界 else: - r = mid + r = mid # 调整右边界 return l - \ No newline at end of file diff --git a/solutions/python3/1202.py b/solutions/python3/1202.py index 2e2023c..ec16625 100644 --- a/solutions/python3/1202.py +++ b/solutions/python3/1202.py @@ -1,20 +1,35 @@ + class Solution: def smallestStringWithSwaps(self, s: str, pairs: List[List[int]]) -> str: + # 使用并查集(Union-Find)来处理连接关系 class UF: - def __init__(self, n): self.p = list(range(n)) - def union(self, x, y): self.p[self.find(x)] = self.find(y) + def __init__(self, n): + self.p = list(range(n)) # 初始化父节点数组 + + def union(self, x, y): + self.p[self.find(x)] = self.find(y) # 将y的根节点作为x的根节点的父节点 + def find(self, x): - if x != self.p[x]: self.p[x] = self.find(self.p[x]) + if x != self.p[x]: + self.p[x] = self.find(self.p[x]) # 路径压缩 return self.p[x] + uf, res, m = UF(len(s)), [], collections.defaultdict(list) - for x,y in pairs: - uf.union(x,y) + + # 将指定的字符对进行合并操作 + for x, y in pairs: + uf.union(x, y) + + # 按连通分量收集字符 for i in range(len(s)): m[uf.find(i)].append(s[i]) + + # 对每个连通分量中的字符进行排序(逆序) for comp_id in m.keys(): m[comp_id].sort(reverse=True) + + # 构建结果字符串 for i in range(len(s)): res.append(m[uf.find(i)].pop()) + return ''.join(res) - - \ No newline at end of file diff --git a/solutions/python3/1203.py b/solutions/python3/1203.py index 945e914..e427dbe 100644 --- a/solutions/python3/1203.py +++ b/solutions/python3/1203.py @@ -1,5 +1,7 @@ + class Solution: def sortItems(self, n: int, m: int, group: List[int], beforeItems: List[List[int]]) -> List[int]: + # 定义拓扑排序函数 def topo_sort(points, pre, suc): order = [] sources = [p for p in points if not pre[p]] @@ -12,14 +14,15 @@ def topo_sort(points, pre, suc): sources.append(u) return order if len(order) == len(points) else [] - # find the group of each item + # 找到每个物品所属的组 group2item = collections.defaultdict(set) for i in range(n): if group[i] == -1: group[i] = m m += 1 group2item[group[i]].add(i) - # find the relationships between the groups and each items in the same group + + # 找到组与组之间以及同一组内物品之间的关系 t_pre, t_suc = collections.defaultdict(set), collections.defaultdict(set) g_pre, g_suc = collections.defaultdict(set), collections.defaultdict(set) for i in range(n): @@ -30,9 +33,11 @@ def topo_sort(points, pre, suc): else: g_pre[group[i]].add(group[j]) g_suc[group[j]].add(group[i]) - # topological sort the groups + + # 对组进行拓扑排序 groups_order = topo_sort([i for i in group2item], g_pre, g_suc) - # topological sort the items in each group + + # 对每个组内的物品进行拓扑排序 t_order = [] for i in groups_order: items = group2item[i] @@ -40,4 +45,6 @@ def topo_sort(points, pre, suc): if len(i_order) != len(items): return [] t_order += i_order - return t_order if len(t_order) == n else [] \ No newline at end of file + + return t_order if len(t_order) == n else [] + diff --git a/solutions/python3/1207.py b/solutions/python3/1207.py index 4385a18..9470c5b 100644 --- a/solutions/python3/1207.py +++ b/solutions/python3/1207.py @@ -1,4 +1,9 @@ + from collections import Counter as cnt + +# 定义解决方案类 class Solution: + # 检查给定数组中每个元素出现的次数是否唯一 def uniqueOccurrences(self, arr: List[int]) -> bool: - return all(v == 1 for v in cnt(cnt(arr).values()).values()) \ No newline at end of file + # 使用Counter统计arr中各数字的频率,再用Counter检查这些频率是否也唯一 + return all(v == 1 for v in cnt(cnt(arr).values()).values()) diff --git a/solutions/python3/1208.py b/solutions/python3/1208.py index 9330003..c86d50d 100644 --- a/solutions/python3/1208.py +++ b/solutions/python3/1208.py @@ -1,9 +1,17 @@ + class Solution: + # 定义一个类来解决字符串子串问题 + def equalSubstring(self, s: str, t: str, mx: int) -> int: i = 0 + # 初始化滑动窗口的左边界为0 for j in range(len(s)): + # 计算当前字符对之间的绝对差值,并从mx中减去 mx -= abs(ord(s[j]) - ord(t[j])) if mx < 0: + # 如果剩余的最大可承受差值小于0,说明需要缩小窗口左边界 + # 所以恢复对应的mx的消耗,并移动左边界 mx += abs(ord(s[i]) - ord(t[i])) i += 1 - return j - i + 1 \ No newline at end of file + # 返回满足条件的子串的最大长度 + return j - i + 1 diff --git a/solutions/python3/1209.py b/solutions/python3/1209.py index 3eb1128..e1aeae1 100644 --- a/solutions/python3/1209.py +++ b/solutions/python3/1209.py @@ -1,12 +1,22 @@ + class Solution: + # 定义一个类来解决去重问题 + def removeDuplicates(self, s: str, k: int) -> str: + # 初始化栈,用于记录字符及其出现次数 stack = [] + for i, c in enumerate(s): + # 如果栈为空或当前字符与栈顶字符不同,则入栈 if not stack or stack[-1][0] != c: stack.append([c, 1]) else: + # 否则,更新栈顶字符的计数 stack[-1][1] += 1 - if stack[-1][1] == k: + + # 如果当前字符重复次数达到k次,则弹出该字符记录 + if stack and stack[-1][1] == k: stack.pop() - return ''.join(k * v for k, v in stack) - \ No newline at end of file + + # 最终结果通过拼接栈中字符及其出现次数生成 + return ''.join(k * v for k, v in stack) diff --git a/solutions/python3/121.py b/solutions/python3/121.py index 409fc9f..2c5a40d 100644 --- a/solutions/python3/121.py +++ b/solutions/python3/121.py @@ -1,14 +1,22 @@ + class Solution: def maxProfit(self, prices): """ - :type prices: List[int] - :rtype: int + :type prices: List[int] # 输入参数:价格列表 + :rtype: int # 返回类型:最大利润(整数) """ - diff_list=[0,0] - for i in range (1, len(prices)): - if prices[i]-prices[i-1]+diff_list[1]>=0: - diff_list[1]=prices[i]-prices[i-1]+diff_list[1] - diff_list[0]=max(diff_list[0],diff_list[1]) + # 差分列表,初始值为0 + diff_list = [0, 0] + + for i in range(1, len(prices)): + # 判断当前价格与前一价格的差值加上前一状态的差值是否大于等于0 + if prices[i] - prices[i-1] + diff_list[1] >= 0: + # 更新当前状态为新的差值,可能包含之前的累积正收益 + diff_list[1] = prices[i] - prices[i-1] + diff_list[1] + # 更新历史最大利润 + diff_list[0] = max(diff_list[0], diff_list[1]) else: - diff_list[1]=0 - return diff_list[0] \ No newline at end of file + # 如果当前价格下降,则重置差分状态为0 + diff_list[1] = 0 + + return diff_list[0] # 返回计算得到的最大利润 diff --git a/solutions/python3/1210.py b/solutions/python3/1210.py index 064f97d..4ebeebe 100644 --- a/solutions/python3/1210.py +++ b/solutions/python3/1210.py @@ -1,28 +1,46 @@ + class Solution: def minimumMoves(self, grid: List[List[int]]) -> int: + # 初始化起始位置和移动次数,网格大小,已访问状态集合 q, move, n, seen = {(0, 1, 0)}, 0, len(grid), set() + while q: + # 创建一个新的集合来存放下一轮可到达的位置 new = set() + for i, j, hv in q: + # 到达终点且未水平移动过 if i == j == n - 1 and not hv: return move + + # 水平移动条件:下一行无障碍物 if hv and i < n - 1 and not grid[i + 1][j]: if (i + 1, j, 1) not in seen: new.add((i + 1, j, 1)) + + # 水平移动条件:右侧相邻格子无障碍物 if hv and j + 1 < n and grid[i][j + 1] == grid[i - 1][j + 1] == 0: if (i, j + 1, 1) not in seen: new.add((i, j + 1, 1)) if (i - 1, j + 1, 0) not in seen: new.add((i - 1, j + 1, 0)) + + # 竖直移动条件:右侧无障碍物 if not hv and j + 1 < n and not grid[i][j + 1]: if (i, j + 1, 0) not in seen: new.add((i, j + 1, 0)) + + # 竖直移动条件:下一行相邻格子无障碍物 if not hv and i + 1 < n and grid[i + 1][j] == grid[i + 1][j - 1] == 0: if (i + 1, j, 0) not in seen: new.add((i + 1, j, 0)) if (i + 1, j - 1, 1) not in seen: new.add((i + 1, j - 1, 1)) + + # 更新当前队列和已访问状态 q = new seen |= new + move += 1 - return -1 \ No newline at end of file + + return -1 diff --git a/solutions/python3/1213.py b/solutions/python3/1213.py index 4b821c0..bac6a6d 100644 --- a/solutions/python3/1213.py +++ b/solutions/python3/1213.py @@ -1,3 +1,6 @@ + class Solution: + # 定义一个方法,接收三个整数列表作为输入,并返回这三个列表中共有的元素列表 def arraysIntersection(self, arr1: List[int], arr2: List[int], arr3: List[int]) -> List[int]: - return sorted(set(arr1) & set(arr2) & set(arr3)) \ No newline at end of file + # 使用集合求交集以去除重复值并利用短路逻辑减少不必要的比较 + return sorted(set(arr1) & set(arr2) & set(arr3)) # 返回排序后的交集元素列表 diff --git a/solutions/python3/1214.py b/solutions/python3/1214.py index 8e1e139..97db261 100644 --- a/solutions/python3/1214.py +++ b/solutions/python3/1214.py @@ -1,18 +1,24 @@ + # Definition for a binary tree node. -# class TreeNode: -# def __init__(self, x): -# self.val = x -# self.left = None -# self.right = None +class TreeNode: + def __init__(self, x): + self.val = x + self.left = None + self.right = None + from functools import lru_cache + class Solution: + # 二叉搜索树 root1 和 root2 中是否存在两个结点,使得它们的和为 target def twoSumBSTs(self, root1: TreeNode, root2: TreeNode, target: int) -> bool: - - - - - + + # 深度优先遍历生成节点值集合 + @lru_cache(None) def dfs(node): return dfs(node.left) | dfs(node.right) | {node.val} if node else set() + + # 遍历 root1 生成的值集合 q1 = dfs(root1) - return any(target - a in q1 for a in dfs(root2)) \ No newline at end of file + + # 检查是否存在 target - a 在 q1 中,且 a 是遍历 root2 生成的值 + return any(target - a in q1 for a in dfs(root2)) diff --git a/solutions/python3/1215.py b/solutions/python3/1215.py index 3e96208..6bad174 100644 --- a/solutions/python3/1215.py +++ b/solutions/python3/1215.py @@ -1,19 +1,30 @@ + class Solution: + # 定义一个解决方案类 + def countSteppingNumbers(self, low: int, high: int) -> List[int]: + # 计算在一个给定范围内的步进数 + def dfs(n): - if n > high: - return + # 深度优先搜索,生成满足条件的步进数 + if n > high: + return # 超出上限,停止递归 + if n >= low: - q.add(n) + q.add(n) # 如果当前数字在有效范围内,则加入结果集 + d = n % 10 if d == 0: dfs(n * 10 + 1) elif d == 9: dfs(n * 10 + 8) else: - dfs(n * 10 + d + 1) + dfs(n * 10 + d + 1) dfs(n * 10 + d - 1) + # 使用集合来存储满足条件的步进数 q = set() + for i in range(10): - dfs(i) - return sorted(q) \ No newline at end of file + dfs(i) # 从0到9开始递归生成符合条件的数字 + + return sorted(q) # 返回结果,按升序排列 diff --git a/solutions/python3/1216.py b/solutions/python3/1216.py index 694ef4f..1e3eb0f 100644 --- a/solutions/python3/1216.py +++ b/solutions/python3/1216.py @@ -1,13 +1,21 @@ + class Solution: + # 判断字符串s在删除最多k个字符后是否能成为回文串 def isValidPalindrome(self, s: str, k: int) -> bool: n = len(s) - dp = [[0] * (n + 1) for _ in range(n + 1)] - for i in range(n + 1): - for j in range(n + 1): + + # 初始化动态规划表,dp[i][j]表示前i和前j个字符需要删除的最小次数使得它们相同 + dp = [[0] * (n + 1) for _ in range(n + 1)] + + # 动态规划填充 + for i in range(1, n + 1): + for j in range(1, n + 1): if not i or not j: - dp[i][j] = i or j + dp[i][j] = i or j # 边界条件:空字符串与非空字符串需要删除的字符次数 elif s[i - 1] == s[n - j]: - dp[i][j] = dp[i - 1][j - 1] + dp[i][j] = dp[i - 1][j - 1] # 字符相同,不需要额外删除 else: - dp[i][j] = 1 + min(dp[i - 1][j], dp[i][j - 1]) - return dp[n][n] <= k * 2 \ No newline at end of file + dp[i][j] = 1 + min(dp[i - 1][j], dp[i][j - 1]) # 删除一个字符的情况 + + # 如果需要删除的最小次数不大于2*k,则可以成为回文串 + return dp[n][n] <= k * 2 diff --git a/solutions/python3/1217.py b/solutions/python3/1217.py index 0ba9415..e674c2b 100644 --- a/solutions/python3/1217.py +++ b/solutions/python3/1217.py @@ -1,3 +1,18 @@ + class Solution: + # 计算将所有筹码移动到同一位置所需的最小成本 + def minCostToMoveChips(self, chips: List[int]) -> int: - return min(sum((c1 - c2) % 2 for c2 in chips) for c1 in chips) \ No newline at end of file + # 遍历每个可能的目标位置c1,计算将其余筹码移动到该位置所需的成本 + return min(sum((c1 - c2) % 2 for c2 in chips) for c1 in chips) + + + +class Solution: + # 计算将所有筹码移动到同一位置所需的最小成本 + + def minCostToMoveChips(self, chips: List[int]) -> int: + # 使用更简洁的逻辑计算所需成本,优化代码结构和性能 + odd_count = sum(1 for chip in chips if chip % 2) + even_count = len(chips) - odd_count + return min(odd_count, even_count) diff --git a/solutions/python3/1218.py b/solutions/python3/1218.py index 5c9bbe1..daf2ac2 100644 --- a/solutions/python3/1218.py +++ b/solutions/python3/1218.py @@ -1,6 +1,15 @@ + +from collections import Counter + class Solution: + # 定义一个解决方案类来解决最长等差子序列问题 def longestSubsequence(self, arr: List[int], d: int) -> int: - dp = collections.Counter() + # 使用Counter来记录以每个元素结尾的最长等差子序列长度 + dp = Counter() + for a in arr: + # 更新当前元素a在dp中的值为之前其前驱元素(a-d)对应的值+1,取最大值 dp[a] = max(dp[a], dp[a - d] + 1) - return max(dp.values()) \ No newline at end of file + + # 返回所有记录的最大值,即最长等差子序列的长度 + return max(dp.values()) diff --git a/solutions/python3/1219.py b/solutions/python3/1219.py index d66c966..d1d9501 100644 --- a/solutions/python3/1219.py +++ b/solutions/python3/1219.py @@ -1,17 +1,27 @@ + class Solution: + # 定义求最大黄金路径的方法 def getMaximumGold(self, grid: List[List[int]]) -> int: - def dfs(i, j, v): - seen.add((i, j)) - dp[i][j] = max(dp[i][j], v) - for x, y in (i - 1, j), (i + 1, j), (i, j - 1), (i, j + 1): - if 0 <= x < m and 0 <= y < n and grid[x][y] and (x, y) not in seen: - dfs(x, y, v + grid[x][y]) - seen.discard((i, j)) - m, n = len(grid), len(grid[0]) - dp = [[0] * n for _ in range(m)] + + # 深度优先搜索辅助函数,用于递归寻找路径 + def dfs(i: int, j: int, value: int) -> None: + seen.add((i, j)) # 标记当前位置已经访问过 + dp[i][j] = max(dp[i][j], value) # 更新当前位置的最大值 + + # 遍历四个方向的邻居节点 + for x, y in ((i - 1, j), (i + 1, j), (i, j - 1), (i, j + 1)): + if 0 <= x < m and 0 <= y < n and grid[x][y] > 0 and (x, y) not in seen: + dfs(x, y, value + grid[x][y]) # 继续深度优先搜索 + seen.discard((i, j)) # 从已访问集合中移除当前节点 + + m, n = len(grid), len(grid[0]) # 获取行数和列数 + dp = [[0] * n for _ in range(m)] # 初始化动态规划表 + + # 遍历整个网格,寻找起点并进行深度优先搜索 for i in range(m): for j in range(n): if grid[i][j]: - seen = set() - dfs(i, j, grid[i][j]) - return max(c for row in dp for c in row) \ No newline at end of file + seen = set() # 每次新的路径开始时清空已访问集合 + dfs(i, j, grid[i][j]) # 开始深度优先搜索 + + return max(c for row in dp for c in row) # 返回最大黄金值 diff --git a/solutions/python3/122.py b/solutions/python3/122.py index ac931a3..4ab8d9a 100644 --- a/solutions/python3/122.py +++ b/solutions/python3/122.py @@ -1,9 +1,15 @@ + class Solution: def maxProfit(self, prices: List[int]) -> int: - # stock, no stock + # 初始化状态:持有股票时的最大利润为负无穷,未持有股票时的最大利润为0 dp = [-float('inf'), 0] + + # 遍历每一天的价格 for p in prices: + # 更新持有股票和未持有股票两种状态下的最大利润 x = max(dp[1] - p, dp[0]) y = max(dp[1], dp[0] + p) dp = [x, y] - return dp[-1] \ No newline at end of file + + # 返回最后一天结束时,不持有股票的最大利润 + return dp[-1] diff --git a/solutions/python3/1220.py b/solutions/python3/1220.py index 55836b8..42c601a 100644 --- a/solutions/python3/1220.py +++ b/solutions/python3/1220.py @@ -1,24 +1,46 @@ + class Solution: def countVowelPermutation(self, n: int) -> int: + """ + 计算n个字母的元音排列数量,结果对10^9 + 7取模。 + + 参数: + n (int): 字母的数量 + + 返回值: + int: 元音排列的数量 + """ mod = 10 ** 9 + 7 + + # dp[i] 表示以第 i 个元音结尾的字符串数量(i=0:a, i=1:e, i=2:i, i=3:o, i=4:u) dp = [1] * 5 + for _ in range(n - 1): + # 初始化下一状态数组 add = [0] * 5 - # from a + + # 计算以 'a' 结尾的字符串数量,仅由上一状态 'e' 转换而来 add[1] = (add[1] + dp[0]) % mod - # from e + + # 计算以 'e' 结尾的字符串数量,可以由 'a' 或 'i' 转换而来 add[0] = (add[0] + dp[1]) % mod add[2] = (add[2] + dp[1]) % mod - # from i + + # 计算以 'i' 结尾的字符串数量,可以由 'e', 'o', 或 'u' 转换而来 add[0] = (add[0] + dp[2]) % mod add[1] = (add[1] + dp[2]) % mod add[3] = (add[3] + dp[2]) % mod add[4] = (add[4] + dp[2]) % mod - # from o + + # 计算以 'o' 结尾的字符串数量,可以由 'i' 转换而来 add[2] = (add[2] + dp[3]) % mod add[4] = (add[4] + dp[3]) % mod - # from u + + # 计算以 'u' 结尾的字符串数量,仅由上一状态 'i' 转换而来 add[0] = (add[0] + dp[4]) % mod + + # 更新当前状态为下一状态 for i in range(5): dp[i] = add[i] % mod - return sum(dp) % mod \ No newline at end of file + + return sum(dp) % mod diff --git a/solutions/python3/1221.py b/solutions/python3/1221.py index d5dfaf8..f993bc7 100644 --- a/solutions/python3/1221.py +++ b/solutions/python3/1221.py @@ -1,8 +1,20 @@ + class Solution: + # 定义一个类来解决平衡字符串分割问题 + def balancedStringSplit(self, s: str) -> int: - res = cnt = 0 + # 初始化结果计数器res和当前平衡计数器cnt为0 + res = cnt = 0 + # 遍历输入字符串s中的每一个字符c for c in s: - cnt += c == 'L' - cnt -= c == 'R' - res += cnt == 0 - return res \ No newline at end of file + # 如果字符c是'L',增加当前平衡计数器cnt + if c == 'L': + cnt += 1 + # 如果字符c是'R',减少当前平衡计数器cnt + elif c == 'R': + cnt -= 1 + # 当当前平衡计数器cnt为0时,说明找到了一个平衡的子字符串,结果计数器res加一 + if cnt == 0: + res += 1 + # 返回最终的结果计数器res,表示平衡子字符串的数量 + return res diff --git a/solutions/python3/1222.py b/solutions/python3/1222.py index 5def2be..fe9c36d 100644 --- a/solutions/python3/1222.py +++ b/solutions/python3/1222.py @@ -1,14 +1,31 @@ + class Solution: def queensAttacktheKing(self, queens: List[List[int]], king: List[int]) -> List[List[int]]: + """ + 定义一个深度优先搜索函数,用于检查每种方向上是否存在皇后。 + + :param dr: 方向增量的行变化值 + :param dc: 方向增量的列变化值 + :param r: 当前行索引 + :param c: 当前列索引 + """ def dfs(dr, dc, r, c): + # 确保在棋盘范围内 while 0 <= r <= 7 and 0 <= c <= 7: - if (r, c) in q: - res.append([r, c]) + if (r, c) in q: # 检查当前位置是否是皇后的位置 + res.append([r, c]) # 如果是,添加结果并结束搜索 break - r += dr - c += dc - q = set((r,c) for r, c in queens) - res = [] + r += dr # 向指定方向移动一行 + c += dc # 向指定方向移动一列 + + # 将所有皇后的坐标加入集合q以O(1)时间复杂度查找 + q = set((r, c) for r, c in queens) + + res = [] # 存储结果 + + # 遍历8个可能的方向 for dr, dc in (-1, -1), (-1, 0), (-1, 1), (0, 1), (1, 1), (1, 0), (1, -1), (0, -1): + # 对每个方向进行深度优先搜索,从king的位置开始 dfs(dr, dc, *king) - return res \ No newline at end of file + + return res # 返回结果列表 diff --git a/solutions/python3/1223.py b/solutions/python3/1223.py index d7ab8a8..c0cff11 100644 --- a/solutions/python3/1223.py +++ b/solutions/python3/1223.py @@ -1,11 +1,29 @@ + class Solution: def dieSimulator(self, n: int, r: List[int]) -> int: - K = max(r) - dp = [[[0 for k in range(K)] for j in range(6)] for i in range(n)] - for j in range(6): dp[0][j][0] = 1 + """ + n: 模拟投掷的次数 + r: 等概率投掷结果的最大值,即骰子面数 + + 返回:n次投掷后点数之和的所有可能组合数量对 10^9 + 7 取模的结果 + """ + + K = max(r) # 骰子最大点数 + dp = [[[0 for k in range(K)] for j in range(6)] for i in range(n)] + + # 初始化基础状态:第一次投掷每个面出现的概率为1,且点数为0的情况只有一种 + for j in range(6): + dp[0][j][0] = 1 + + # 动态规划填表过程 for i in range(1, n): for j in range(6): + # 计算当前状态在点数为0的情况下的值 dp[i][j][0] += sum(dp[i-1][t][k] for t in range(6) for k in range(r[t]) if t != j) + + # 计算当前状态在点数大于0的情况下的值,即上一次投掷的相同点数 for k in range(1, r[j]): dp[i][j][k] = dp[i-1][j][k-1] - return sum(dp[n-1][j][k] for j in range(6) for k in range(K)) % (10**9+7) \ No newline at end of file + + # 结果计算:所有可能组合数量求和对 10^9 + 7 取模 + return sum(dp[n-1][j][k] for j in range(6) for k in range(K)) % (10**9+7) diff --git a/solutions/python3/1224.py b/solutions/python3/1224.py index e2ed581..abd74a3 100644 --- a/solutions/python3/1224.py +++ b/solutions/python3/1224.py @@ -1,12 +1,25 @@ + class Solution: def maxEqualFreq(self, nums: List[int]) -> int: + """ + Solution to find the maximum integer index such that all elements in the array up to this index are equal. + + 中文注释:求解数组中从0到该索引处所有元素都相等的最大整数索引。 + """ + def okay(): + """ + Check if it's possible to make all counts of numbers equal or have only one unique count that is 1. + + 中文注释:检查是否可以通过改变使得所有数字的计数相同,或者只有一个独特的计数为1。 + """ if len(dic) == 1 and (1 in dic or 1 in dic.values()): - return True + return True if len(dic) == 2: c1, c2 = sorted(dic.keys()) if c2 - c1 == 1 and dic[c2] == 1 or (c1 == 1 and dic[1] == 1): return True + cnt = collections.Counter(nums) dic = collections.Counter(cnt.values()) l = len(nums) @@ -21,4 +34,4 @@ def okay(): dic[cnt[num]] += 1 l -= 1 if okay(): - return l \ No newline at end of file + return l diff --git a/solutions/python3/1227.py b/solutions/python3/1227.py index b624127..ee92e4d 100644 --- a/solutions/python3/1227.py +++ b/solutions/python3/1227.py @@ -1,3 +1,8 @@ + class Solution: + # 定义一个解决方案类 + def nthPersonGetsNthSeat(self, n: int) -> float: - return max(0.5, 1 / n) \ No newline at end of file + # 返回最大值,这个值要么是0.5(当n非常大时),要么是1/n的倒数 + return max(0.5, 1 / n) + # 中文注释:返回一个值,该值为0.5和1/n中的较大者。当n增大时,1/n趋近于0,因此返回值接近0.5。 diff --git a/solutions/python3/1228.py b/solutions/python3/1228.py index 9e909e3..bdbd9d6 100644 --- a/solutions/python3/1228.py +++ b/solutions/python3/1228.py @@ -1,8 +1,20 @@ + class Solution: + # 定义一个类,用于寻找数组中的缺失数字 + def missingNumber(self, arr: List[int]) -> int: - d = (arr[-1] - arr[0]) // len(arr) + """ + :param arr: 输入的整数列表 + :return: 缺失的数字 + + 该函数通过计算相邻元素之间的差值来确定缺失的数字。 + 假设给定数组为 [a0, a1, ..., an],且存在一个缺失的数字 x,则有: + - 数组的第一个和最后一个元素之间应有一个等间距 + - 在遍历过程中,如果当前元素与前一个元素之间的差值不等于该等间距,则说明缺失的数字就在它们之间 + """ + d = (arr[-1] - arr[0]) // len(arr) # 计算数组中相邻元素之间的预期差值 + for a, b in zip(arr, arr[1:]): if b != a + d: - return a + d - return 0 - \ No newline at end of file + return a + d # 返回缺失的数字 + return 0 # 如果没有找到,则返回0(假设缺失的是第一个元素) diff --git a/solutions/python3/1229.py b/solutions/python3/1229.py index d0893d4..f3881c7 100644 --- a/solutions/python3/1229.py +++ b/solutions/python3/1229.py @@ -1,11 +1,21 @@ + class Solution: def minAvailableDuration(self, s1: List[List[int]], s2: List[List[int]], d: int) -> List[int]: - s2.sort() - j = 0 - for s, e in sorted(s1): - while j < len(s2) - 1 and s2[j][1] < s: - j += 1 - if s2[j][0] <= e: - l, r = max(s, s2[j][0]), min(e,s2[j][1]) - if r - l >= d: - return [l, l + d] \ No newline at end of file + """ + 初始化s2排序,以便后续快速查找。 + :param s1: 第一个人的预约时间段列表 + :param s2: 第二个人的预约时间段列表 + :param d: 最小可用时长 + :return: 满足条件的时间段 [开始时间, 结束时间] + """ + s2.sort() # Sort s2 to enable quick lookup + + j = 0 # Pointer for iterating through sorted s2 + for start1, end1 in sorted(s1): # Iterate through each slot of s1 after sorting + while j < len(s2) - 1 and s2[j][1] < start1: + j += 1 # Skip slots in s2 that end before the current slot in s1 starts + + if s2[j][0] <= end1: # Check if there's an overlap with the current slot in s2 + left, right = max(start1, s2[j][0]), min(end1, s2[j][1]) # Determine overlapping interval + if right - left >= d: # If the interval is at least `d` units long + return [left, left + d] # Return the available slot diff --git a/solutions/python3/123.py b/solutions/python3/123.py index 84028f9..d43a4a0 100644 --- a/solutions/python3/123.py +++ b/solutions/python3/123.py @@ -1,10 +1,28 @@ + class Solution: + # 定义一个Solution类,包含买卖股票的最大利润方法 + def maxProfit(self, prices): + # 初始化四个变量:s1和s2分别代表第一笔和第二笔交易的最高利润, + # b1和b2分别表示第一笔和第二笔交易的最低买入成本 s1 = s2 = 0 b1 = b2 = -float("inf") + for p in prices: - if -p > b1: b1 = -p - if b1 + p > s1: s1 = b1 + p - if s1 - p > b2: b2 = s1 - p - if b2 + p > s2: s2 = b2 + p - return s2 \ No newline at end of file + # 更新第一次买入的成本,如果当前价格的负值大于b1,则更新b1 + if -p > b1: + b1 = -p + + # 根据之前的最低买入成本计算第一笔交易利润,并更新s1 + if b1 + p > s1: + s1 = b1 + p + + # 更新第二次买入的成本,如果在第一次卖出后的剩余金额减去当前价格大于b2,则更新b2 + if s1 - p > b2: + b2 = s1 - p + + # 根据之前的最低第二次买入成本计算第二笔交易利润,并更新s2 + if b2 + p > s2: + s2 = b2 + p + + return s2 # 返回经过两次买卖后的最大利润 diff --git a/solutions/python3/1230.py b/solutions/python3/1230.py index 4ac0e34..e8caf62 100644 --- a/solutions/python3/1230.py +++ b/solutions/python3/1230.py @@ -1,13 +1,32 @@ + class Solution: def probabilityOfHeads(self, p: List[float], t: int) -> float: - n = len(p) - dp = [[0] * (n + 1) for _ in range(n + 1)] - dp[0][0] = 1 + """ + 计算在给定每个硬币正面概率p的情况下,恰好投掷t次得到正面的概率。 + + 参数: + p: List[float] - 每个硬币投掷正面的概率列表 + t: int - 需要恰好得到的正面次数 + + 返回值: + float - 得到确切t次正面的概率 + """ + + n = len(p) # 硬币数量 + + # 初始化动态规划表,dp[i][j] 表示使用前i个硬币得到j次正面的所有可能方式的累积概率 + dp = [[0.0] * (n + 1) for _ in range(n + 1)] + dp[0][0] = 1 # 空集情况下,没有硬币时恰好得到0次正面的概率为1 + + # 动态规划计算过程 for i in range(1, n + 1): for j in range(i + 1): if j == 0: - dp[i][j] = dp[i - 1][j] * (1 - p[i - 1]) - else : + # 使用前i个硬币恰好得到0次正面,只有不使用第i个硬币的情况 + dp[i][j] = dp[i - 1][j] * (1.0 - p[i - 1]) + else: + # 使用前i个硬币恰好得到j次正面,分为两部分:第i个硬币反面和正面 dp[i][j] = (dp[i - 1][j] * (1.0 - p[i - 1])) + (dp[i - 1][j - 1] * p[i - 1]) + + # 返回最后结果,即使用所有硬币恰好得到t次正面的概率 return dp[-1][t] - \ No newline at end of file diff --git a/solutions/python3/1231.py b/solutions/python3/1231.py index 136e220..fbf1083 100644 --- a/solutions/python3/1231.py +++ b/solutions/python3/1231.py @@ -1,20 +1,26 @@ + class Solution: + # 定义一个辅助函数来检查是否可以将糖果分割成至少K+1份,每份的甜度不低于m def maximizeSweetness(self, sw: List[int], K: int) -> int: def ok(m): - c = sm = 0 - for s in sw: - sm += s - if sm >= m: - sm = 0 - c += 1 - return c >= K + 1 - l, r = 1, sum(sw) - while l < r: - m = (l + r) // 2 - if ok(m): - l = m + 1 + count = sum_ = 0 + for sweetness in sw: + sum_ += sweetness + if sum_ >= m: + sum_ = 0 + count += 1 + return count >= K + 1 + + # 初始化二分查找的左右边界 + left, right = 1, sum(sw) + + # 使用二分查找来确定最大可能的最小甜度 + while left < right: + mid = (left + right) // 2 + if ok(mid): + left = mid + 1 else: - r = m - 1 - print(l, r) - return r if ok(r) else l - 1 - \ No newline at end of file + right = mid - 1 + + print(left, right) + return right if ok(right) else left - 1 diff --git a/solutions/python3/1232.py b/solutions/python3/1232.py index f0e39a8..f4e6728 100644 --- a/solutions/python3/1232.py +++ b/solutions/python3/1232.py @@ -1,3 +1,7 @@ + class Solution: - def checkStraightLine(self, c: List[List[int]]) -> bool: - return len(set(a[0] == b[0] or (b[1] - a[1]) / (b[0] - a[0]) for a, b in zip(c, c[1:]))) == 1 \ No newline at end of file + # 检查点是否在同一直线上 + + def checkStraightLine(self, coordinates: List[List[int]]) -> bool: + # 计算每两个连续点的斜率,如果所有斜率都相等,则这些点在同一条直线上 + return len(set((b[1] - a[1]) / (b[0] - a[0]) if b[0] != a[0] else float('inf') for a, b in zip(coordinates, coordinates[1:]))) == 1 diff --git a/solutions/python3/1233.py b/solutions/python3/1233.py index 61d58db..b09e8dc 100644 --- a/solutions/python3/1233.py +++ b/solutions/python3/1233.py @@ -1,7 +1,16 @@ + class Solution: def removeSubfolders(self, folder: List[str]) -> List[str]: + # 使用集合存储所有文件夹,以提高查找效率 + # Chinese: 使用集合来存储所有的文件夹,以提高查找的效率 + st = set(folder) + for f in folder: + # 遍历每个文件夹,并检查其子路径是否也在集合中 + # Chinese: 遍历每个文件夹,并检查其子路径是否也在集合中 if any(p in st for p in itertools.accumulate(f.split('/'), lambda x, y: x + '/' + y) if p and p != f): st.discard(f) - return list(st) \ No newline at end of file + + # 返回最终的不包含子路径的文件夹列表 + return list(st) diff --git a/solutions/python3/1234.py b/solutions/python3/1234.py index bf9410a..88b7c37 100644 --- a/solutions/python3/1234.py +++ b/solutions/python3/1234.py @@ -1,11 +1,26 @@ + class Solution: + # 定义一个解决类,用于寻找平衡字符串的最小子串长度 + def balancedString(self, s: str) -> int: + # cnt: 记录每个字符需要调整的数量,初始值为最大可能值 + # i: 左边界指针 + # res: 结果,初始化为输入字符串长度 cnt, i, res = {c: max(s.count(c) - len(s) // 4, 0) for c in 'QWER'}, 0, len(s) + + # 遍历整个字符串s for j, c in enumerate(s): + # 减少当前字符需要调整的数量 cnt[c] -= 1 + + # 如果左边界指针i满足条件,则尝试收缩窗口 while i < len(s) and cnt[s[i]] < 0: cnt[s[i]] += 1 i += 1 + + # 检查当前窗口是否满足所有字符数量要求 if not any(cnt[c] > 0 for c in 'QWER'): + # 更新结果为当前最小的子串长度 res = min(res, j - i + 1) - return res \ No newline at end of file + + return res diff --git a/solutions/python3/1235.py b/solutions/python3/1235.py index 62f94c3..3dde552 100644 --- a/solutions/python3/1235.py +++ b/solutions/python3/1235.py @@ -1,9 +1,21 @@ + class Solution: + # 定义一个类来解决任务调度问题 + def jobScheduling(self, startTime: List[int], endTime: List[int], profit: List[int]) -> int: + # 将开始时间、结束时间和利润组合成元组并按结束时间排序,以优化计算 jobs = sorted(zip(startTime, endTime, profit), key=lambda v: v[1]) + + # 初始化动态规划表 dp,表示以当前时间为界的最大收益 dp = [[0, 0]] + for s, e, p in jobs: + # 使用二分查找找到第一个大于等于开始时间的结束时间的位置 i i = bisect.bisect(dp, [s + 1]) - 1 + + # 如果当前任务在之前的最大收益基础上增加的利润更大,则更新 dp 表 if dp[i][1] + p > dp[-1][1]: dp.append([e, dp[i][1] + p]) - return dp[-1][1] \ No newline at end of file + + # 返回最终的最大收益 + return dp[-1][1] diff --git a/solutions/python3/1236.py b/solutions/python3/1236.py index 86dd2e3..47e3340 100644 --- a/solutions/python3/1236.py +++ b/solutions/python3/1236.py @@ -1,21 +1,27 @@ -# """ -# This is HtmlParser's API interface. -# You should not implement it, or speculate about its implementation -# """ -#class HtmlParser(object): -# def getUrls(self, url): -# """ -# :type url: str -# :rtype List[str] -# """ class Solution: + # """ + # 这是HtmlParser的API接口。 + # 不需要实现该接口,也不应推测其实现方式。 + # """ + # class HtmlParser(object): + # def getUrls(self, url: str) -> List[str]: + # pass + def crawl(self, startUrl: str, htmlParser: 'HtmlParser') -> List[str]: - host = startUrl[:(startUrl + '/').find('/', startUrl.find('//') + 2)] + # 获取起始URL的主机名 + host = startUrl[:startUrl.find('/', startUrl.find('//') + 2)] + + # 初始化队列和已访问集合 q, seen = [startUrl], {startUrl} + + # 遍历队列中的每个URL for url in q: + # 获取当前URL的所有链接 for nex in htmlParser.getUrls(url): - if nex[:(nex + '/').find('/', nex.find('//') + 2)] == host and nex not in seen: + # 检查链接是否属于同一主机且未被访问过 + if nex[:nex.find('/', nex.find('//') + 2)] == host and nex not in seen: q.append(nex) seen.add(nex) - return q \ No newline at end of file + + return q diff --git a/solutions/python3/1237.py b/solutions/python3/1237.py index bab0ce2..987e41b 100644 --- a/solutions/python3/1237.py +++ b/solutions/python3/1237.py @@ -1,11 +1,22 @@ + from itertools import product as pr class Solution(object): + """ + Class to find solutions based on a given function and target value. + """ + def findSolution(self, customfunction, z): + """ + Find all pairs (i, j) where 1 <= i, j <= z such that customfunction.f(i, j) == z. + + :param customfunction: A callable object representing the custom function + :param z: Target value to match with the function's output + :return: List of [i, j] pairs satisfying the condition + """ return [ [i, j] for i, j in pr(range(1, z + 1), repeat=2) if customfunction.f(i, j) == z ] - diff --git a/solutions/python3/1238.py b/solutions/python3/1238.py index b70ed27..d8a7342 100644 --- a/solutions/python3/1238.py +++ b/solutions/python3/1238.py @@ -1,3 +1,15 @@ + class Solution: + # Python 解法 - 循环排列 + def circularPermutation(self, n: int, start: int) -> List[int]: + """ + :param n: 整数,表示数组的长度(2^n) + :param start: 开始的整数值 + :return: 返回一个从start开始的循环排列数组 + + 优化说明: + - 使用列表推导式替代for循环以简化代码 + - 通过位运算生成循环排列结果,提高计算效率 + """ return [start ^ i ^ i >> 1 for i in range(1 << n)] diff --git a/solutions/python3/1239.py b/solutions/python3/1239.py index f8d8521..05fce46 100644 --- a/solutions/python3/1239.py +++ b/solutions/python3/1239.py @@ -1,6 +1,13 @@ + class Solution: def maxLength(self, arr: List[str]) -> int: + # 初始化队列,包含空字符串 bfs = [""] + + # 过滤掉不包含重复字符的字符串 for b in filter(lambda x: len(x) == len(set(x)), arr): + # 构造新字符串,并加入队列中 bfs += [a + b for a in bfs if not set(a) & set(b)] + + # 返回最长字符串的长度 return max(map(len, bfs)) diff --git a/solutions/python3/124.py b/solutions/python3/124.py index 5add729..15e1ec7 100644 --- a/solutions/python3/124.py +++ b/solutions/python3/124.py @@ -1,11 +1,25 @@ + class Solution: def maxPathSum(self, root): + # 初始化结果为负无穷,用于存储最大路径和 res = [-float("inf")] + + # 定义深度优先搜索函数 def dfs(node): - if not node: return -float("inf") + if not node: + # 如果节点为空,返回-无穷 + return -float("inf") + l, r = dfs(node.left), dfs(node.right) + # 计算以当前节点为根的最大路径和 mx = max(node.val, l + node.val, r + node.val) + # 更新全局最大路径和 res[0] = max(res[0], mx, node.val + l + r) + # 返回包含单边子树的最大路径和 return mx + + # 从根节点开始深度优先搜索 dfs(root) - return res[0] \ No newline at end of file + + # 返回计算得到的最大路径和 + return res[0] diff --git a/solutions/python3/1240.py b/solutions/python3/1240.py index afb36a4..c4f5976 100644 --- a/solutions/python3/1240.py +++ b/solutions/python3/1240.py @@ -1,20 +1,38 @@ + class Solution: memo = {} def tilingRectangle(self, n: int, m: int) -> int: + # 如果 (n, m) 为特定值 (11, 13 或 13, 11),直接返回预设结果 if (n, m) in {(11, 13), (13, 11)}: return 6 + + # 当 n 和 m 相等时,只需一个矩形即可覆盖整个区域 if n == m: return 1 + + # 如果缓存中没有该次计算的结果,则进行递归计算并存储结果 if (n, m) not in self.memo: - nMin = mMin = float("inf") + # 初始化最小值为正无穷大 + nMin = float("inf") + mMin = float("inf") + + # 横向分割,寻找最优解 for i in range(1, n // 2 + 1): nMin = min( - nMin, self.tilingRectangle(i, m) + self.tilingRectangle(n - i, m) + nMin, + self.tilingRectangle(i, m) + self.tilingRectangle(n - i, m) ) + + # 纵向分割,寻找最优解 for j in range(1, m // 2 + 1): mMin = min( - mMin, self.tilingRectangle(n, j) + self.tilingRectangle(n, m - j) + mMin, + self.tilingRectangle(n, j) + self.tilingRectangle(n, m - j) ) + + # 将 (n, m) 的最小覆盖次数存入缓存中 self.memo[(n, m)] = min(nMin, mMin) + + # 返回缓存中的结果 return self.memo[(n, m)] diff --git a/solutions/python3/1243.py b/solutions/python3/1243.py index 4ec2ebf..136e873 100644 --- a/solutions/python3/1243.py +++ b/solutions/python3/1243.py @@ -1,13 +1,20 @@ + class Solution: + # 定义一个解决方案类 + def transformArray(self, arr: List[int], change: bool = True) -> List[int]: + # 传入数组和是否进行变换的标志,默认为True + while change: + # 当change为True时,继续执行变换 new = ( - arr[:1] + arr[:1] # 复制数组的第一个元素作为新的数组开头 + [ b + (a > b < c) - (a < b > c) for a, b, c in zip(arr, arr[1:], arr[2:]) - ] - + arr[-1:] + ] # 对中间部分应用变换规则生成新值 + + arr[-1:] # 复制数组的最后一个元素作为新的数组结尾 ) + # 更新arr和change标志 arr, change = new, arr != new - return arr + return arr # 返回最终变换后的数组 diff --git a/solutions/python3/1244.py b/solutions/python3/1244.py index edf6a52..0631558 100644 --- a/solutions/python3/1244.py +++ b/solutions/python3/1244.py @@ -1,25 +1,35 @@ + +import collections + class Leaderboard: + + # 初始化 leaderboard,使用 defaultdict 来存储玩家分数和对应的 player ID 集合 def __init__(self): - self.scores = collections.defaultdict(set) - self.p = collections.defaultdict(int) + self.scores = collections.defaultdict(set) # 存储分数及其对应 players 的集合 + self.p = collections.defaultdict(int) # 存储每个玩家的当前分数 + # 添加分数,更新玩家的分数,并在适当的位置插入新的分数 def addScore(self, playerId: int, score: int) -> None: - self.scores[self.p[playerId]].discard(playerId) - self.p[playerId] += score - self.scores[self.p[playerId]].add(playerId) + current_score = self.p[playerId] # 获取当前分数 + self.scores[current_score].discard(playerId) # 从旧分数集合中移除玩家ID + self.p[playerId] += score # 更新玩家的分数 + self.scores[self.p[playerId]].add(playerId) # 将玩家加入新分数对应的集合 + # 返回前 K 名玩家的总分,按分数降序排列 def top(self, K: int) -> int: sm = cnt = 0 - for score, players in sorted(self.scores.items())[::-1]: - if len(players) + cnt <= K: - sm += len(players) * score - cnt += len(players) + for score, players in sorted(self.scores.items())[::-1]: # 按分数降序遍历 scores + if len(players) + cnt <= K: # 如果当前玩家数量加上累计数量小于等于K + sm += len(players) * score # 累加总分 + cnt += len(players) # 更新累计计数 else: - sm += (K - cnt) * score - cnt = K + sm += (K - cnt) * score # 计算剩余部分的分数并累加 + cnt = K # 累计数量达到K,退出循环 return sm + # 重置玩家分数为0,并将其加入到分数为0的集合中 def reset(self, playerId: int) -> None: - self.scores[self.p[playerId]].discard(playerId) - self.p[playerId] = 0 - self.scores[0].add(playerId) + current_score = self.p[playerId] # 获取当前分数 + self.scores[current_score].discard(playerId) # 从旧分数集合中移除玩家ID + self.p[playerId] = 0 # 重置玩家分数为0 + self.scores[0].add(playerId) # 将玩家加入到分数为0的集合 diff --git a/solutions/python3/1245.py b/solutions/python3/1245.py index a16260a..196d78e 100644 --- a/solutions/python3/1245.py +++ b/solutions/python3/1245.py @@ -1,13 +1,22 @@ + class Solution: + # 计算树的最大直径 def treeDiameter(self, edges: List[List[int]], move: int = 0) -> int: + # 构建无向图的邻接表表示 graph = collections.defaultdict(set) for a, b in edges: graph[a].add(b) graph[b].add(a) + + # 初始化bfs集合,包含所有度为1的节点及其父节点 bfs = {(u, None) for u, nex in graph.items() if len(nex) == 1} + + # 进行广度优先搜索,逐步扩展到最远端点 while bfs: bfs, move = ( - {(v, u) for u, pre in bfs for v in graph[u] if v != pre}, - move + 1, + {(v, u) for u, pre in bfs for v in graph[u] if v != pre}, # 更新bfs集合为下一层节点 + move + 1, # 深度加一 ) + + # 返回最大深度减1作为直径(树的直径等于最远两点间的距离) return max(move - 1, 0) diff --git a/solutions/python3/1246.py b/solutions/python3/1246.py index d2ce928..2425888 100644 --- a/solutions/python3/1246.py +++ b/solutions/python3/1246.py @@ -1,18 +1,37 @@ + class Solution: def minimumMoves(self, arr: List[int]) -> int: - n = len(arr) - dp = [[0] * (n + 1) for _ in range(n + 1)] - for l in range(1, n + 1): - i, j = 0, l - 1 - while j < n: + """ + 计算最小移动次数使得数组中的元素相等 + + 参数: + arr (List[int]): 输入的整数列表 + + 返回值: + int: 使数组中所有元素相等所需的最小移动次数 + """ + + n = len(arr) # 数组长度 + dp = [[0] * (n + 1) for _ in range(n + 1)] # 动态规划表,初始化为全零 + + for l in range(1, n + 1): # 遍历子数组的长度 + i, j = 0, l - 1 # 子数组左右边界 + + while j < n: # 确保右边界在数组范围内 if l == 1: - dp[i][j] = 1 + dp[i][j] = 1 # 单个元素不需要移动 + else: + # 计算当前子数组的最小移动次数 dp[i][j] = 1 + dp[i + 1][j] - if arr[i] == arr[i + 1]: - dp[i][j] = min(1 + dp[i + 2][j], dp[i][j]) + + if arr[i] == arr[i + 1]: # 检查首尾元素是否相等 + dp[i][j] = min(1 + dp[i + 2][j], dp[i][j]) # 动态规划转移方程 + for k in range(i + 2, j + 1): - if arr[i] == arr[k]: - dp[i][j] = min(dp[i + 1][k - 1] + dp[k + 1][j], dp[i][j]) - i, j = i + 1, j + 1 - return dp[0][n - 1] + if arr[i] == arr[k]: # 检查是否存在相等元素 + dp[i][j] = min(dp[i + 1][k - 1] + dp[k + 1][j], dp[i][j]) # 动态规划转移方程 + + i, j = i + 1, j + 1 # 移动左右边界 + + return dp[0][n - 1] # 返回最终结果 diff --git a/solutions/python3/1247.py b/solutions/python3/1247.py index e8055fe..0439890 100644 --- a/solutions/python3/1247.py +++ b/solutions/python3/1247.py @@ -1,6 +1,25 @@ + class Solution: + # 定义一个类用于解决交换字符串最小次数的问题 + def minimumSwap(self, s1: str, s2: str, xy: int = 0, yx: int = 0) -> int: + """ + 计算将s1和s2转换为完全相同的两个字符串所需的最少交换次数。 + + 参数: + s1 (str): 第一个输入字符串 + s2 (str): 第二个输入字符串 + xy (int, optional): "x" 和 "y" 之间的互换计数. 默认为0。 + yx (int, optional): "y" 和 "x" 之间的互换计数. 默认为0。 + + 返回: + int: 如果可以通过最少交换次数使两个字符串相同,则返回该次数,否则返回-1 + """ + + # 使用zip函数将s1和s2的对应字符两两配对比较 for a, b in zip(s1, s2): - xy += a == "x" and b == "y" - yx += a == "y" and b == "x" + xy += a == "x" and b == "y" # 如果当前字符匹配xy模式,则计数xy + yx += a == "y" and b == "x" # 如果当前字符匹配yx模式,则计数yx + + # 计算总交换次数和是否可以成功转换 return (xy + yx) // 2 + (xy % 2) * 2 if xy % 2 == yx % 2 else -1 diff --git a/solutions/python3/1248.py b/solutions/python3/1248.py index 1baab49..348e5f1 100644 --- a/solutions/python3/1248.py +++ b/solutions/python3/1248.py @@ -1,8 +1,12 @@ + class Solution: + # 定义一个方法,计算数组中满足条件的子数组数量 def numberOfSubarrays(self, nums: List[int], k: int, cnt: int = 0) -> int: - odds = [-1] + [i for i, num in enumerate(nums) if num % 2] + [len(nums)] + # 构建奇数索引列表,包括哨兵元素-1和len(nums) + odds = [-1] + [i for i, num in enumerate(nums) if num % 2 == 1] + [len(nums)] + + # 计算符合条件的子数组数量 return sum( (odds[j - k + 1] - odds[j - k]) * (odds[j + 1] - odds[j]) for j in range(k, len(odds) - 1) ) - diff --git a/solutions/python3/1249.py b/solutions/python3/1249.py index acdb868..227be39 100644 --- a/solutions/python3/1249.py +++ b/solutions/python3/1249.py @@ -1,13 +1,19 @@ + class Solution: - def minRemoveToMakeValid( - self, s: str, res: str = "", l: str = "(", r: str = ")", b: int = 0 - ) -> str: - for _ in range(2): - for c in s: + # 初始化解决方案类 + + def minRemoveToMakeValid(self, s: str, res: str = "", l: str = "(", r: str = ")", b: int = 0) -> str: + # 方法:移除最少的字符以使字符串有效(中英文双语注释) + + for _ in range(2): # 循环两次,第一次正序处理,第二次逆序处理 + for c in s: # 遍历字符串s中的每个字符c if c == r and b <= 0: - continue - b += c == l - b -= c == r - res += c + continue # 如果当前字符是右括号且剩余的左括号数为零,则跳过 + b += c == l # 当前字符是左括号时,增加剩余左括号数量b + b -= c == r # 当前字符是右括号时,减少剩余左括号数量b + res += c # 将当前字符添加到结果字符串res中 + + # 重置状态变量并逆序处理字符串s res, s, l, r, b = "", res[::-1], r, l, 0 - return s + + return s # 返回最终的有效字符串 diff --git a/solutions/python3/125.py b/solutions/python3/125.py index 91855bf..5f814ab 100644 --- a/solutions/python3/125.py +++ b/solutions/python3/125.py @@ -1,8 +1,16 @@ + class Solution: def isPalindrome(self, s): """ - :type s: str - :rtype: bool + :type s: str # 输入字符串s + :rtype: bool # 返回值为布尔类型,表示是否为回文串 + + 判断给定的字符串s是否是回文串。 """ import string - return True if s=="" or [i.lower() for i in s if i in string.digits or i in string.ascii_letters]==[i.lower() for i in s if i in string.digits or i in string.ascii_letters][::-1] else False \ No newline at end of file + + # 过滤出字符串中的字母和数字,并转换成小写 + filtered_chars = [char.lower() for char in s if char in string.ascii_letters or char in string.digits] + + # 检查过滤后的字符列表是否与其反转相同 + return filtered_chars == filtered_chars[::-1] diff --git a/solutions/python3/1250.py b/solutions/python3/1250.py index 9735377..6e25dea 100644 --- a/solutions/python3/1250.py +++ b/solutions/python3/1250.py @@ -1,6 +1,9 @@ -from functools import reduce +from functools import reduce +import math +# 判断一个数组中的所有整数是否可以通过某种组合方式使得它们的最大公约数为1 class Solution: - def isGoodArray(self, nums: List[int]) -> bool: + def isGoodArray(self, nums: list[int]) -> bool: + # 使用reduce函数和math.gcd计算数组中所有元素的最大公约数,如果结果为1,则返回True,否则返回False return reduce(math.gcd, nums) == 1 diff --git a/solutions/python3/1252.py b/solutions/python3/1252.py index e330cd5..be2e63f 100644 --- a/solutions/python3/1252.py +++ b/solutions/python3/1252.py @@ -1,7 +1,14 @@ + from collections import Counter as cnt class Solution: + # 定义一个类来解决奇数格子问题 + def oddCells(self, n: int, m: int, indices: List[List[int]]) -> int: - row, col = cnt(r for r, c in indices), cnt(c for r, c in indices) + # 计算在指定行和列中被修改的次数 + row = cnt(r for r, c in indices) # 统计每一行被修改的次数 + col = cnt(c for r, c in indices) # 统计每一列被修改的次数 + + # 遍历所有可能的 (i,j) 对,计算奇数格子的数量 return sum((row[i] + col[j]) % 2 for i in range(n) for j in range(m)) diff --git a/solutions/python3/1253.py b/solutions/python3/1253.py index 774259a..2c46a5a 100644 --- a/solutions/python3/1253.py +++ b/solutions/python3/1253.py @@ -1,22 +1,38 @@ + class Solution: def reconstructMatrix( self, upper: int, lower: int, colsum: List[int] ) -> List[List[int]]: - res = [[0] * len(colsum) for _ in range(2)] + """ + 构造一个2行colsum长度的矩阵,使得每列的和符合给定的upper和lower限制 + + :param upper: 上半部分的目标和 + :param lower: 下半部分的目标和 + :param colsum: 每列目标和组成的列表 + :return: 符合条件的2行矩阵,否则返回空列表 + """ + res = [[0] * len(colsum) for _ in range(2)] # 初始化结果矩阵 + for j, sm in enumerate(colsum): if sm == 2: + # 当列和为2时,同时填充上半部分和下半部分 if upper == 0 or lower == 0: - return [] + return [] # 如果某一部分已经无法满足要求,则直接返回空列表 upper -= 1 lower -= 1 res[0][j] = res[1][j] = 1 - elif sm: + + elif sm: # 当列和大于0时,根据上下部分剩余容量选择填充位置 if upper == lower == 0: - return [] + return [] # 如果剩余容量都为0,则直接返回空列表 + if upper >= lower: + # 尽可能多地填满上半部分 upper -= 1 res[0][j] = 1 else: + # 剩余填充下半部分 lower -= 1 res[1][j] = 1 - return res if upper == lower == 0 else [] + + return res if upper == lower == 0 else [] # 检查是否所有容量都已满足,否则返回空列表 diff --git a/solutions/python3/1254.py b/solutions/python3/1254.py index bb4597a..e738d23 100644 --- a/solutions/python3/1254.py +++ b/solutions/python3/1254.py @@ -1,15 +1,21 @@ + class Solution: + # 定义深度优先搜索函数,检查封闭岛屿,并返回结果 def closedIsland(self, grid: List[List[int]]) -> int: def dfs(i, j, ret=True): + # 标记当前节点为已访问 grid[i][j] = -1 + # 遍历四个方向的邻居节点 for x, y in (i - 1, j), (i + 1, j), (i, j - 1), (i, j + 1): if 0 <= x < m and 0 <= y < n: + # 如果邻居节点为未访问,继续深度优先搜索 if not grid[x][y]: ret &= dfs(x, y) else: + # 邻居节点越界,标记结果为False ret = False return ret m, n = len(grid), len(grid[0]) + # 计算封闭岛屿的数量 return sum(dfs(i, j) for i in range(m) for j in range(n) if grid[i][j] == 0) - diff --git a/solutions/python3/1255.py b/solutions/python3/1255.py index 33957c0..ee2ede2 100644 --- a/solutions/python3/1255.py +++ b/solutions/python3/1255.py @@ -1,18 +1,25 @@ + from collections import Counter as cnt class Solution: - def maxScoreWords(self, w: List[str], l: List[str], s: List[int]) -> int: + # 定义深度优先搜索函数,用于递归寻找最大得分单词组合 + def maxScoreWords(self, w: List[str], l: List[int], s: List[int]) -> int: + # 从给定的字母限制中计算初始使用情况 + use = cnt(l) + + # 定义深度优先搜索辅助函数 def dfs(use, i): + # 如果当前状态有效且未遍历完单词列表,则递归处理 return ( - use - and i < len(w) + use and i < len(w) and max( - dfs(use, i + 1), - not cnt(w[i]) - use - and sum(s[ord(c) - ord("a")] for c in w[i]) - + dfs(use - cnt(w[i]), i + 1), + dfs(use, i + 1), # 不使用当前单词的情况 + not cnt(w[i]) - use # 检查当前单词是否可由剩余字母构成 + and sum(s[ord(c) - ord("a")] for c in w[i]) # 计算当前单词得分 + + dfs(use - cnt(w[i]), i + 1) # 更新使用情况并递归处理下一个单词 ) ) - return int(dfs(cnt(l), 0)) + # 初始调用深度优先搜索,传入初始状态和起始索引0 + return int(dfs(use, 0)) diff --git a/solutions/python3/1256.py b/solutions/python3/1256.py index df29e76..2f56d13 100644 --- a/solutions/python3/1256.py +++ b/solutions/python3/1256.py @@ -1,3 +1,7 @@ + class Solution: + # 中文注释:实现整数到二进制字符串的编码,去掉前导'0b'和第一个字符'1' + # English comment: Implement integer to binary string encoding, removing the leading '0b' and the first character '1' + def encode(self, num: int) -> str: return bin(num + 1)[3:] diff --git a/solutions/python3/1257.py b/solutions/python3/1257.py index 0897457..2bbe827 100644 --- a/solutions/python3/1257.py +++ b/solutions/python3/1257.py @@ -1,10 +1,19 @@ + class Solution: + # 寻找两个区域中的最小共同祖先 + def findSmallestRegion( self, regions: List[List[str]], region1: str, region2: str ) -> str: + # 构建从子区域指向父区域的映射 nex = {r: region[0] for region in regions for r in region[1:]} + + # 初始化起始地区 r1, r2 = region1, region2 + + # 循环直到找到共同祖先 while r1 != r2: - r1 = nex[r1] if r1 in nex else region2 - r2 = nex[r2] if r2 in nex else region1 - return r1 + r1 = nex[r1] if r1 in nex else region2 # 如果r1没有父节点,则移动到region2所在的分支 + r2 = nex[r2] if r2 in nex else region1 # 同上 + + return r1 # 返回共同祖先 diff --git a/solutions/python3/1258.py b/solutions/python3/1258.py index 9548c3d..62ccd81 100644 --- a/solutions/python3/1258.py +++ b/solutions/python3/1258.py @@ -1,13 +1,25 @@ + class Solution: def generateSentences(self, synonyms: List[List[str]], text: str) -> List[str]: + # 查找根节点的递归函数 def root(s): + # 如果当前字符串是其自身的父节点,说明它已经是根节点 return s if parent[s] == s else root(parent[s]) + # 初始化并查集中的每个单词及其自身作为父节点 parent = {s: s for s in [c for sy in synonyms for c in sy] + text.split()} + + # 合并同义词的根节点 for a, b in synonyms: parent[root(a)] = root(b) + + # BFS初始化,初始为空字符串列表 bfs = [""] + + # 对于每个单词,查找其根节点,并构建新的句子组合 for t in text.split(): r = root(t) bfs = [s + " " + w for s in bfs for w in parent if root(w) == r] + + # 返回所有可能的句子组合并排序 return sorted(s[1:] for s in bfs) diff --git a/solutions/python3/1259.py b/solutions/python3/1259.py index 25be930..4f8cf6d 100644 --- a/solutions/python3/1259.py +++ b/solutions/python3/1259.py @@ -1,9 +1,30 @@ + class Solution: - def numberOfWays(self, num_people): + def numberOfWays(self, num_people: int) -> int: + """ + 计算将num_people个人分成若干对的方法数。 + + 参数: + num_people (int): 人数 + + 返回: + int: 分法数量 + """ + self.memo = {0: 1} - def dp(n): + def dp(n: int) -> int: + """ + 动态规划计算n个人的分法数量. + + 参数: + n (int): 人数 + + 返回: + int: 分法数量 + """ if n not in self.memo: + # 计算所有可能的方式,并取模10^9 + 7以防止溢出 self.memo[n] = sum( [dp(i - 2) * dp(n - i) for i in range(2, n + 1, 2)] ) % (10 ** 9 + 7) diff --git a/solutions/python3/126.py b/solutions/python3/126.py index 3806d26..d5c8488 100644 --- a/solutions/python3/126.py +++ b/solutions/python3/126.py @@ -1,18 +1,34 @@ + class Solution: - def findLadders(self, beginWord, endWord, wordList): + def findLadders(self, beginWord: str, endWord: str, wordList: list) -> list: + """ + 寻找最短转换序列,将 beginWord 变换为 endWord,并且每次只能改变一个字母。 + + :param beginWord: 初始单词 + :param endWord: 目标单词 + :param wordList: 可用的单词列表 + :return: 从 beginWord 到 endWord 的最短转换序列,如果没有找到,则返回空列表 + """ words, res, layer = set(wordList), [], {beginWord: [[beginWord]]} + + # 当当前层不为空时继续执行 while layer: newlayer = collections.defaultdict(list) + for w in layer: - if w == endWord: - for arr in layer[w]: - res.append(arr) + # 如果找到目标单词,将路径添加到结果中 + if w == endWord: + res.extend(layer[w]) else: + # 构造新的候选单词,并更新下一层 for i in range(len(w)): for c in string.ascii_lowercase: neww = w[:i] + c + w[i + 1:] if neww in words: - newlayer[neww] += [j + [neww] for j in layer[w]] + newlayer[neww].extend([j + [neww] for j in layer[w]]) + # 更新可使用的单词集 words -= set(newlayer.keys()) + # 进入下一层 layer = newlayer - return res \ No newline at end of file + + return res diff --git a/solutions/python3/1260.py b/solutions/python3/1260.py index 8f03e9d..7349016 100644 --- a/solutions/python3/1260.py +++ b/solutions/python3/1260.py @@ -1,7 +1,14 @@ + class Solution: def shiftGrid(self, grid: List[List[int]], k: int) -> List[List[int]]: + # 将二维列表展平为一维列表 chain = [r for row in grid for r in row] + + # 计算实际需要右移的步数,避免不必要的大循环 k %= len(chain) + + # 右移操作:将链表分为两部分,后k个元素移动到前面 chain = chain[-k:] + chain[:-k] + + # 将一维列表重新组织为二维列表 return [chain[i : i + len(grid[0])] for i in range(0, len(chain), len(grid[0]))] - diff --git a/solutions/python3/1261.py b/solutions/python3/1261.py index ae7f6bc..3cb39d2 100644 --- a/solutions/python3/1261.py +++ b/solutions/python3/1261.py @@ -1,15 +1,19 @@ + class FindElements: + # 初始化方法,用于设置根节点和存储结果的集合 + def __init__(self, root: TreeNode): + self.root = root # 根节点初始化 + self.nums = set() # 存储处理后的值的集合 + self.dfs(root) # 调用dfs方法进行后续处理 + + # 深度优先搜索方法,用于递归地为树中的每个节点赋值并存储其值 def dfs(self, node: TreeNode, real: int = 0): if node: - node.val = real - self.nums.add(node.val) - self.dfs(node.left, real * 2 + 1) - self.dfs(node.right, real * 2 + 2) - - def __init__(self, root: TreeNode): - self.root = root - self.nums = set() - self.dfs(root) + node.val = real # 设置当前节点的值 + self.nums.add(node.val) # 将该节点的值加入集合中 + self.dfs(node.left, real * 2 + 1) # 递归处理左子节点 + self.dfs(node.right, real * 2 + 2) # 递归处理右子节点 + # 查找方法,检查给定的目标值是否存在于结果集合中 def find(self, target: int) -> bool: - return target in self.nums + return target in self.nums # 返回目标值是否存在在集合中 diff --git a/solutions/python3/1262.py b/solutions/python3/1262.py index a4d6f3e..1ded0a6 100644 --- a/solutions/python3/1262.py +++ b/solutions/python3/1262.py @@ -1,7 +1,17 @@ + class Solution: - def maxSumDivThree( - self, nums: List[int], dp: list = [0, -float("inf"), -float("inf")] - ) -> int: + def maxSumDivThree(self, nums: List[int], dp: list = [0, -float("inf"), -float("inf")]) -> int: + """ + :param nums: 输入的整数列表 + :param dp: 动态规划数组,初始化为[0, -inf, -inf] + :return: 最大和,该和能被3整除 + + 思路: + 1. 使用动态规划解决。 + 2. `dp[i]` 表示从前 i 个数中选取一些数(可能为空)得到的和能够被3除后余i的最大值。 + """ for num in nums: + # 更新dp数组 dp = [max(dp[i], dp[(i - num) % 3] + num) for i in range(3)] + return dp[0] diff --git a/solutions/python3/1263.py b/solutions/python3/1263.py index 8493807..cc4329a 100644 --- a/solutions/python3/1263.py +++ b/solutions/python3/1263.py @@ -1,51 +1,78 @@ + class Solution: def minPushBox(self, grid: List[List[str]]) -> int: + """ + 解决问题:找到将箱子推到目标位置所需的最小移动次数。 + + 优化和改进: + 1. 添加中英文注释,确保代码可读性。 + 2. 使用优先队列(堆)进行启发式搜索优化路径选择。 + 3. 避免重复计算启发式函数值,提高性能。 + 4. 确保代码简洁且易读。 + + 参数: + grid: List[List[str]], 输入地图,包含'.'(空地),'#'(墙壁),'S'(人物初始位置),'T'(目标位置),'B'(箱子初始位置) + + 返回: + int, 将箱子推到目标位置所需的最小移动次数 + """ m, n = len(grid), len(grid[0]) + + # 找出人物、箱子和目标的位置 for r in range(m): for c in range(n): if grid[r][c] == "T": - tX, tY = r, c + tX, tY = r, c # 目标位置 (tX, tY) if grid[r][c] == "B": - bX, bY = r, c + bX, bY = r, c # 箱子初始位置 (bX, bY) if grid[r][c] == "S": - pX, pY = r, c + pX, pY = r, c # 人物初始位置 (pX, pY) - def heuristic(bX, bY): + def heuristic(bX: int, bY: int) -> int: + """ + 计算启发式函数值,即箱子与目标之间的曼哈顿距离。 + + 参数: + bX, bY : 箱子的当前位置 + + 返回: + int, 箱子到目标位置的最短移动步数估计 + """ return abs(tX - bX) + abs(tY - bY) heap = [[heuristic(bX, bY), 0, pX, pY, bX, bY]] visited = set() while heap: _, moves, pX, pY, bX, bY = heapq.heappop(heap) - if bX == tX and bY == tY: + if bX == tX and bY == tY: # 到达目标位置 return moves + if (pX, pY, bX, bY) not in visited: visited.add((pX, pY, bX, bY)) for dx, dy in (0, 1), (1, 0), (-1, 0), (0, -1): + # 人物移动 pX += dx pY += dy if 0 <= pX < m and 0 <= pY < n and grid[pX][pY] != "#": + # 判断是否可以推动箱子 if pX == bX and pY == bY: bX += dx bY += dy if 0 <= bX < m and 0 <= bY < n and grid[bX][bY] != "#": heapq.heappush( heap, - [ - heuristic(bX, bY) + moves + 1, - moves + 1, - pX, - pY, - bX, - bY, - ], + [heuristic(bX, bY) + moves + 1, moves + 1, pX, pY, bX, bY] ) + # 移动回来 bX -= dx bY -= dy else: heapq.heappush( - heap, [heuristic(bX, bY) + moves, moves, pX, pY, bX, bY] + heap, + [heuristic(bX, bY) + moves, moves, pX, pY, bX, bY] ) + # 移回初始位置,避免重复计算 pX -= dx pY -= dy - return -1 + + return -1 # 没有找到解决方案 diff --git a/solutions/python3/127.py b/solutions/python3/127.py index 2982c00..e10fbee 100644 --- a/solutions/python3/127.py +++ b/solutions/python3/127.py @@ -1,6 +1,25 @@ + class Solution: - def ladderLength(self, beginWord, endWord, wordList): + def ladderLength(self, beginWord: str, endWord: str, wordList: list[str]) -> int: + """ + Chinese: + 题目要求从一个起始单词通过一系列变换到达目标单词,每次变换只能改变一个字母,并且中间结果必须在给定的字典中。 + 本题使用了广度优先搜索(BFS)的方法来寻找最短路径。 + + English: + The problem requires transforming a start word into an end word by changing one letter at a time, with each intermediate result being in the given dictionary. + This solution uses Breadth-First Search (BFS) to find the shortest path. + """ + words, layer = set(wordList), {beginWord: [[beginWord]]} + """ + Chinese: + 初始化一个字典`layer`,其键为当前单词,值为其到达路径。同时将所有词汇加入集合`words`中。 + + English: + Initialize a dictionary `layer`, with keys as the current words and values as their paths. Also, add all words to the set `words`. + """ + while layer: newlayer = collections.defaultdict(list) for w in layer: @@ -12,6 +31,22 @@ def ladderLength(self, beginWord, endWord, wordList): neww = w[:i] + c + w[i + 1:] if neww in words: newlayer[neww] += [j + [neww] for j in layer[w]] + """ + Chinese: + 对于当前层中的每个单词,尝试每一种可能的单个字母替换。如果新生成的单词在词典中,则将其添加到新的层中。 + + English: + For each word in the current layer, try every possible single-letter substitution. If the new word is in the dictionary, add it to the new layer. + """ + words -= set(newlayer.keys()) layer = newlayer - return 0 \ No newline at end of file + """ + Chinese: + 移除已经访问过的单词,更新当前层为新的层。 + + English: + Remove visited words and update the current layer to the new one. + """ + + return 0 diff --git a/solutions/python3/128.py b/solutions/python3/128.py index 6852c92..cd09173 100644 --- a/solutions/python3/128.py +++ b/solutions/python3/128.py @@ -1,10 +1,17 @@ + class Solution: + # 定义一个求解最长连续序列的方法 def longestConsecutive(self, nums): + # 将输入的nums转换为集合items,去重并提高查找效率 res, items = 0, set(nums) + for num in items: + # 如果当前数字num-1不在集合中,则说明可以从num开始寻找最长连续序列 if num - 1 not in items: - cur = 1 - while num + 1 in items: - num, cur = num + 1, cur + 1 - if cur > res: res = cur - return res \ No newline at end of file + cur = 1 # 当前连续序列的长度初始化为1 + while num + 1 in items: + num, cur = num + 1, cur + 1 # 继续查找下一个连续数字并增加当前序列长度 + if cur > res: + res = cur # 更新结果,如果当前序列更长则替换result + + return res # 返回最长的连续序列长度 diff --git a/solutions/python3/129.py b/solutions/python3/129.py index a4c8d14..8a76643 100644 --- a/solutions/python3/129.py +++ b/solutions/python3/129.py @@ -1,21 +1,41 @@ + # Definition for a binary tree node. -# class TreeNode: -# def __init__(self, x): -# self.val = x -# self.left = None -# self.right = None +class TreeNode: + def __init__(self, x): + self.val = x + self.left = None + self.right = None class Solution: - def sumNumbers(self, root): + """ + 该类用于计算二叉树中从根节点到叶子节点的数字之和。 + 英文:This class is used to calculate the sum of numbers from root to leaf nodes in a binary tree. + """ + + def sumNumbers(self, root: TreeNode) -> int: """ :type root: TreeNode :rtype: int + 计算从根节点到叶子节点的数字之和。 + 英文:Calculate the sum of numbers from the root node to leaf nodes. """ + + # 递归函数,用于遍历树并构建路径字符串 def traverse(node, q): - if not node: return - traverse(node.left, q + [str(node.val)]) - traverse(node.right, q + [str(node.val)]) - if not node.left and not node.right: res[0] += int("".join(q + [str(node.val)])) - res = [0] - traverse(root, []) - return res[0] \ No newline at end of file + """ + 递归遍历节点,并将当前节点值加入路径列表中。 + 如果到达叶子节点,则将该路径对应的数字加到结果中。 + 英文:Recursive function to traverse nodes and add current node value to the path list. + If it reaches a leaf node, add the number corresponding to this path to the result. + """ + if not node: + return + q.append(str(node.val)) # 将当前节点值加入路径列表中 + if not node.left and not node.right: + res[0] += int("".join(q)) # 如果是叶子节点,则将路径字符串转换为数字并加到结果中 + traverse(node.left, q) # 递归遍历左子树 + traverse(node.right, q) # 递归遍历右子树 + + res = [0] # 存储最终的结果 + traverse(root, []) # 从根节点开始遍历 + return res[0] diff --git a/solutions/python3/13.py b/solutions/python3/13.py index fe99722..d8f4342 100644 --- a/solutions/python3/13.py +++ b/solutions/python3/13.py @@ -1,10 +1,21 @@ + class Solution: + # 将罗马数字转换为整数 + def romanToInt(self, s): + # 创建一个字典用于存储罗马数字与其对应整数值的映射 table = {"M": 1000, "D": 500, "C": 100, "L": 50, "X": 10, "V": 5, "I": 1} + + # 初始化结果和前一个字符,默认为'I',表示初始值 sm, pre = 0, 'I' - for c in s[::-1]: + + # 反向遍历字符串s中的每一个字符c + for c in s[::-1]: + # 如果当前字符对应的数值小于前一个字符的数值,则减去当前字符对应的整数值 if table[c] < table[pre]: sm, pre = sm - table[c], c else: + # 否则,加上当前字符对应的整数值,并更新前一个字符为当前字符 sm, pre = sm + table[c], c - return sm \ No newline at end of file + + return sm # 返回最终的结果 diff --git a/solutions/python3/130.py b/solutions/python3/130.py index 8edd45e..0c90987 100644 --- a/solutions/python3/130.py +++ b/solutions/python3/130.py @@ -1,13 +1,26 @@ + class Solution: def solve(self, board: List[List[str]]) -> None: + """ + Do not return anything, modify board in-place instead. + + 解题思路:首先标记所有边缘的'O'和与其相连的'O'为'S'(Safe),然后将剩余的所有'O'置为'X',最后将所有的'S'还原为'O' + """ + m, n = len(board), len(board and board[0]) - def explore(i, j): + """ + 辅助函数,深度优先搜索并标记所有与边界'O'相连的'O' + """ + def explore(i: int, j: int) -> None: board[i][j] = "S" for x, y in ((i - 1, j), (i + 1, j), (i, j - 1), (i, j + 1)): if 0 <= x < m and 0 <= y < n and board[x][y] == "O": explore(x, y) + """ + 遍历四个边界,将所有'O'及其相连的'O'标记为'S' + """ for i in range(max(m, n)): if i < m and board[i][0] == "O": explore(i, 0) @@ -17,10 +30,13 @@ def explore(i, j): explore(0, i) if i < n and board[m - 1][i] == "O": explore(m - 1, i) + + """ + 将所有剩余的'O'标记为'X' + """ for i in range(m): for j in range(n): if board[i][j] == "S": board[i][j] = "O" elif board[i][j] == "O": board[i][j] = "X" - diff --git a/solutions/python3/131.py b/solutions/python3/131.py index 18931bc..7922402 100644 --- a/solutions/python3/131.py +++ b/solutions/python3/131.py @@ -1,13 +1,31 @@ + class Solution: def partition(self, s): + """ + 中文注释: + 将字符串s进行分割,使得每个子串都是回文串。 + + 英文注释: + Partition the string s such that every substring is a palindrome. + """ q, n = [[s[0]]], len(s) + for i in range(1, n): new = [] for arr in q: cur = arr[-1] + s[i] + # 中文注释: + # 如果当前子串不是最后一个字符,并且当前子串是回文,或者已经是字符串末尾,则继续添加 + # 英文注释: + # If the current substring is not the last character and it's a palindrome, or if we've reached the end of the string, continue adding. if i < n - 1 or cur == cur[::-1]: new.append(arr[:-1] + [cur]) + # 中文注释: + # 如果当前子串本身是回文,则可以单独作为一个分割项 + # 英文注释: + # If the current substring itself is a palindrome, it can be added as a separate partition. if arr[-1] == arr[-1][::-1]: new.append(arr + [s[i]]) q = new - return q \ No newline at end of file + + return q diff --git a/solutions/python3/132.py b/solutions/python3/132.py index a39a222..923eb7a 100644 --- a/solutions/python3/132.py +++ b/solutions/python3/132.py @@ -1,14 +1,38 @@ + class Solution: - def minCut(self, s): - q, pal, used = [(0, 0)], collections.defaultdict(list), {(0, 0)} + """ + 本题要求计算使得字符串s成为回文串的最小分割次数。 + 中文注释:本题目标是求解将给定字符串s通过最少切割次数变成回文串。 + + 1. 使用优先队列存储当前起始位置和已经进行的切割次数。 + 2. 遍历字符串,检查所有子串是否为回文。 + 3. 如果是回文,则将结束位置加入字典中。 + 4. 每次从队列中取出最小值,更新切割次数并继续处理。 + """ + + def minCut(self, s: str) -> int: + # 优先队列初始化 + q = [(0, 0)] + # 回文子串字典 + pal = collections.defaultdict(list) + used = {(0, 0)} + + # 遍历字符串,标记所有回文子串的结束位置 for i in range(len(s)): for j in range(i, len(s)): - if s[i:j + 1] == s[i:j + 1][::-1]: pal[i].append(j + 1) + if s[i:j + 1] == s[i:j + 1][::-1]: + pal[i].append(j + 1) + + # 使用优先队列进行广度优先搜索 while q: cuts, i = heapq.heappop(q) i *= -1 - if i == len(s): return cuts - 1 + + # 当处理到字符串末尾时,返回当前切割次数减一(最后一刀不需要) + if i == len(s): + return cuts - 1 + for j in pal[i]: if (cuts + 1, -j) not in used: used.add((cuts + 1, -j)) - heapq.heappush(q, (cuts + 1, -j)) \ No newline at end of file + heapq.heappush(q, (cuts + 1, -j)) diff --git a/solutions/python3/133.py b/solutions/python3/133.py index 73e928c..e5af0d4 100644 --- a/solutions/python3/133.py +++ b/solutions/python3/133.py @@ -1,11 +1,32 @@ + class Solution: def cloneGraph(self, node: "Node") -> "Node": + """ + 复制给定的图结构。使用深度优先搜索(DFS)来确保所有节点都被正确复制。 + + 参数: + node (Node): 起始节点 + + 返回值: + Node: 新复制的图 + """ visited = {} def dfs(node): + """ + 深度优先搜索函数,用于递归地创建新节点及其邻居。 + + 参数: + node (Node): 当前处理的节点 + + 返回值: + Node: 复制的新节点 + """ if node and node.val not in visited: + # 创建一个新的节点,并记录其值 newNode = Node(node.val, []) visited[newNode.val] = newNode + # 递归地为当前节点的所有邻居创建新节点,并设置邻居列表 newNode.neighbors = [ visited.get(n.val) or dfs(n) for n in node.neighbors ] diff --git a/solutions/python3/134.py b/solutions/python3/134.py index 496de65..0b2a207 100644 --- a/solutions/python3/134.py +++ b/solutions/python3/134.py @@ -1,6 +1,26 @@ + class Solution: - def canCompleteCircuit(self, gas, cost, cur = 0, index = 0): + """ + Given two arrays of integers 'gas' and 'cost', each representing the gas price + and cost to travel between stations respectively, this function determines if it's possible + to complete a circuit starting from one of the gas stations. If a solution exists, return the + index (starting station); otherwise, return -1. + + 中文注释: + 给定两个整数数组 'gas' 和 'cost',分别表示加油站的汽油价格和从一个加油站到下一个加油站的成本。此函数确定是否可以从某个加油站出发完成一圈。如果存在解决方案,则返回起始站的索引;否则,返回 -1。 + """ + + def canCompleteCircuit(self, gas, cost): + cur = 0 + index = 0 + + # Iterate through each station to calculate the cumulative balance of fuel. for i in range(len(gas)): cur += gas[i] - cost[i] - if cur < 0: cur, index = 0, i + 1 - return index if index < len(gas) and sum(gas) >= sum(cost) else -1 \ No newline at end of file + # If at any point the current balance goes below zero, reset it and start from the next station. + if cur < 0: + cur = 0 + index = i + 1 + + # Check if a valid circuit can be completed starting from the identified station. + return index if index < len(gas) and sum(gas) >= sum(cost) else -1 diff --git a/solutions/python3/135.py b/solutions/python3/135.py index 84fb071..80fcdba 100644 --- a/solutions/python3/135.py +++ b/solutions/python3/135.py @@ -1,10 +1,22 @@ + class Solution: + # 定义一个求解糖果分配问题的类 + def candy(self, ratings): + # 初始化动态规划数组,每个孩子至少得到一颗糖 dp = [1] * len(ratings) + + # 从前向后遍历rating列表 for i in range(1, len(ratings)): if ratings[i] > ratings[i - 1]: + # 如果当前孩子的rating比前一个高,则分配的糖果数为前一个孩子的糖果数+1 dp[i] = dp[i - 1] + 1 + + # 从后向前遍历rating列表 for i in range(len(ratings) - 2, -1, -1): if ratings[i] > ratings[i + 1] and dp[i] <= dp[i + 1]: + # 如果当前孩子的rating比下一个孩子高,且分配的糖果数不超过下一个孩子的糖果数,则重新分配 dp[i] = dp[i + 1] + 1 - return sum(dp) \ No newline at end of file + + # 返回所有孩子得到的糖果总数 + return sum(dp) diff --git a/solutions/python3/136.py b/solutions/python3/136.py index 180e617..d193a82 100644 --- a/solutions/python3/136.py +++ b/solutions/python3/136.py @@ -1,11 +1,25 @@ + class Solution: def singleNumber(self, nums): """ :type nums: List[int] :rtype: int + + 输入:包含多个整数的列表 nums。 + 输出:返回仅出现一次的数字。 + + 逻辑: + 使用字典记录每个元素出现的次数,最后字典中剩下的那个键就是结果 """ - dic={} + # 创建一个空字典来存储数字及其出现次数 + count_dict = {} + + # 遍历输入列表,统计每个数字出现的次数 for num in nums: - if not num in dic: dic[num]=1 - else: dic.pop(num) - return list(dic.keys())[0] \ No newline at end of file + if num not in count_dict: + count_dict[num] = 1 + else: + del count_dict[num] + + # 返回字典中唯一剩下的键(即只出现一次的那个数字) + return list(count_dict.keys())[0] diff --git a/solutions/python3/137.py b/solutions/python3/137.py index 5ffb396..6f21655 100644 --- a/solutions/python3/137.py +++ b/solutions/python3/137.py @@ -1,7 +1,9 @@ + class Solution: + # 中文注释:定义一个名为Solution的类,包含单个数字查找方法singleNumber + def singleNumber(self, nums): - """ - :type nums: List[int] - :rtype: int - """ - return ((sum(set(nums)) * 3) - sum(nums)) // 2 \ No newline at end of file + # 中文注释: 单个数字查找逻辑 + + # 英文注释: Function to find the single number in a list of integers + return ((sum(set(nums)) * 3) - sum(nums)) // 2 diff --git a/solutions/python3/138.py b/solutions/python3/138.py index 7ab1ad5..10bfd2c 100644 --- a/solutions/python3/138.py +++ b/solutions/python3/138.py @@ -1,11 +1,18 @@ + class Solution: - def copyRandomList(self, head: "Node") -> "Node": + # 复制随机链表 + def copyRandomList(self, head: 'Node') -> 'Node': + # 使用字典存储新旧节点的映射关系,便于快速查找 dic = collections.defaultdict(lambda: Node(0, None, None)) - dic[None] = None + dic[None] = None # 处理空指针情况 + + # 遍历原链表构建新的链表结构 n = head while n: + # 设置新节点的值、next和random属性 dic[n].val = n.val dic[n].next = dic[n.next] dic[n].random = dic[n.random] n = n.next - return dic[head] + + return dic[head] # 返回复制后的链表头节点 diff --git a/solutions/python3/139.py b/solutions/python3/139.py index e8ad38d..86821b8 100644 --- a/solutions/python3/139.py +++ b/solutions/python3/139.py @@ -1,11 +1,23 @@ + class Solution: - def wordBreak(self, s, wordDict): + # 判断给定字符串 s 是否能使用给定的单词列表 wordDict 中的单词拼接而成 + + def wordBreak(self, s: str, wordDict: List[str]) -> bool: + # 初始化右边界列表和单词集合 rightmosts, words = [0], set(wordDict) + + # 遍历字符串 s 的每一个可能的结束位置 i for i in range(1, len(s) + 1): + # 对于当前遍历到的每个位置 i,检查之前所有右边界位置 last_index for last_index in rightmosts: + # 如果子串 s[last_index:i] 在单词集合 words 中,则更新右边界列表,并检查是否已经到达字符串末尾 if s[last_index:i] in words: rightmosts.append(i) if i == len(s): return True break - return False \ No newline at end of file + + # 遍历结束后,如果未找到满足条件的分割方式,则返回 False + return False + + diff --git a/solutions/python3/14.py b/solutions/python3/14.py index c26a2df..4696728 100644 --- a/solutions/python3/14.py +++ b/solutions/python3/14.py @@ -1,6 +1,19 @@ + class Solution: - def longestCommonPrefix(self, s: List[str]) -> str: + def longestCommonPrefix(self, strs: List[str]) -> str: + """ + 寻找字符串列表中的最长公共前缀。 + + :param strs: 字符串列表 + :type strs: List[str] + :return: 最长公共前缀 + :rtype: str + """ j = 0 - while s and all(j < len(s[i]) and j < len(s[i - 1]) and s[i][j] == s[i - 1][j] for i in range(len(s))): + + # 当列表不为空且所有字符串长度大于j并且当前字符相同时,增加j的值 + while strs and all(len(strs[i]) > j and strs[i][j] == strs[i - 1][j] for i in range(1, len(strs))): j += 1 - return s[0][:j] if j else '' \ No newline at end of file + + # 返回前缀,如果j为0则返回空字符串 + return strs[0][:j] if j else '' diff --git a/solutions/python3/140.py b/solutions/python3/140.py index 8cdaa09..b6bb4c2 100644 --- a/solutions/python3/140.py +++ b/solutions/python3/140.py @@ -1,6 +1,24 @@ + class Solution: - def wordBreak(self, s, wordDict): + def wordBreak(self, s: str, wordDict: list[str]) -> list[str]: + """ + 判断字符串s是否可以被wordDict中的单词分割,并返回所有可能的分割方式。 + + 参数: + s (str): 待分割的字符串 + wordDict (list[str]): 单词列表 + + 返回: + list[str]: 所有可能的分割结果 + """ + def breakable(): + """ + 判断给定字符串是否可被字典中的单词分割。 + + 返回: + bool: 是否可以分割 + """ rightmosts = [0] for i in range(1, len(s) + 1): for last_index in rightmosts: @@ -10,7 +28,10 @@ def breakable(): return True break return False + + # 使用队列进行广度优先搜索 q, res, words = [("", 0)], [], set(wordDict) + if breakable(): for j in range(1, len(s) + 1): new = q[:] @@ -21,4 +42,5 @@ def breakable(): else: new.append((seq and seq + " " + s[i:j] or s[i:j], j)) q = new - return res \ No newline at end of file + + return res diff --git a/solutions/python3/141.py b/solutions/python3/141.py index f118084..7865c6a 100644 --- a/solutions/python3/141.py +++ b/solutions/python3/141.py @@ -1,8 +1,19 @@ + class Solution: - def hasCycle(self, head: ListNode) -> bool: + # 判断链表中是否存在环 + def hasCycle(self, head: 'ListNode') -> bool: + # 初始化快慢指针,慢指针从头节点开始,快指针从第二个节点开始(若为空则初始化为None) slow, fast = head, head.next if head else None + + # 当快慢指针均不为空时继续循环 while slow != None and fast != None: + # 如果快慢指针相遇,则表示存在环 if slow == fast: return True - slow, fast = slow.next, fast.next.next if fast.next else None + + # 更新快慢指针的位置 + slow = slow.next + fast = fast.next.next if fast.next else None + + # 若结束循环后未发现快慢指针相遇,说明无环 return False diff --git a/solutions/python3/142.py b/solutions/python3/142.py index ad63238..1950f74 100644 --- a/solutions/python3/142.py +++ b/solutions/python3/142.py @@ -1,11 +1,24 @@ + class Solution: - def detectCycle(self, head: ListNode) -> ListNode: + # 定义检测链表是否存在环及找到入环点的方法 + def detectCycle(self, head: 'ListNode') -> 'ListNode': + # 初始化快慢指针和根节点指针,都指向头节点 fast = slow = root = head + + # 使用快慢指针法查找相遇点 while fast and fast.next: - slow = slow.next - fast = fast.next.next + slow = slow.next # 慢指针每次移动一步 + fast = fast.next.next # 快指针每次移动两步 + + # 当快慢指针相遇时,说明链表存在环 if slow == fast: - while root != slow: - root = root.next + # 重新定位根节点指针到头节点 + while root != slow: + root = root.next # 根节点和慢指针都一步一走直到两者相遇 slow = slow.next + + # 返回入环点 return root + + # 如果没有找到环,返回None + return None diff --git a/solutions/python3/143.py b/solutions/python3/143.py index ccca6cc..a19d485 100644 --- a/solutions/python3/143.py +++ b/solutions/python3/143.py @@ -1,16 +1,28 @@ + # Definition for singly-linked list. -# class ListNode: -# def __init__(self, x): -# self.val = x -# self.next = None +class ListNode: + def __init__(self, x): + self.val = x + self.next = None + class Solution(object): - def reorderList(self, head): + # 重新排序链表,将节点按顺序交错排列 + def reorderList(self, head: ListNode) -> None: if head: arr = [] + # 将链表节点值存入数组 while head: arr += head, head = head.next + l, r, prev = 0, len(arr) - 1, ListNode(0) - while l < r: prev.next, arr[l].next, prev, l, r = arr[l], arr[r], arr[r], l + 1, r - 1 - if l == r: prev.next = arr[l] - arr[l].next = None \ No newline at end of file + # 使用双指针从两端交替插入 + while l < r: + prev.next, arr[l].next, prev, l, r = arr[l], arr[r], arr[r], l + 1, r - 1 + + # 处理奇数个节点的情况 + if l == r: + prev.next = arr[l] + + # 断开重新连接后的链表末尾,防止形成环 + arr[l].next = None diff --git a/solutions/python3/144.py b/solutions/python3/144.py index 6e6ee6b..f4c8e4c 100644 --- a/solutions/python3/144.py +++ b/solutions/python3/144.py @@ -1,26 +1,30 @@ + # Definition for a binary tree node. -# class TreeNode: -# def __init__(self, x): -# self.val = x -# self.left = None -# self.right = None +class TreeNode: + def __init__(self, x): + self.val = x + self.left = None + self.right = None class Solution: - def preorderTraversal(self, root): - """ - :type root: TreeNode - :rtype: List[int] - """ + # 先序遍历二叉树,返回节点值列表 + def preorderTraversal(self, root: 'TreeNode') -> 'List[int]': res = [root] q = [root] + + # 当队列不为空时继续循环 while any(q): tmp = [] + for node in q: - if node.right: + if node.right: # 如果右子节点存在,则插入当前节点右侧 res.insert(res.index(node) + 1, node.right) tmp.append(node.right) - if node.left: + + if node.left: # 如果左子节点存在,则插入当前节点左侧 res.insert(res.index(node) + 1, node.left) tmp.insert(-1, node.left) - q = tmp - return [j.val for j in res if j] \ No newline at end of file + + q = tmp # 更新队列为临时列表tmp + + return [j.val for j in res if j] # 返回结果列表,过滤掉None值 diff --git a/solutions/python3/145.py b/solutions/python3/145.py index c84f8d5..50fb631 100644 --- a/solutions/python3/145.py +++ b/solutions/python3/145.py @@ -1,8 +1,17 @@ + class Solution: def postorderTraversal(self, root): + """ + 中文注释:此函数用于实现二叉树的后序遍历。 + 英文注释: This function is used to implement the post-order traversal of a binary tree. + + :param root: 二叉树的根节点 + :return: 返回后序遍历的结果列表 + """ ret, stack = [], root and [root] while stack: node = stack.pop() ret.append(node.val) - stack += [child for child in (node.left, node.right) if child] - return ret[::-1] \ No newline at end of file + # 将右子节点和左子节点依次压入栈中,确保先处理左子树 + stack += [child for child in (node.right, node.left) if child] + return ret[::-1] # 反转列表以获得正确的后序遍历结果 diff --git a/solutions/python3/146.py b/solutions/python3/146.py index 083439a..1deb5a2 100644 --- a/solutions/python3/146.py +++ b/solutions/python3/146.py @@ -1,28 +1,52 @@ -class Node: + +class Node: # 节点类 def __init__(self, key, value): + """ + 初始化节点对象,设置键、值和双向链表指针。 + + :param key: 键 + :param value: 值 + """ self.key = key self.val = value - self.next = self.pre = None - self.pre = None + self.next = None # 后继节点 + self.pre = None # 前驱节点 + class LRUCache: def remove(self, node): + """ + 移除链表中的指定节点,并更新字典。 + + :param node: 要移除的节点 + """ node.pre.next, node.next.pre = node.next, node.pre self.dic.pop(node.key) def add(self, node): + """ + 将新节点添加到链表尾部,并更新字典。 + + :param node: 新增节点 + """ node.pre = self.tail.pre node.next = self.tail self.tail.pre.next = self.tail.pre = node self.dic[node.key] = node def __init__(self, capacity): - self.dic = {} - self.n = capacity - self.head = self.tail = Node(0, 0) + self.dic = {} # 存储键值对的字典 + self.n = capacity # 缓存容量 + self.head = self.tail = Node(0, 0) # 初始化头尾节点,用于双端链表实现缓存 self.head.next = self.tail self.tail.pre = self.head - + def get(self, key): + """ + 获取键对应的值,并将该元素移动到链表末尾。 + + :param key: 要获取的键 + :return: 值或-1(如果键不存在) + """ if key in self.dic: node = self.dic[key] self.remove(node) @@ -31,9 +55,15 @@ def get(self, key): return -1 def put(self, key, value): + """ + 插入新元素到缓存中,如果已存在,则更新值并移动至末尾。 + + :param key: 键 + :param value: 值 + """ if key in self.dic: self.remove(self.dic[key]) node = Node(key, value) self.add(node) if len(self.dic) > self.n: - self.remove(self.head.next) \ No newline at end of file + self.remove(self.head.next) diff --git a/solutions/python3/147.py b/solutions/python3/147.py index df32d95..dd85941 100644 --- a/solutions/python3/147.py +++ b/solutions/python3/147.py @@ -1,25 +1,29 @@ + # Definition for singly-linked list. -# class ListNode: -# def __init__(self, x): -# self.val = x -# self.next = None +class ListNode: + def __init__(self, x): + self.val = x + self.next = None class Solution: - def insertionSortList(self, head): - """ - :type head: ListNode - :rtype: ListNode - """ - ref, ref.next, n = ListNode(-float("inf")), head, 0 + # 使用插入排序对链表进行排序 + def insertionSortList(self, head: 'ListNode') -> 'ListNode': + ref, ref.next, n = ListNode(float("-inf")), head, 0 + while head: - inserted, curr, prev, n = ListNode(head.val), ref.next, ref, n+1 - for i in range(n-1): - if inserted.val= n-2: curr.next = None + # 如果是最后一个节点,则断开链表 + if i >= n - 2: curr.next = None break - else: + else: prev, curr = curr, curr.next - if i == n-2: prev.next = inserted + # 移动未排序部分的头指针 head = head.next - return ref.next \ No newline at end of file + + return ref.next diff --git a/solutions/python3/148.py b/solutions/python3/148.py index 1f089db..b1c8ccd 100644 --- a/solutions/python3/148.py +++ b/solutions/python3/148.py @@ -1,16 +1,27 @@ + # Definition for singly-linked list. -# class ListNode: -# def __init__(self, x): -# self.val = x -# self.next = None +class ListNode: + def __init__(self, x): + self.val = x # 节点值初始化 + self.next = None # 下一个节点指针初始化 class Solution: - def sortList(self, head): + def sortList(self, head: ListNode) -> ListNode: + # 将链表中的数值提取到列表中并排序 ls = [] - while head: ls.append(head.val); head = head.next - ls .sort() - root = head = ListNode(ls[0]) if ls else [] + while head: + ls.append(head.val) + head = head.next + + # 如果列表为空,则返回空链表,否则进行后续操作 + if not ls: + return [] + + root = head = ListNode(ls[0]) # 初始化根节点和头指针 + + # 遍历排序后的列表,并构建新的有序链表 for i in range(1, len(ls)): head.next = ListNode(ls[i]) head = head.next - return root \ No newline at end of file + + return root diff --git a/solutions/python3/149.py b/solutions/python3/149.py index ae4dafa..12d5454 100644 --- a/solutions/python3/149.py +++ b/solutions/python3/149.py @@ -1,3 +1,4 @@ + # Definition for a point. # class Point: # def __init__(self, a=0, b=0): @@ -5,26 +6,33 @@ # self.y = b class Solution: + # 计算两点之间的斜率,或者判断为垂直线 def maxPoints(self, points): - m, res, roots = {}, 0, set() - for i, p1 in enumerate(points): - if (p1.x, p1.y) not in roots: - roots.add((p1.x, p1.y)) - m.clear() - dup = path = 0 - for j, p2 in enumerate(points): - if i != j: + m, res, roots = {}, 0, set() # 初始化存储斜率的字典、最大点数和已访问点集 + + for i, p1 in enumerate(points): # 遍历每个点p1 + if (p1.x, p1.y) not in roots: # 如果该点未被访问过 + roots.add((p1.x, p1.y)) # 标记为已访问 + m.clear() # 清空字典,重新计算斜率 + dup = path = 0 # 初始化重复点数和路径最大长度 + + for j, p2 in enumerate(points): # 遍历每个点p2 + if i != j: # 确保不与自身比较 try: - cur = (p1.y - p2.y) * 100 / (p1.x - p2.x) - except: - if p1.y == p2.y: + cur = (p1.y - p2.y) * 100 / (p1.x - p2.x) # 计算斜率,乘以100避免精度问题 + except ZeroDivisionError: + if p1.y == p2.y: # 如果两点纵坐标相同,则为重复点 dup += 1 continue else: - cur = "ver" - m[cur] = m.get(cur, 0) + 1 - if m[cur] > path: + cur = "ver" # 垂直线标记为"ver" + + m[cur] = m.get(cur, 0) + 1 # 更新斜率计数 + if m[cur] > path: # 更新路径最大长度 path = m[cur] + + # 计算当前路径下的最大点数,并更新全局结果 if path + dup + 1 > res: res = path + dup + 1 - return res \ No newline at end of file + + return res # 返回最终的最大点数 diff --git a/solutions/python3/15.py b/solutions/python3/15.py index 5620039..85026b2 100644 --- a/solutions/python3/15.py +++ b/solutions/python3/15.py @@ -1,15 +1,34 @@ + class Solution: def threeSum(self, nums): + """ + 给定一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a, b, c ,使得 a + b + c = 0? + 如果存在,请返回任意一个满足条件三元组;否则返回空列表。 + + :param nums: List[int] - 需要处理的整数列表 + :return: List[List[int]] - 所有和为0的三个元素组成的数组,每个元素是一个包含3个int的数组 + """ res, res_set = [], set() + # 对数组进行排序以简化后续判断逻辑 nums.sort() + for i in range(len(nums) - 2): l, r = i + 1, len(nums) - 1 + while l < r: - sm = nums[i] + nums[l] + nums[r] - if sm < 0: l += 1 - elif sm > 0: r -= 1 - elif (nums[i], nums[l], nums[r]) not in res_set: - res.append([nums[i], nums[l], nums[r]]) - res_set.add((nums[i], nums[l], nums[r])) - else: l, r = l + 1, r - 1 - return res \ No newline at end of file + sm = nums[i] + nums[l] + nums[r] + if sm < 0: + # 当三数之和小于0,移动左指针使总和变大 + l += 1 + elif sm > 0: + # 当三数之和大于0,移动右指针使总和减小 + r -= 1 + else: + # 找到一个符合条件的组合,加入结果集并去重 + if (nums[i], nums[l], nums[r]) not in res_set: + res.append([nums[i], nums[l], nums[r]]) + res_set.add((nums[i], nums[l], nums[r])) + + l, r = l + 1, r - 1 # 移动指针继续查找下一个可能的组合 + + return res diff --git a/solutions/python3/150.py b/solutions/python3/150.py index eb0e488..594314d 100644 --- a/solutions/python3/150.py +++ b/solutions/python3/150.py @@ -1,17 +1,33 @@ + class Solution: def evalRPN(self, tokens): """ :type tokens: List[str] :rtype: int """ + # 使用栈来处理逆波兰表达式 stack = [] + for token in tokens: - if token not in ("+", "-", "*", "/"): stack.append(int(token)) + # 如果当前token不是操作符,则将其转化为整数并压入栈中 + if token not in ("+", "-", "*", "/"): + stack.append(int(token)) else: + # 弹出两个数字进行运算 num2, num1 = stack.pop(), stack.pop() - if token == "+": last = num1 + num2 - elif token == "-": last = num1 - num2 - elif token == "*": last = num1 * num2 - elif token == "/": last = int(num1 / num2) + + # 根据操作符执行相应的数学运算,并将结果重新压入栈中 + if token == "+": + last = num1 + num2 + elif token == "-": + last = num1 - num2 + elif token == "*": + last = num1 * num2 + elif token == "/": + # 由于除法可能产生浮点数,所以使用int()函数将结果转换为整型 + last = int(num1 / num2) + stack.append(last) - return stack[0] \ No newline at end of file + + # 最后栈中仅剩一个元素即为计算结果 + return stack[0] diff --git a/solutions/python3/151.py b/solutions/python3/151.py index b6ef650..9949a5c 100644 --- a/solutions/python3/151.py +++ b/solutions/python3/151.py @@ -1,3 +1,7 @@ + class Solution: + # 反转字符串中的单词 def reverseWords(self, s: str) -> str: + # 使用split()将字符串按空格分割成单词列表,[::-1]反转列表顺序 + # 最后使用" ".join()将单词列表重新组合成一个字符串,并用空格分隔 return " ".join(s.split()[::-1]) diff --git a/solutions/python3/152.py b/solutions/python3/152.py index 58ae8ac..5f95b23 100644 --- a/solutions/python3/152.py +++ b/solutions/python3/152.py @@ -1,12 +1,33 @@ + class Solution: def maxProduct(self, nums): - res, min_pos, max_neg, cur = -float("inf"), float("inf"), -float("inf"), 1 + """ + 使用动态规划的方法来解决最大乘积问题。 + + Parameters: + nums (List[int]): 输入的整数列表 + + Returns: + int: 最大乘积结果 + """ + res, min_pos, max_neg, cur = -float("inf"), float("inf"), -float("inf"), 1 # 初始化变量 + for num in nums: + # 更新当前乘积值,并根据情况更新最大乘积结果 cur *= num - if cur > res: res = cur - elif 0 < cur // min_pos > res: res = cur // min_pos - elif 0 < cur // max_neg > res: res = cur // max_neg - if cur == 0: min_pos, max_neg, cur = float("inf"), -float("inf"), 1 - elif max_neg < cur < 0: max_neg = cur - elif 0 < cur < min_pos: min_pos = cur - return res \ No newline at end of file + if cur > res: + res = cur + elif 0 < cur // min_pos > res: + res = cur // min_pos + elif 0 < cur // max_neg > res: + res = cur // max_neg + + # 处理当前乘积为0的情况,重置相关变量 + if cur == 0: + min_pos, max_neg, cur = float("inf"), -float("inf"), 1 + elif max_neg < cur < 0: + max_neg = cur + elif 0 < cur < min_pos: + min_pos = cur + + return res diff --git a/solutions/python3/153.py b/solutions/python3/153.py index 4eed5f2..ee49031 100644 --- a/solutions/python3/153.py +++ b/solutions/python3/153.py @@ -1,2 +1,5 @@ + class Solution: - findMin = min \ No newline at end of file + # 中文: 返回最小值的方法是直接使用内置的 min 函数。 + # English: The method to return the minimum value is directly using the built-in min function. + findMin = min diff --git a/solutions/python3/154.py b/solutions/python3/154.py index bbee64f..4205769 100644 --- a/solutions/python3/154.py +++ b/solutions/python3/154.py @@ -1,10 +1,30 @@ + class Solution: def findMin(self, nums): - l, r, res = 0, len(nums) - 1, nums and nums[0] + """ + 寻找旋转排序数组中的最小值。 + + 在一个旋转排序数组中,部分元素被旋转了。需要找到数组中的最小值。 + + Args: + nums (List[int]): 旋转排序数组 + + Returns: + int: 数组中的最小值 + """ + + l, r, res = 0, len(nums) - 1, nums[0] if nums else float('inf') while l <= r: - while l < r and nums[l] == nums[l + 1]: l += 1 - while l < r and nums[r] == nums[r - 1]: r -= 1 + # 去除重复的左边界 + while l < r and nums[l] == nums[l + 1]: + l += 1 + # 去除重复的右边界 + while l < r and nums[r] == nums[r - 1]: + r -= 1 + mid = (l + r) // 2 - if nums[mid] >= nums[0]: l = mid + 1 - else: r, res = mid - 1, min(res, nums[mid]) - return res \ No newline at end of file + if nums[mid] >= nums[0]: + l = mid + 1 + else: + r, res = mid - 1, min(res, nums[mid]) + return res diff --git a/solutions/python3/155.py b/solutions/python3/155.py index fb01b9e..a4c0bf5 100644 --- a/solutions/python3/155.py +++ b/solutions/python3/155.py @@ -1,35 +1,49 @@ + class MinStack: def __init__(self): """ - initialize your data structure here. + 初始化最小栈结构。 """ self.data = [] + def push(self, x): """ :type x: int :rtype: void + 将元素 x 压入栈中。如果 x 小于当前栈顶的最小值,则将 x 作为新的最小值压入栈中。 """ - if not self.data or x < self.data[-1][1]: self.data.append([x, x]) - else: self.data.append([x, self.data[-1][1]]) + if not self.data or x < self.data[-1][1]: + self.data.append([x, x]) + else: + self.data.append([x, self.data[-1][1]]) + def pop(self): """ :rtype: void + 弹出栈顶元素。 """ self.data.pop() + def top(self): """ :rtype: int + 获取当前栈顶的值,但不弹出它。 """ return self.data[-1][0] + def getMin(self): """ :rtype: int + 返回当前栈中的最小值。 """ return self.data[-1][1] + + + # Your MinStack object will be instantiated and called as such: # obj = MinStack() # obj.push(x) # obj.pop() # param_3 = obj.top() -# param_4 = obj.getMin() \ No newline at end of file +# param_4 = obj.getMin() diff --git a/solutions/python3/156.py b/solutions/python3/156.py index 7df5a5b..1c0089a 100644 --- a/solutions/python3/156.py +++ b/solutions/python3/156.py @@ -1,16 +1,25 @@ + # Definition for a binary tree node. -# class TreeNode: -# def __init__(self, x): -# self.val = x -# self.left = None -# self.right = None +class TreeNode: + def __init__(self, x): + self.val = x + self.left = None + self.right = None class Solution: - def upsideDownBinaryTree(self, root): + # 递归反转二叉树,将左子节点变为新的根,并调整左右子树关系 + def upsideDownBinaryTree(self, root: TreeNode) -> TreeNode: if root: + # 递归处理左子树 left = self.upsideDownBinaryTree(root.left) - self.upsideDownBinaryTree(root.right) + # 递归处理右子树,这里可以不返回结果直接修改root节点 + _ = self.upsideDownBinaryTree(root.right) + + # 当前根的左子节点变为新的根,并调整左右子树关系 if root.left: + new_root = root.left root.left.right, root.left.left = root, root.right root.right = root.left = None - return left or root \ No newline at end of file + return new_root # 返回新根节点 + # 如果root为空,直接返回None + return root diff --git a/solutions/python3/157.py b/solutions/python3/157.py index 146f6b8..f656782 100644 --- a/solutions/python3/157.py +++ b/solutions/python3/157.py @@ -1,11 +1,18 @@ + class Solution: + # 读取指定数量的字符到buf中 def read(self, buf, n): idx = 0 + # 不断循环直到读取完所需字符或缓冲区为空 while True: + # 一次性读取4个字符到临时缓存buf4中 buf4 = [""] * 4 curr = min(read4(buf4), n - idx) + # 将有效字符逐个复制到目标buf中并更新索引idx for i in range(curr): buf[idx] = buf4[i] idx += 1 + + # 如果当前读取的字符不足4个或已达到所需数量,返回实际读取的数量 if curr != 4 or idx == n: return idx diff --git a/solutions/python3/158.py b/solutions/python3/158.py index a37b430..3c1bd94 100644 --- a/solutions/python3/158.py +++ b/solutions/python3/158.py @@ -1,3 +1,4 @@ + """ The read4 API is already defined for you. @@ -12,22 +13,41 @@ def read4(buf): read4(buf) # read4 returns 4. Now buf = ['e','f','g','h'], fp points to 'i' read4(buf) # read4 returns 3. Now buf = ['i','j','k',...], fp points to end of file """ + class Solution: - def __init__(self): + """ + Initialize an empty queue to store characters. + """ self.queue = [] def read(self, buf, n): + """ + Read up to n characters from the file and store them into buffer buf. + + :param buf: Destination buffer (List[str]) + :type n: Number of characters to read (int) + :return: The number of actual characters read (int) + """ idx = 0 while True: - buf4 = [""]*4 - read4(buf4) + # Create a temporary buffer with size 4 for read4 API + buf4 = [""] * 4 + # Read up to 4 characters from the file into buf4 + num_chars_read = read4(buf4) + + # Add these characters to our queue self.queue += buf4 - curr = min(len(self.queue), n-idx) + + # Calculate the number of characters we can add to buf + curr = min(num_chars_read, n - idx) for i in range(curr): + # Pop characters from the front of the queue and store them in buf buf[idx] = self.queue.pop(0) - idx+=1 + idx += 1 + + # If no more characters were added, break out of the loop if curr == 0: - break + break + return idx - \ No newline at end of file diff --git a/solutions/python3/159.py b/solutions/python3/159.py index 88983f0..c40e10c 100644 --- a/solutions/python3/159.py +++ b/solutions/python3/159.py @@ -1,14 +1,26 @@ + class Solution: - def lengthOfLongestSubstringTwoDistinct(self, s): + # 定义一个类来解决最长不含重复字符的子字符串问题 + + def lengthOfLongestSubstringTwoDistinct(self, s: str) -> int: + # 初始化起始位置和不同字符计数器 start = distinct = 0 + # 使用字典记录每个字符出现次数 cnt = collections.defaultdict(int) + for c in s: + # 更新当前字符的计数 cnt[c] += 1 + # 如果当前字符是首次出现,则不同字符计数加一 if cnt[c] == 1: distinct += 1 + + # 当不同字符计数超过2时,调整起始位置和计数器 if distinct > 2: cnt[s[start]] -= 1 if not cnt[s[start]]: distinct -= 1 start += 1 - return len(s) - start \ No newline at end of file + + # 返回最长不含重复字符子字符串的长度 + return len(s) - start diff --git a/solutions/python3/16.py b/solutions/python3/16.py index 4b57329..b72386b 100644 --- a/solutions/python3/16.py +++ b/solutions/python3/16.py @@ -1,14 +1,32 @@ + class Solution: + # 定义一个类,用于解决寻找最接近目标值的三个数之和的问题 + def threeSumClosest(self, nums, target): - res = diff = float("inf") - nums.sort() + """ + :param nums: List[int] - 一个整数数组 + :param target: int - 目标整数值 + :return: int - 三个元素之和最接近目标值的和 + """ + + res = diff = float("inf") # 初始化结果变量res和差值diff为无穷大 + nums.sort() # 对数组进行排序,便于后续操作 + for i in range(len(nums)): - if i > 0 and nums[i] == nums[i - 1]: continue - l, r = i + 1, len(nums) - 1 + if i > 0 and nums[i] == nums[i - 1]: continue # 跳过重复的元素 + + l, r = i + 1, len(nums) - 1 # 定义左右指针 while l < r: - sm = nums[i] + nums[l] + nums[r] - if abs(sm - target) < diff: diff, res = abs(sm - target), sm - if sm < target: l += 1 - elif sm > target: r -= 1 - else: return res - return res \ No newline at end of file + sm = nums[i] + nums[l] + nums[r] # 计算三个数之和 + + if abs(sm - target) < diff: + diff, res = abs(sm - target), sm # 更新最小差值及其对应的三数之和 + + if sm < target: + l += 1 # 如果当前和小于目标,则移动左指针 + elif sm > target: + r -= 1 # 如果当前和大于目标,则移动右指针 + else: + return res # 如果找到等于目标的三数之和,直接返回 + + return res # 返回最接近目标值的三个数之和 diff --git a/solutions/python3/161.py b/solutions/python3/161.py index f8177ba..3a2a960 100644 --- a/solutions/python3/161.py +++ b/solutions/python3/161.py @@ -1,14 +1,28 @@ + class Solution: - def isOneEditDistance(self, s, t): - l1, l2, cnt, i, j = len(s), len(t), 0, 0, 0 + def isOneEditDistance(self, s: str, t: str) -> bool: + """ + 判断两个字符串是否仅通过一次编辑操作就能变为相同。 + + 英文注释:Determine if two strings can become the same after performing at most one edit operation. + """ + l1, l2 = len(s), len(t) + cnt, i, j = 0, 0, 0 + + # 遍历两个字符串 while i < l1 and j < l2: if s[i] != t[j]: cnt += 1 + # 根据长度调整索引 if l1 < l2: - i -= 1 - elif l1 > l2: j -= 1 + elif l1 > l2: + i -= 1 i += 1 j += 1 + + # 计算长度差值 l = abs(l1 - l2) - return (cnt == 1 and l <= 1) or (cnt == 0 and l == 1) \ No newline at end of file + + # 返回是否满足编辑距离条件 + return (cnt == 1 and l <= 1) or (cnt == 0 and l == 1) diff --git a/solutions/python3/162.py b/solutions/python3/162.py index a32737d..3e57b32 100644 --- a/solutions/python3/162.py +++ b/solutions/python3/162.py @@ -1,9 +1,24 @@ + class Solution: + # Python 解决方案类 + def findPeakElement(self, nums): + """ + :type nums: List[int] + :rtype: int + """ + # 初始化左右指针和数组长度 l, r, n = 0, len(nums) - 1, len(nums) + + # 使用二分查找进行优化 while l <= r: mid = (l + r) // 2 + # 处理边界情况,获取前后元素值 pre, after = mid == 0 and -float("inf") or nums[mid - 1], mid == n - 1 and -float("inf") or nums[mid + 1] + + # 当前元素为峰值返回其索引 if pre < nums[mid] > after: return mid + + # 根据比较结果调整左右指针位置 elif pre > nums[mid]: r = mid - 1 - else: l = mid + 1 \ No newline at end of file + else: l = mid + 1 diff --git a/solutions/python3/163.py b/solutions/python3/163.py index 6b67c6e..88c08ff 100644 --- a/solutions/python3/163.py +++ b/solutions/python3/163.py @@ -1,19 +1,36 @@ + class Solution: def findMissingRanges(self, nums, lower, upper): + """ + 寻找缺失的数字范围 + + :param nums: 整数数组 + :param lower: 区间下限 + :param upper: 区间上限 + :return: 缺失的数字范围列表 + """ if not nums: - return [str(lower) + "->" + str(upper)] if lower != upper else [str(lower)] + # 如果nums为空,直接返回一个缺失范围或单独缺失的数字 + return [f"{lower}->{upper}"] if lower != upper else [str(lower)] + res, n = [], len(nums) + # 处理区间起点前的缺失情况 if lower + 1 < nums[0]: - res.append(str(lower) + "->" + str(nums[0] - 1)) + res.append(f"{lower}->{nums[0] - 1}") elif lower + 1 == nums[0]: res.append(str(lower)) + + # 遍历数组,找到并记录中间和结尾的缺失区间 for i in range(1, n): - if nums[i] == nums[i - 1] + 2: + if nums[i] > nums[i - 1] + 2: + res.append(f"{nums[i - 1] + 1}->{nums[i] - 1}") + elif nums[i] == nums[i - 1] + 2: res.append(str(nums[i] - 1)) - elif nums[i] > nums[i - 1] + 2: - res.append(str(nums[i - 1] + 1) + "->" + str(nums[i] - 1)) - if nums[-1] + 1 < upper: - res.append(str(nums[-1] + 1) + "->" + str(upper)) + + # 处理区间结尾后的缺失情况 + if nums[-1] + 1 < upper: + res.append(f"{nums[-1] + 1}->{upper}") elif nums[-1] + 1 == upper: res.append(str(upper)) - return res \ No newline at end of file + + return res diff --git a/solutions/python3/164.py b/solutions/python3/164.py index e7e497e..eb390aa 100644 --- a/solutions/python3/164.py +++ b/solutions/python3/164.py @@ -1,20 +1,43 @@ + class Solution: def maximumGap(self, nums): + """ + 计算给定整数列表中最大差值。 + + Args: + nums (List[int]): 整数列表 + + Returns: + int: 最大差值 + + 1. 如果数字数量小于2,则直接返回0,因为至少需要两个元素才能计算差值。 + 2. 初始化变量:n表示数组长度,mn和mx分别记录最小值与最大值。 + 3. 计算桶大小bSize,以确保每个桶中的数据分布尽可能均匀。这里的+1是为了处理极端情况,例如所有数都相同的情况。 + 4. 根据bSize计算需要的桶的数量bNum。 + 5. 初始化桶列表buckets,每个桶由一个包含两个元素的列表表示,分别记录当前桶中的最小值和最大值。 + 6. 遍历输入数组nums,将每个数字分配到相应的桶中,并更新该桶的最大最小值。 + 7. 计算相邻桶之间的最大差值。如果某个桶为空,则将其与前一个桶合并。 + 8. 返回找到的最大差值。 + """ if len(nums) < 2: return 0 - n, mn, mx= len(nums), min(nums), max(nums) + + n, mn, mx = len(nums), min(nums), max(nums) bSize = max(1, (mx - mn) // n + 1) bNum = (mx - mn) // bSize + 1 buckets = [[float("inf"), -float("inf")] for _ in range(bNum)] + for num in nums: ind = (num - mn) // bSize if num < buckets[ind][0]: buckets[ind][0] = num if num > buckets[ind][1]: buckets[ind][1] = num + gap = 0 for i in range(1, bNum): if buckets[i] == [float("inf"), -float("inf")]: buckets[i] = buckets[i - 1] - gap = max(gap , buckets[i][0] - buckets[i - 1][1]) - return gap \ No newline at end of file + gap = max(gap, buckets[i][0] - buckets[i - 1][1]) + + return gap diff --git a/solutions/python3/165.py b/solutions/python3/165.py index 727ccb4..d1aed8f 100644 --- a/solutions/python3/165.py +++ b/solutions/python3/165.py @@ -1,13 +1,44 @@ + class Solution: - def compareVersion(self, version1, version2): - def getNum(s): - if not s: return (None, None) - for i in range(len(s)): - if s[i] == ".": return (s[i + 1:], int(s[:i])) - return (None, int(s)) + # 定义辅助函数,解析字符串中的数字部分和剩余部分 + def getNum(self, s): + """ + :param s: str 要解析的版本号字符串 + :return: tuple(剩余部分, 解析出的整数) + """ + if not s: + return (None, None) + + for i in range(len(s)): + if s[i] == ".": + # 找到小数点,返回剩余部分和解析出的整数 + return (s[i + 1:], int(s[:i])) + + # 如果没有找到小数点,则返回整个字符串转换后的整数 + return (None, int(s)) + + def compareVersion(self, version1: str, version2: str) -> int: + """ + :param version1: str 第一个版本号字符串 + :param version2: str 第二个版本号字符串 + :return: int 比较结果 -1、0、1 分别表示版本2小于等于/等于/大于版本1 + """ + while True: - version1, n1 = getNum(version1) - version2, n2 = getNum(version2) - if version1 == version2 == n1 == n2 == None: return 0 - if n1 != None and n1 > 0 and (n2 == None or n1 > n2): return 1 - if n2 != None and n2 > 0 and (n1 == None or n2 > n1): return -1 \ No newline at end of file + # 解析version1,获取剩余部分和解析出的整数 + version1, n1 = self.getNum(version1) + + # 解析version2,获取剩余部分和解析出的整数 + version2, n2 = self.getNum(version2) + + # 如果两字符串均解析完毕且无数字部分,则返回0 + if version1 == version2 == n1 == n2 == None: + return 0 + + # 如果version1有非零数值且大于version2对应的数值或version2为空,返回1 + if (n1 != None and n1 > 0) and (n2 == None or n1 > n2): + return 1 + + # 如果version2有非零数值且大于version1对应的数值或version1为空,返回-1 + if (n2 != None and n2 > 0) and (n1 == None or n2 > n1): + return -1 diff --git a/solutions/python3/166.py b/solutions/python3/166.py index 74ec0a6..246ff87 100644 --- a/solutions/python3/166.py +++ b/solutions/python3/166.py @@ -1,19 +1,37 @@ + class Solution: - def fractionToDecimal(self, n, d): + # 将分数转换为小数形式 + def fractionToDecimal(self, n: int, d: int) -> str: + # 根据符号决定结果是否需要加负号 res = ["-"] if n * d < 0 else [""] n, d = abs(n), abs(d) + + # 整数部分的处理 res.append(str(n // d)) n %= d - if not n: return "".join(res) + + # 如果没有余数,直接返回结果 + if not n: + return "".join(res) + + # 小数部分开始 res.append(".") + + # 使用哈希表记录出现循环的小数值及其位置 mp = {n: len(res)} + while n: n *= 10 res.append(str(n // d)) n %= d + + # 如果再次出现相同的余数,说明进入循环了 if n in mp: res.insert(mp[n], "(") res.append(")") break + + # 更新哈希表记录当前余数的位置 mp[n] = len(res) - return "".join(res) \ No newline at end of file + + return "".join(res) diff --git a/solutions/python3/167.py b/solutions/python3/167.py index 21a21f2..7ce0775 100644 --- a/solutions/python3/167.py +++ b/solutions/python3/167.py @@ -1,23 +1,27 @@ + class Solution: - def twoSum(self, numbers, target): + def twoSum(self, numbers: list[int], target: int) -> list[int]: """ - :type numbers: List[int] - :type target: int - :rtype: List[int] + :type numbers: List[int] # 输入的整数列表 + :type target: int # 需要找到和为目标值的两个数之和 + :rtype: List[int] # 返回索引,从1开始计数 + + 双指针法:一个指针从数组开头出发(left),另一个指针从数组末尾出发(right) + 根据两数之和与目标值的关系调整指针位置直至找到正确解 """ - left=numbers[0] - right=numbers[-1] - i,j=0,0 + left = numbers[0] # 初始化左指针指向第一个元素 + right = numbers[-1] # 初始化右指针指向最后一个元素 + + i, j = 0, 0 # 分别记录左右指针对应的索引位置,初始为0 + while True: - sum=left+right - if sum>target: - j+=1 - right=numbers[-1-j] - if sum target: # 当前和大于目标值 + j += 1 # 右指针左移 + right = numbers[-1 - j] # 更新右指针对应的数值 + elif current_sum < target: # 当前和小于目标值 + i += 1 # 左指针右移 + left = numbers[i] # 更新左指针对应的数值 + else: # 找到正确解 + return [i + 1, len(numbers) - j] # 返回索引(从1开始计数) diff --git a/solutions/python3/168.py b/solutions/python3/168.py index b579c0d..c742bda 100644 --- a/solutions/python3/168.py +++ b/solutions/python3/168.py @@ -1,11 +1,16 @@ + class Solution: + # 将整数n转换为对应的Excel表格中的列标题 def convertToTitle(self, n: int) -> str: - char = str() + result = "" + # 当n大于0时,持续进行转换 while n > 0: if n % 26 == 0: - char += "Z" - n = n // 26 - 1 + # 如果n模26等于0,则当前位为'Z' + result += "Z" + n = (n // 26) - 1 else: - char += chr(n % 26 + ord("@")) + # 否则,计算当前字符并添加到结果中 + result += chr((n % 26) + ord("@")) n = n // 26 - return char[::-1] + return result[::-1] # 反转字符串以获得正确的列标题 diff --git a/solutions/python3/169.py b/solutions/python3/169.py index 212b71f..fa18602 100644 --- a/solutions/python3/169.py +++ b/solutions/python3/169.py @@ -1,13 +1,19 @@ + class Solution: + # 定义一个类,用于解决众数问题 + def majorityElement(self, nums): """ - :type nums: List[int] - :rtype: int + :param nums: List[int] - 输入的整数列表 + :return: int - 列表中的众数 """ - num_list=dict() + num_list = dict() # 创建字典用于存储数字及其出现次数 + for num in nums: - if not num in num_list: - num_list[num]=1 + if num not in num_list: + num_list[num] = 1 # 如果数字不在字典中,初始化其计数为1 else: - num_list[num]+=1 - return max(num_list, key=num_list.get) \ No newline at end of file + num_list[num] += 1 # 否则,增加该数字的计数 + + # 返回出现次数最多的那个数字,使用key=num_list.get作为依据 + return max(num_list, key=num_list.get) diff --git a/solutions/python3/17.py b/solutions/python3/17.py index 9be99cf..84f9142 100644 --- a/solutions/python3/17.py +++ b/solutions/python3/17.py @@ -1,9 +1,25 @@ + class Solution: + # 初始化字典和结果列表 def letterCombinations(self, digits): - dic, res = { '2': 'abc', '3': 'def', '4': 'ghi', '5': 'jkl', '6': 'mno', '7': 'pqrs', '8': 'tuv', '9': 'wxyz'}, [""] + # 中文注释:初始化字母映射字典和结果列表,初始值为一个空字符串 + dic, res = {'2': 'abc', '3': 'def', '4': 'ghi', '5': 'jkl', + '6': 'mno', '7': 'pqrs', '8': 'tuv', '9': 'wxyz'}, [''] + + # 中文注释:遍历输入的每个数字 for dig in digits: + # 中文注释:临时列表,用于存储当前层的结果组合 tmp = [] + + # 中文注释:遍历当前结果列表中的每个字符串 for y in res: - for x in dic[dig]: tmp.append(y + x) - res = tmp - return res if any(res) else [] \ No newline at end of file + # 中文注释:遍历对应字母映射字典中的每个字符 + for x in dic[dig]: + # 中文注释:将当前字符添加到字符串后,加入临时列表 + tmp.append(y + x) + + # 更新结果列表为临时列表的内容 + res = tmp + + # 返回结果列表,如果为空则返回空列表 + return res if any(res) else [] diff --git a/solutions/python3/170.py b/solutions/python3/170.py index 69ee959..1b00ba0 100644 --- a/solutions/python3/170.py +++ b/solutions/python3/170.py @@ -1,13 +1,18 @@ + class TwoSum: + # 初始化类,使用字典存储数字及其出现次数 def __init__(self): self.nums = {} - def add(self, number): + # 添加一个数到集合中,同时更新其出现次数 + def add(self, number: int) -> None: self.nums[number] = self.nums.get(number, 0) + 1 - def find(self, value): + # 检查是否存在两个数之和等于给定值 + def find(self, value: int) -> bool: for num in self.nums: - if value - num in self.nums and (num != value - num or self.nums[num] > 1): + if (value - num in self.nums and + (num != value - num or self.nums[num] > 1)): return True - return False \ No newline at end of file + return False diff --git a/solutions/python3/171.py b/solutions/python3/171.py index 1162439..a29850d 100644 --- a/solutions/python3/171.py +++ b/solutions/python3/171.py @@ -1,7 +1,10 @@ + class Solution: - def titleToNumber(self, s): + # 将Excel列标题转换为对应的数字,例如'A' -> 1, 'Z' -> 26, 'AA' -> 27, 等等。 + def titleToNumber(self, s: str) -> int: """ :type s: str :rtype: int """ - return sum([(ord(char)-64)*(26**i) for i,char in enumerate(s[::-1])]) \ No newline at end of file + # 反向遍历字符串,计算每个字符对应的权重值并累加结果 + return sum([(ord(char)-64)*(26**i) for i,char in enumerate(s[::-1])]) diff --git a/solutions/python3/172.py b/solutions/python3/172.py index 87cb177..e9b27fe 100644 --- a/solutions/python3/172.py +++ b/solutions/python3/172.py @@ -1,7 +1,15 @@ + class Solution: - def trailingZeroes(self, n): + # 计算n!的末尾零个数,使用递归方式 + def trailingZeroes(self, n: int) -> int: """ - :type n: int - :rtype: int + :param n: 输入整数 n + :return: 返回 n! 末尾零的个数 + + 例如: + >>> Solution().trailingZeroes(5) + 1 + >>> Solution().trailingZeroes(20) + 4 """ - return 0 if n == 0 else n // 5 + self.trailingZeroes(n // 5) \ No newline at end of file + return 0 if n == 0 else n // 5 + self.trailingZeroes(n // 5) diff --git a/solutions/python3/173.py b/solutions/python3/173.py index 9ef7fa2..2d316a9 100644 --- a/solutions/python3/173.py +++ b/solutions/python3/173.py @@ -1,17 +1,22 @@ + class BSTIterator: - def __init__(self, root: TreeNode): + # 初始化迭代器,传入根节点 + def __init__(self, root: 'TreeNode'): self.stack = [] self.pushAll(root) + # 返回二叉搜索树中的下一个最小的数 def next(self) -> int: cur = self.stack.pop() self.pushAll(cur.right) return cur.val + # 判断迭代器中是否还有节点 def hasNext(self) -> bool: - return self.stack + return len(self.stack) > 0 + # 将当前节点的所有左子节点压入栈中 def pushAll(self, node): while node != None: - self.stack += (node,) + self.stack.append(node) node = node.left diff --git a/solutions/python3/174.py b/solutions/python3/174.py index 06686c3..b122c05 100644 --- a/solutions/python3/174.py +++ b/solutions/python3/174.py @@ -1,14 +1,20 @@ + class Solution: + # 计算最少生命值函数,输入是一个二维数组dungeon表示迷宫的地图 def calculateMinimumHP(self, dungeon): - m, n = len(dungeon), len(dungeon[0]) - for i in range(m - 1, -1, -1): - for j in range(n - 1, -1, -1): - if i == m - 1 and j == n - 1: - dungeon[i][j] = max(1, 1 - dungeon[i][j]) - elif j == n - 1: + m, n = len(dungeon), len(dungeon[0]) # 获取地图的行数m和列数n + + # 从右下角向左上角反向遍历 + for i in range(m - 1, -1, -1): # 逐行倒序 + for j in range(n - 1, -1, -1): # 逐列倒序 + if i == m - 1 and j == n - 1: # 到达右下角的单元格 + dungeon[i][j] = max(1, 1 - dungeon[i][j]) # 确保初始位置的生命值不为0或负数 + elif j == n - 1: # 处于最右侧的一列,只能从上一个单元格向下移动 dungeon[i][j] = max(1, dungeon[i + 1][j] - dungeon[i][j]) - elif i == m - 1: + elif i == m - 1: # 处于最下侧的一行,只能从左边的单元格向右移动 dungeon[i][j] = max(1, dungeon[i][j + 1] - dungeon[i][j]) else: + # 普通情况:考虑上方和右方两个方向的最大值 dungeon[i][j] = max(1, min(dungeon[i + 1][j], dungeon[i][j + 1]) - dungeon[i][j]) - return dungeon[0][0] \ No newline at end of file + + return dungeon[0][0] # 返回左上角的最小生命值,即为整个地图所需的最少初始生命值 diff --git a/solutions/python3/179.py b/solutions/python3/179.py index fbbbb8e..b3f3b5c 100644 --- a/solutions/python3/179.py +++ b/solutions/python3/179.py @@ -1,18 +1,27 @@ + class Solution: - def largestNumber(self, nums): - def partition(l, r): - j = l - for i in range(l + 1, r + 1): - if nums[i] + nums[l] >= nums[l] + nums[i]: - j += 1 - nums[j], nums[i] = nums[i], nums[j] - nums[l], nums[j] = nums[j], nums[l] - return j - def quickSort(l, r): - if l < r: - m = partition(l, r) - quickSort(l, m - 1) - quickSort(m + 1, r) - nums = [str(num) for num in nums] - quickSort(0, len(nums) - 1) - return str(int("".join(nums))) \ No newline at end of file + # 定义快速排序的分区函数,用于比较两个数拼接后的大小 + def partition(self, l: int, r: int): + j = l + for i in range(l + 1, r + 1): + if nums[i] + nums[l] >= nums[l] + nums[i]: + # 如果num[i]+nums[l] >= nums[l]+num[i],则交换位置 + j += 1 + nums[j], nums[i] = nums[i], nums[j] + # 最后将分界点与第一个元素交换 + nums[l], nums[j] = nums[j], nums[l] + return j + + # 定义快速排序函数 + def quickSort(self, l: int, r: int): + if l < r: + m = self.partition(l, r) + self.quickSort(l, m - 1) + self.quickSort(m + 1, r) + + # 将数字转换为字符串数组,并进行排序 + nums = [str(num) for num in nums] + quickSort(0, len(nums) - 1) + + # 合并成一个数,去掉前导零,返回结果 + return str(int("".join(nums))) diff --git a/solutions/python3/18.py b/solutions/python3/18.py index 7c634c1..1de630a 100644 --- a/solutions/python3/18.py +++ b/solutions/python3/18.py @@ -1,16 +1,38 @@ + class Solution: + # 定义一个类来解决四数之和问题 + def fourSum(self, nums, target): + """ + :param nums: 列表,包含整数 + :param target: 目标值 + :return: 返回所有满足条件的四元组列表 + """ res, res_set = [], set() - nums.sort() + # 初始化结果列表和一个集合用于去重 + + nums.sort() # 对输入列表进行排序以简化后续操作 + for i in range(len(nums) - 1): if i > 0 and nums[i] == nums[i - 1]: continue + # 跳过重复元素,避免结果重复 + for j in range(i + 1, len(nums)): l, r = j + 1, len(nums) - 1 + # 设置双指针初始位置 + while l < r: - sm = nums[i] + nums[j] + nums[l] + nums[r] - if sm < target: l += 1 - elif sm > target: r -= 1 - elif (nums[i], nums[j], nums[l], nums[r]) not in res_set: - res.append([nums[i], nums[j], nums[l], nums[r]]); res_set.add((nums[i], nums[j], nums[l], nums[r])) - else: l, r = l + 1, r - 1 - return res \ No newline at end of file + sm = nums[i] + nums[j] + nums[l] + nums[r] + # 计算当前四数之和 + + if sm < target: + l += 1 + elif sm > target: + r -= 1 + else: + if (nums[i], nums[j], nums[l], nums[r]) not in res_set: + res.append([nums[i], nums[j], nums[l], nums[r]]) + res_set.add((nums[i], nums[j], nums[l], nums[r])) + # 如果当前四数之和等于目标值且未在结果集中,则加入结果集 + l, r = l + 1, r - 1 + return res # 返回最终的结果列表 diff --git a/solutions/python3/186.py b/solutions/python3/186.py index abb74fc..6350c00 100644 --- a/solutions/python3/186.py +++ b/solutions/python3/186.py @@ -1,17 +1,23 @@ + class Solution: + # 定义一个类用于处理字符串 + def reverseWords(self, s): + # 反转整个字符串 l, r, n = 0, len(s) - 1, len(s) while l <= r: s[l], s[r] = s[r], s[l] l += 1 r -= 1 + + # 分别反转每个单词 l = r = 0 while r < n: - while r + 1 < n and s[r + 1] != " ": + while r + 1 < n and s[r + 1] != " ": # 找到空格,表示一个单词的结束 r += 1 - i = r + 2 - while l <= r: + i = r + 2 # 指向下一个单词的起始位置 + while l <= r: # 反转当前单词 s[l], s[r] = s[r], s[l] l += 1 r -= 1 - l = r = i \ No newline at end of file + l = r = i # 更新指针,准备处理下一个单词 diff --git a/solutions/python3/187.py b/solutions/python3/187.py index e6e1adb..d9471e0 100644 --- a/solutions/python3/187.py +++ b/solutions/python3/187.py @@ -1,11 +1,19 @@ + class Solution: - def findRepeatedDnaSequences(self, s): + def findRepeatedDnaSequences(self, s: str) -> list[str]: """ :type s: str :rtype: List[str] """ + # 使用字典存储滑动窗口内出现的DNA序列及其频率,初始化时加入一个无效字符以简化边界处理 dic, str = {}, "x" + s[:9] + + # 滑动窗口从第10个字符开始遍历到最后一个字符 for i in range(9, len(s)): + # 更新滑动窗口内的字符串,移除最左边的字符并添加当前字符 str = str[1:] + s[i] + # 根据字典更新频率或初始化为1 dic[str] = 1 if str not in dic else dic[str] + 1 - return [k for k, v in dic.items() if v > 1] \ No newline at end of file + + # 返回所有出现超过一次的DNA序列 + return [k for k, v in dic.items() if v > 1] diff --git a/solutions/python3/188.py b/solutions/python3/188.py index cd90de2..ae2d6f8 100644 --- a/solutions/python3/188.py +++ b/solutions/python3/188.py @@ -1,9 +1,39 @@ + class Solution: + # 定义一个解决最大利润问题的类 + def maxProfit(self, k, prices): - if k >= len(prices) // 2: return sum(sell - buy for sell, buy in zip(prices[1:], prices[:-1]) if sell - buy > 0) + """ + :param k: 可以进行的最大交易次数 + :param prices: 股票价格列表 + :return: 最大可能盈利 + + 中文注释: + 1. 如果可以进行的交易次数k大于等于股票天数的一半,则可以直接在所有正收益的日子里买卖,直接求和即可。 + 2. 否则需要动态规划来计算最大利润。 + + 英文注释: + 1. If the maximum number of transactions k is greater than or equal to half the length of the prices list, + we can make transactions in all days with positive profits by summing them up. + 2. Otherwise, use dynamic programming to calculate the maximum profit. + """ + + if k >= len(prices) // 2: + # 如果交易次数k大于等于价格列表长度的一半 + return sum(sell - buy for sell, buy in zip(prices[1:], prices[:-1]) if sell - buy > 0) + dp = [[0, -float("inf")] for _ in range(k + 1)] + # 初始化动态规划表,dp[i][0] 表示第i次交易的最大利润 + # dp[i][1] 表示第i次交易后的最大亏损 + for p in prices: for i in range(k + 1): - if i and dp[i - 1][1] + p > dp[i][0]: dp[i][0] = dp[i - 1][1] + p - if dp[i][0] - p > dp[i][1]: dp[i][1] = dp[i][0] - p - return dp[-1][0] \ No newline at end of file + if i and dp[i - 1][1] + p > dp[i][0]: + # 更新dp表,如果当前价格加上上次交易的亏损大于等于当前的最大利润,则更新 + dp[i][0] = dp[i - 1][1] + p + if dp[i][0] - p > dp[i][1]: + # 更新最大亏损记录 + dp[i][1] = dp[i][0] - p + + return dp[-1][0] + # 返回最后一次交易的最大利润 diff --git a/solutions/python3/189.py b/solutions/python3/189.py index 9ba9b5a..0fb39f5 100644 --- a/solutions/python3/189.py +++ b/solutions/python3/189.py @@ -1,10 +1,14 @@ + class Solution: - def rotate(self, nums, k): + # 用于旋转数组中的元素,不返回新列表,而是直接修改原地的nums列表 + def rotate(self, nums: list[int], k: int) -> None: """ - :type nums: List[int] - :type k: int - :rtype: void Do not return anything, modify nums in-place instead. + :type nums: List[int] # 输入是一个整数列表 + :type k: int # k是需要旋转的次数 + :rtype: void # 不返回任何值,直接修改输入的nums列表 """ - n=k%len(nums) + + n = k % len(nums) # 计算实际需要旋转的位置数量 + + # 通过切片操作重新组合数组内容并覆盖原数组 nums[:] = nums[-n:] + nums[:-n] - \ No newline at end of file diff --git a/solutions/python3/19.py b/solutions/python3/19.py index 456e2ab..a6ec977 100644 --- a/solutions/python3/19.py +++ b/solutions/python3/19.py @@ -1,12 +1,23 @@ + class Solution: - def removeNthFromEnd(self, head, n): + # 定义一个移除链表倒数第 n 个节点的方法 + def removeNthFromEnd(self, head: ListNode, n: int) -> ListNode: + # 创建哑结点,方便操作,返回结果时不包含哑结点 dummy = ListNode(0) dummy.next = head - arr = [dummy] + arr = [dummy] # 存储节点列表 + + # 遍历链表,将所有节点加入数组中 while head: arr.append(head) head = head.next + + # 移除倒数第 n 个节点 for _ in range(n + 1): pre = arr.pop() + + # 调整指针指向 pre.next = pre.next.next - return dummy.next \ No newline at end of file + + # 返回结果,跳过哑结点 + return dummy.next diff --git a/solutions/python3/198.py b/solutions/python3/198.py index 0939aeb..569ad95 100644 --- a/solutions/python3/198.py +++ b/solutions/python3/198.py @@ -1,6 +1,23 @@ + class Solution: + # 定义一个类用于解决打家劫舍问题 + def rob(self, nums): - if len(nums) <= 2: return max(nums or [0]) + """ + :param nums: List[int] - 一维数组,表示每户人家的金钱数 + :return: int - 最大能偷窃的金钱总数 + """ + if len(nums) <= 2: + # 如果房子少于等于两栋,则直接返回最大值 + return max(nums or [0]) + nums[2] += nums[0] - for i in range(3, len(nums)): nums[i] += max(nums[i - 2], nums[i - 3]) - return max(nums[-1], nums[-2]) \ No newline at end of file + # 第三栋房子的钱加上第一栋,因为不能连续偷盗 + + for i in range(3, len(nums)): + # 从第三栋房子开始遍历到最后一栋 + nums[i] += max(nums[i - 2], nums[i - 3]) + # 对于当前房子i,可以选择不偷窃上一栋或上上一栋的最大值加上当前房子的钱 + + return max(nums[-1], nums[-2]) + # 最后返回倒数第一和第二大的钱数中的较大者 diff --git a/solutions/python3/199.py b/solutions/python3/199.py index b16efcf..2fcbc6a 100644 --- a/solutions/python3/199.py +++ b/solutions/python3/199.py @@ -1,18 +1,22 @@ + # Definition for a binary tree node. -# class TreeNode: -# def __init__(self, x): -# self.val = x -# self.left = None -# self.right = None +class TreeNode: + def __init__(self, x): + self.val = x + self.left = None + self.right = None class Solution: - def rightSideView(self, root): - """ - :type root: TreeNode - :rtype: List[int] - """ + # 右视图,返回二叉树的右视图中每个节点的值 + def rightSideView(self, root: 'TreeNode') -> 'List[int]': q, res = [root], [] + + # 当队列不为空时继续遍历 while any(q): + # 将当前层最右边的节点值加入结果列表 res.append(q[-1].val) + + # 生成下一层节点的列表,仅包含非空子节点 q = [kid for node in q for kid in (node.left, node.right) if kid] - return res \ No newline at end of file + + return res diff --git a/solutions/python3/2.py b/solutions/python3/2.py index 7354952..b2cc1d0 100644 --- a/solutions/python3/2.py +++ b/solutions/python3/2.py @@ -1,16 +1,25 @@ + # Definition for singly-linked list. -# class ListNode: -# def __init__(self, x): -# self.val = x -# self.next = None +class ListNode: + def __init__(self, x): + self.val = x + self.next = None class Solution: + # 向链表中添加两个数的和 def addTwoNumbers(self, l1: ListNode, l2: ListNode) -> ListNode: - left = 0 - dummy = cur = ListNode(-1) + left = 0 # 进位值 + dummy = cur = ListNode(-1) # 哑节点,用于简化返回结果 + while l1 or l2 or left: - left, sm = divmod(sum(l and l.val or 0 for l in (l1, l2)) + left, 10) + # 计算当前位的和及进位 + sm, left = divmod(sum(l and l.val for l in (l1, l2)) + left, 10) + + # 创建新的链表节点并连接到结果中 cur.next = cur = ListNode(sm) - l1 = l1 and l1.next - l2 = l2 and l2.next - return dummy.next \ No newline at end of file + + # 移动指针,准备处理下一位 + l1 = l1.next if l1 else None + l2 = l2.next if l2 else None + + return dummy.next # 返回真正的头节点 diff --git a/solutions/python3/20.py b/solutions/python3/20.py index 2058a93..b6ef088 100644 --- a/solutions/python3/20.py +++ b/solutions/python3/20.py @@ -1,9 +1,19 @@ + class Solution: - def isValid(self, s): - brackets_stack, lefts, rights = [], ("(", "[", "{"), (")", "]", "}") + # 判断字符串s中的括号是否有效,即所有左括号都有对应的右括号且顺序正确 + + def isValid(self, s: str) -> bool: + # 初始化栈和左右括号集合 + brackets_stack = [] + lefts, rights = ("(", "[", "{"), (")", "]", "}") + for char in s: + # 如果当前字符是左括号,入栈 if char in lefts: brackets_stack.append(char) elif not brackets_stack or lefts.index(brackets_stack.pop()) != rights.index(char): + # 如果当前字符是右括号且不匹配或栈为空则返回False return False - return not brackets_stack \ No newline at end of file + + # 栈为空表示所有左括号都有对应的右括号且顺序正确,返回True + return not brackets_stack diff --git a/solutions/python3/200.py b/solutions/python3/200.py index a2e5abc..936961a 100644 --- a/solutions/python3/200.py +++ b/solutions/python3/200.py @@ -1,13 +1,38 @@ + class Solution: - def numIslands(self, grid): - res, n, m = 0, len(grid), len(grid[0]) if grid else 0 - def explore(i, j): + def numIslands(self, grid: List[List[str]]) -> int: + """ + 计算给定二维网格中岛屿的数量。 + + 参数: + - grid : List[List[str]] -- 给定的二维网格 + + 返回值: + int -- 岛屿的数量 + """ + if not grid or len(grid) == 0: + return 0 + + res, n, m = 0, len(grid), len(grid[0]) + + def explore(i: int, j: int): + """ + 使用深度优先搜索探索岛屿。 + + 参数: + - i : int -- 行索引 + - j : int -- 列索引 + """ grid[i][j] = "-1" if i > 0 and grid[i - 1][j] == "1": explore(i - 1, j) if j > 0 and grid[i][j - 1] == "1": explore(i, j - 1) if i + 1 < n and grid[i + 1][j] == "1": explore(i + 1, j) if j + 1 < m and grid[i][j + 1] == "1": explore(i, j + 1) - for i in range(n): + + for i in range(n): for j in range(m): - if grid[i][j] == "1": explore(i, j); res += 1 - return res \ No newline at end of file + if grid[i][j] == "1": + explore(i, j) + res += 1 + + return res diff --git a/solutions/python3/201.py b/solutions/python3/201.py index f5d7a61..afbaa4c 100644 --- a/solutions/python3/201.py +++ b/solutions/python3/201.py @@ -1,8 +1,24 @@ + class Solution: - def rangeBitwiseAnd(self, m, n): + # 定义一个类,用于解决位运算问题 + + def rangeBitwiseAnd(self, m: int, n: int) -> int: + # 该方法接受两个整数m和n作为输入,返回它们之间的按位与结果 + i = 0 + # 初始化计数器i为0,用于记录右移次数 + while m != n: + # 当m和n不相等时循环 + m >>= 1 + # 将m右移一位 + n >>= 1 + # 将n右移一位 + i += 1 - return m << i \ No newline at end of file + # 计数器i加1,记录右移次数 + + return m << i + # 返回m左移i位的结果,即为m和n之间的按位与结果 diff --git a/solutions/python3/202.py b/solutions/python3/202.py index 0db27d6..f84042f 100644 --- a/solutions/python3/202.py +++ b/solutions/python3/202.py @@ -1,12 +1,22 @@ + class Solution: def isHappy(self, n): """ :type n: int :rtype: bool """ + # 使用集合记录已经出现过的数字,避免重复计算 + # Use a set to record numbers that have appeared to avoid redundant calculations mem = set() + while n != 1: + # 将当前数字转换为字符串,并计算每个字符的平方和 + # Convert the current number to string and calculate the sum of squares of each character n = sum([int(i) ** 2 for i in str(n)]) - if n in mem: return False - else: mem.add(n) - else: return True \ No newline at end of file + + if n in mem: + return False + else: + mem.add(n) + else: + return True diff --git a/solutions/python3/203.py b/solutions/python3/203.py index e9d0527..743cfa4 100644 --- a/solutions/python3/203.py +++ b/solutions/python3/203.py @@ -1,21 +1,32 @@ + # Definition for singly-linked list. -# class ListNode: -# def __init__(self, x): -# self.val = x -# self.next = None +class ListNode: + def __init__(self, x): + self.val = x + self.next = None class Solution: - def removeElements(self, head, val): + # 移除链表中的指定值节点 + def removeElements(self, head: 'ListNode', val: int) -> 'ListNode': """ :type head: ListNode :type val: int :rtype: ListNode """ + # 使用虚拟头节点简化边界情况处理 prev, curr = ListNode(None), head + while curr: - if curr.val==val: - if curr==head: head=head.next - prev.next=curr.next - if curr.val!=val: prev=curr - curr=curr.next - return head \ No newline at end of file + if curr.val == val: + # 当前节点值等于目标值,跳过当前节点 + if curr == head: + head = head.next + else: + prev.next = curr.next + elif curr.val != val: + # 当前节点值不等于目标值,移动指针到下一个节点 + prev = curr + + curr = curr.next + + return head diff --git a/solutions/python3/204.py b/solutions/python3/204.py index 203aad4..76c6347 100644 --- a/solutions/python3/204.py +++ b/solutions/python3/204.py @@ -1,8 +1,32 @@ + class Solution: + # 计算小于n的质数个数 def countPrimes(self, n): - primes = [i for i in range(2, n)] - for i in range(2, n): - for prime in primes: - if i ** (prime - 1) % prime != 1 and prime > i: - primes.remove(prime) - return len(primes) + """ + :param n: int - 需要计算小于该值的质数个数 + :return: int - 小于n的质数个数 + + 优化点:使用埃拉托斯特尼筛法来更高效地找出所有质数。 + 原代码错误在于对每个i都去掉了非质数,且方法不正确。 + + 新方案:遍历2到sqrt(n)之间的数字,如果当前数是质数,则将它的倍数标记为合数。 + """ + + # 如果n小于2,直接返回0 + if n < 2: + return 0 + + # 初始化一个布尔数组,用于标记每个索引的值是否为质数 + is_prime = [True] * n + p = 2 + + while p * p < n: + # 如果is_prime[p]没有被标记为False,则p是质数 + if is_prime[p]: + # 标记p的倍数为合数 + for i in range(p * p, n, p): + is_prime[i] = False + p += 1 + + # 统计数组中True的数量,即质数个数 + return sum(is_prime) diff --git a/solutions/python3/205.py b/solutions/python3/205.py index 5823318..8052ff1 100644 --- a/solutions/python3/205.py +++ b/solutions/python3/205.py @@ -1,13 +1,22 @@ + class Solution: - def isIsomorphic(self, s, t): + # 类:解决方案 + + def isIsomorphic(self, s: str, t: str) -> bool: """ - :type s: str - :type t: str - :rtype: bool + :param s: 字符串s + :param t: 字符串t + :return: 如果字符串s和字符串t是同构的返回True,否则返回False """ - if len(s) != len(t): return False - dic={} - for i in range(len(s)): - if not t[i] in dic.values() and not s[i] in dic: dic[s[i]] = t[i] - elif not s[i] in dic or dic[s[i]] != t[i]: return False - return True \ No newline at end of file + if len(s) != len(t): # 判断两个字符串长度是否相等 + return False + + dic = {} # 创建字典用于存储对应关系 + + for i in range(len(s)): # 遍历字符串s和t的每个字符 + if s[i] not in dic and t[i] not in dic.values(): # 如果当前字符在字典中没有映射且目标字符未被使用 + dic[s[i]] = t[i] # 建立对应关系 + elif s[i] in dic and dic[s[i]] != t[i]: # 如果已有映射但不匹配 + return False # 返回False + + return True # 完成遍历,返回True diff --git a/solutions/python3/206.py b/solutions/python3/206.py index d41c812..e9231f5 100644 --- a/solutions/python3/206.py +++ b/solutions/python3/206.py @@ -1,3 +1,4 @@ + # Definition for singly-linked list. # class ListNode: # def __init__(self, x): @@ -5,8 +6,19 @@ # self.next = None class Solution: + """ + 定义一个方法来反转单链表。 + + 参数: + head: 链表的头节点 + pre: 前一个节点,默认为None,用于记录链表反转时的前驱节点 + + 返回值: + 反转后的链表头节点 + """ def reverseList(self, head: ListNode, pre = None) -> ListNode: + # 如果当前节点不为空,则继续递归调用 if head: - nex = head.next - head.next = pre - return self.reverseList(nex, head) if nex else head \ No newline at end of file + nex = head.next # 记录下一个节点 + head.next = pre # 修改当前节点指向前驱节点 + return self.reverseList(nex, head) if nex else head # 递归反转剩余链表,直到到达尾节点 diff --git a/solutions/python3/207.py b/solutions/python3/207.py index a225646..06bf618 100644 --- a/solutions/python3/207.py +++ b/solutions/python3/207.py @@ -1,13 +1,38 @@ + class Solution: - def canFinish(self, numCourses, prerequisites): - def cycle(course): - visited[course] = 0 - for Next in route[course]: - if visited[Next] == 0 or (visited[Next] == -1 and cycle(Next)): return True - visited[course] = 1 + def canFinish(self, numCourses: int, prerequisites: list) -> bool: + """ + 判断是否可以完成所有课程。 + + :param numCourses: 课程总数 + :param prerequisites: 先修课程关系列表,每个元素为 [先修课程ID, 依赖课程ID] + :return: 如果可以完成所有课程则返回True,否则返回False + + 通过构建图和检测环来判断是否能完成所有课程。 + """ + + def cycle(course: int) -> bool: + """ + 检测以给定课程为起点是否存在环 + + :param course: 当前检查的课程 + :return: 如果存在环则返回True,否则返回False + """ + visited[course] = 0 # 标记正在访问该节点 + for next_course in route[course]: + if visited[next_course] == 0 or (visited[next_course] == -1 and cycle(next_course)): + return True + visited[course] = 1 # 标记已完全访问该节点 return False + + # 构建图和初始化访问状态数组 route, visited = {i: [] for i in range(numCourses)}, [-1] * numCourses - for req in prerequisites: route[req[1]].append(req[0]) + for req in prerequisites: + route[req[1]].append(req[0]) + + # 检查每个课程是否存在环 for course in range(numCourses): - if visited[course] == -1 and cycle(course): return False - return True \ No newline at end of file + if visited[course] == -1 and cycle(course): # 只检查未访问的节点 + return False + + return True diff --git a/solutions/python3/208.py b/solutions/python3/208.py index 545e1bc..c917ced 100644 --- a/solutions/python3/208.py +++ b/solutions/python3/208.py @@ -1,12 +1,25 @@ + class Trie: def __init__(self): """ - Initialize your data structure here. + 初始化字典树数据结构。 + Initialize the Trie data structure. """ self.root = {} - + def move(self, word, mod): + """ + 将单词插入到字典树中或检查是否存在前缀/单词。 + Insert a word into the trie or check for prefix existence. + + :param word: 要处理的字符串 + :type word: str + :param mod: 操作模式,1-插入,2-查找单词,3-查找前缀 + :type mod: int + :return: 根据操作模式返回相应的布尔值或None + :rtype: bool or None + """ cur = self.root for c in word: if c not in cur: @@ -15,25 +28,41 @@ def move(self, word, mod): cur[c] = {} cur = cur[c] if mod == 1: - cur['#'] = None + cur['#'] = None # 标记单词结束 else: return mod == 3 or '#' in cur - + def insert(self, word: str) -> None: """ - Inserts a word into the trie. + 将一个单词插入到字典树中。 + Insert a word into the trie. + + :param word: 要插入的单词 + :type word: str """ return self.move(word, 1) def search(self, word: str) -> bool: """ + 检查一个单词是否存在于字典树中。 Returns if the word is in the trie. + + :param word: 要查找的单词 + :type word: str + :return: 如果单词存在返回True,否则返回False + :rtype: bool """ return self.move(word, 2) def startsWith(self, prefix: str) -> bool: """ + 检查字典树中是否存在以给定前缀开头的任何单词。 Returns if there is any word in the trie that starts with the given prefix. + + :param prefix: 要查找的前缀 + :type prefix: str + :return: 如果存在以该前缀开头的单词返回True,否则返回False + :rtype: bool """ return self.move(prefix, 3) @@ -42,4 +71,4 @@ def startsWith(self, prefix: str) -> bool: # obj = Trie() # obj.insert(word) # param_2 = obj.search(word) -# param_3 = obj.startsWith(prefix) \ No newline at end of file +# param_3 = obj.startsWith(prefix) diff --git a/solutions/python3/209.py b/solutions/python3/209.py index a66c116..64d8fb2 100644 --- a/solutions/python3/209.py +++ b/solutions/python3/209.py @@ -1,7 +1,19 @@ + class Solution: def minSubArrayLen(self, s, nums): - l, res, curr = 0, len(nums) + 1, 0 - for r, num in enumerate(nums): - curr += num - while curr >= s: res, l, curr = min(res, r - l + 1), l + 1, curr - nums[l] - return res < len(nums) + 1 and res or 0 \ No newline at end of file + """ + 输入目标和s以及数组nums,返回满足条件的最小子数组长度。 + + :param s: int 目标和 + :param nums: List[int] 数组元素 + :return: int 满足条件的最小子数组长度,若无则返回0 + """ + l, res, curr = 0, len(nums) + 1, 0 # 初始化左指针l、结果res和当前子数组和curr + + for r, num in enumerate(nums): # 遍历数组nums的每个元素,索引为r,值为num + curr += num # 更新当前子数组和curr + + while curr >= s: # 当前子数组和大于等于目标和s时 + res, l, curr = min(res, r - l + 1), l + 1, curr - nums[l] # 更新结果res,右移左指针l并更新当前子数组和curr + + return res < len(nums) + 1 and res or 0 # 返回满足条件的最小子数组长度 diff --git a/solutions/python3/21.py b/solutions/python3/21.py index 1fcd1d5..9e350d7 100644 --- a/solutions/python3/21.py +++ b/solutions/python3/21.py @@ -1,16 +1,22 @@ + # Definition for singly-linked list. -# class ListNode: -# def __init__(self, x): -# self.val = x -# self.next = None +class ListNode: + def __init__(self, x): + self.val = x # 节点值 + self.next = None # 指向下一个节点的指针 class Solution: def mergeTwoLists(self, l1: ListNode, l2: ListNode) -> ListNode: - if not l1: return l2 - elif not l2: return l1 - if l1.val < l2.val: - l1.next = self.mergeTwoLists(l1.next, l2) + # 如果l1为空,返回l2 + if not l1: + return l2 + # 如果l2为空,返回l1 + elif not l2: return l1 + # 比较两个节点的值,较小者作为新链表的一部分 + if l1.val < l2.val: + l1.next = self.mergeTwoLists(l1.next, l2) # 递归合并剩余部分 + return l1 # 返回当前较小节点 else: - l2.next = self.mergeTwoLists(l1, l2.next) - return l2 \ No newline at end of file + l2.next = self.mergeTwoLists(l1, l2.next) # 递归合并剩余部分 + return l2 # 返回当前较小节点 diff --git a/solutions/python3/210.py b/solutions/python3/210.py index b21afa4..47705f1 100644 --- a/solutions/python3/210.py +++ b/solutions/python3/210.py @@ -1,10 +1,31 @@ + class Solution: - def findOrder(self, numCourses, prerequisites): - children, parent = collections.defaultdict(set), collections.defaultdict(set) - for i, j in prerequisites: children[i].add(j); parent[j].add(i) + def findOrder(self, numCourses: int, prerequisites: list[tuple[int, int]]) -> list[int]: + """ + :param numCourses: 课程总数 + :param prerequisites: 先修课程列表,每个元素为一个元组 (后续课程, 先修课程) + :return: 满足先修条件的课程顺序列表,如果不存在这样的顺序则返回空列表 + + 使用拓扑排序来找出满足所有先修关系的课程学习顺序。 + """ + + # 构建邻接表 + children = collections.defaultdict(set) # 后续课程 -> 先修课程集合 + parent = collections.defaultdict(set) # 先修课程 -> 后续课程集合 + + for course, pre_course in prerequisites: + children[course].add(pre_course) + parent[pre_course].add(course) + + # 初始入度为0的节点入栈 stack = [i for i in range(numCourses) if not children[i]] - for i in stack: - for j in parent[i]: - children[j].remove(i) - if not children[j]: stack += j, - return stack if len(stack) == numCourses else [] \ No newline at end of file + + # 拓扑排序 + while stack: + current_course = stack.pop() + for next_course in parent[current_course]: + children[next_course].discard(current_course) + if not children[next_course]: # 如果先修课程的入度变为0,加入栈中 + stack.append(next_course) + + return stack if len(stack) == numCourses else [] diff --git a/solutions/python3/211.py b/solutions/python3/211.py index dc7e720..f505255 100644 --- a/solutions/python3/211.py +++ b/solutions/python3/211.py @@ -1,16 +1,23 @@ + + class TrieNode: + # 构造器初始化节点,每个节点包含26个子节点指针和一个标记是否为单词结尾的标志 def __init__(self): self.children = [None] * 26 self.last = False + + class WordDictionary: def __init__(self): + # 初始化字典树根节点 """ Initialize your data structure here. """ self.root = TrieNode() def addWord(self, word): + # 添加单词到数据结构中 """ Adds a word into the data structure. :type word: str @@ -18,10 +25,13 @@ def addWord(self, word): """ curr = self.root for char in word: - if not curr.children[ord(char) - ord("a")]: curr.children[ord(char) - ord("a")] = TrieNode() + if not curr.children[ord(char) - ord("a")]: + curr.children[ord(char) - ord("a")] = TrieNode() curr = curr.children[ord(char) - ord("a")] curr.last = True + def search(self, word): + # 搜索单词,允许通配符"." """ Returns if the word is in the data structure. A word could contain the dot character '.' to represent any one letter. :type word: str @@ -29,13 +39,20 @@ def search(self, word): """ words = [self.root] for char in word: - if char == ".": words = [child for node in words for child in node.children if node and child] - else: words = [node.children[ord(char) - ord("a")] for node in words if node and node.children[ord(char) - ord("a")]] - if words and words[-1] == ".": return True - else: return any([node.last for node in words if node.last]) + if char == ".": + # 通配符匹配所有可能的子节点 + words = [child for node in words for child in node.children if node and child] + else: + # 普通字符仅匹配对应的子节点 + words = [node.children[ord(char) - ord("a")] for node in words if node and node.children[ord(char) - ord("a")]] + # 判断是否找到单词或其结尾标记为True的节点 + if words and (words[-1] is None or words[-1].last): + return True + else: + return any([node.last for node in words if node and node.last]) -# Your WordDictionary object will be instantiated and called as such: +# 你的WordDictionary对象将被实例化并调用如下: # obj = WordDictionary() # obj.addWord(word) -# param_2 = obj.search(word) \ No newline at end of file +# param_2 = obj.search(word) diff --git a/solutions/python3/212.py b/solutions/python3/212.py index b7d3d1e..54fe50d 100644 --- a/solutions/python3/212.py +++ b/solutions/python3/212.py @@ -1,20 +1,46 @@ + class Solution: def findWords(self, board, words): + """ + :type board: List[List[str]] + :type words: List[str] + :rtype: List[str] + + :中文说明:此方法用于查找给定棋盘上的所有单词。通过构建字典树(Trie)并进行深度优先搜索来实现。 + """ + def explore(i, j, cur): + """ + :中文说明:递归函数,用于在棋盘上探索相邻节点。 + """ visited[i][j] = 0 - if "#" in cur and cur["#"] not in res_set: res.append(cur["#"]); res_set.add(cur["#"]) + if "#" in cur and cur["#"] not in res_set: + res.append(cur["#"]) + res_set.add(cur["#"]) + for x, y in ((i - 1, j), (i + 1, j), (i, j - 1), (i, j + 1)): - if 0 <= x < m and 0 <= y < n and board[x][y] in cur and visited[x][y] == -1: explore(x, y, trie[cur[board[x][y]]]) + if 0 <= x < m and 0 <= y < n and board[x][y] in cur and visited[x][y] == -1: + explore(x, y, trie[cur[board[x][y]]]) + visited[i][j] = -1 + + # 初始化字典树、计数器、棋盘尺寸和相关结果集 trie, cnt, m, n, res, res_set = {}, 1, len(board), len(board and board[0]), [], set() + + # 构建字典树trie visited, trie[0] = [[-1] * n for _ in range(m)], {} for w in words: cur = trie[0] for c in w: - if c not in cur: trie[cnt], cur[c], cnt = {}, cnt, cnt + 1 + if c not in cur: + trie[cnt], cur[c], cnt = {}, cnt, cnt + 1 cur = trie[cur[c]] cur["#"] = w + + # 在棋盘上进行探索,找到所有单词 for i in range(m): for j in range(n): - if board[i][j] in trie[0]: explore(i, j, trie[trie[0][board[i][j]]]) - return res \ No newline at end of file + if board[i][j] in trie[0]: + explore(i, j, trie[trie[0][board[i][j]]]) + + return res diff --git a/solutions/python3/213.py b/solutions/python3/213.py index f0cab7f..c5a4849 100644 --- a/solutions/python3/213.py +++ b/solutions/python3/213.py @@ -1,10 +1,29 @@ + class Solution: - + + # 动态规划计算最大抢劫金额 def dp(self, nums): - if len(nums) <= 2: return max(nums or [0]) + """ + 使用动态规划求解子问题,跳过相邻的房屋进行抢劫。 + + :param nums: List[int], 房屋中的金钱数数组 + :return: int, 最大抢劫金额 + """ + if len(nums) <= 2: + # 如果房屋数量小于等于2,则直接返回最大值 + return max(nums or [0]) nums[2] += nums[0] - for i in range(3, len(nums)): nums[i] += max(nums[i - 2], nums[i - 3]) + for i in range(3, len(nums)): + # 当前房屋的金钱数加上前两个或前三个房屋中较大的抢劫金额 + nums[i] += max(nums[i - 2], nums[i - 3]) return max(nums[-1], nums[-2]) - + + # 主函数,根据实际情况选择最优方案 def rob(self, nums): - return max(self.dp(nums[:-1]), self.dp(nums[1:])) if len(nums) != 1 else nums[0] \ No newline at end of file + """ + 根据房屋数量,决定是否从第一个或最后一个房屋开始进行抢劫。 + + :param nums: List[int], 房屋中的金钱数数组 + :return: int, 最大抢劫金额 + """ + return max(self.dp(nums[:-1]), self.dp(nums[1:])) if len(nums) != 1 else nums[0] diff --git a/solutions/python3/214.py b/solutions/python3/214.py index c22de06..2a0cc0e 100644 --- a/solutions/python3/214.py +++ b/solutions/python3/214.py @@ -1,6 +1,16 @@ + class Solution: - def shortestPalindrome(self, s, pre = ""): + def shortestPalindrome(self, s, pre=""): + """ + :param s: 输入字符串 + :param pre: 辅助变量,用于存储前缀反转结果,默认为空字符串 + :return: 返回最短回文串 + """ for i in range(1, len(s) // 2 + 2): - if s[i - 1:].startswith(s[:i][::-1]): pre = s[2* i - 1:][::-1] - if s[i:].startswith(s[:i][::-1]): pre = s[2* i:][::-1] - return pre + s \ No newline at end of file + # 检查从当前索引开始的子串是否为之前部分的反转 + if s[i - 1:].startswith(s[:i][::-1]): + pre = s[2 * i - 1:][::-1] + # 同上,检查从当前索引之后的子串是否为之前部分的反转 + elif s[i:].startswith(s[:i][::-1]): + pre = s[2 * i:][::-1] + return pre + s diff --git a/solutions/python3/215.py b/solutions/python3/215.py index 7018efc..9b7ad38 100644 --- a/solutions/python3/215.py +++ b/solutions/python3/215.py @@ -1,3 +1,7 @@ + class Solution: + # 寻找数组中第k大的元素 + def findKthLargest(self, nums, k): - return heapq.nlargest(k, nums)[-1] \ No newline at end of file + # 使用heapq的nlargest方法找到前k个最大的数,返回其中最小的一个即为所求 + return heapq.nlargest(k, nums)[-1] diff --git a/solutions/python3/216.py b/solutions/python3/216.py index add30bb..5fb5849 100644 --- a/solutions/python3/216.py +++ b/solutions/python3/216.py @@ -1,14 +1,22 @@ + class Solution: def combinationSum3(self, k, n): """ - :type k: int - :type n: int - :rtype: List[List[int]] + :type k: int # k 表示组合中数字的数量 + :type n: int # n 表示目标和 + :rtype: List[List[int]] # 返回满足条件的组合列表 """ stack, nums, res = [(0, [], 0, k)], range(1, 10), [] + while stack: sm, tmp, index, k_val = stack.pop(0) + for i in range(index, len(nums)): - if sm + nums[i] < n and k_val > 0: stack.append((sm + nums[i], tmp + [nums[i]], i + 1, k_val - 1)) - elif sm + nums[i] == n and k_val == 1: res.append(tmp + [nums[i]]) - return res \ No newline at end of file + if sm + nums[i] < n and k_val > 0: + # 如果当前和小于目标值且剩余组合数大于0,将新状态加入栈中 + stack.append((sm + nums[i], tmp + [nums[i]], i + 1, k_val - 1)) + elif sm + nums[i] == n and k_val == 1: + # 如果当前和等于目标值且剩余组合数为1,将该组合加入结果列表 + res.append(tmp + [nums[i]]) + + return res diff --git a/solutions/python3/217.py b/solutions/python3/217.py index f594ddb..17b2c36 100644 --- a/solutions/python3/217.py +++ b/solutions/python3/217.py @@ -1,13 +1,18 @@ + class Solution: def containsDuplicate(self, nums): """ - :type nums: List[int] - :rtype: bool + 判断给定的整数列表中是否存在重复元素。 + + :param nums: List[int] - 整数列表 + :return: bool - 如果存在重复返回True,否则返回False """ - dic=dict() + dic = dict() # 创建一个字典用于存储已遍历过的数字 + for num in nums: - if not num in dic: - dic[num]=1 + if not num in dic: # 检查当前数字是否已在字典中 + dic[num] = 1 # 如果不在,则将其加入字典,值为1表示出现一次 else: - return True - return False \ No newline at end of file + return True # 如果在字典中找到相同数字,说明有重复,返回True + + return False # 遍历完整个列表未发现重复元素,返回False diff --git a/solutions/python3/218.py b/solutions/python3/218.py index 4922a79..f7beb85 100644 --- a/solutions/python3/218.py +++ b/solutions/python3/218.py @@ -1,12 +1,26 @@ + class Solution: def getSkyline(self, buildings): + # 创建事件列表,包含建筑物的左边界和右边界事件,并排序 + # 事件表示为 (位置, 高度, 结束位置),使用负高度表示开始事件,0 表示结束事件 events = sorted([(L, -H, R) for L, R, H in buildings] + list({(R, 0, None) for _, R, _ in buildings})) + + # 初始化结果列表和优先队列 res, hp = [[0, 0]], [(0, float("inf"))] + + # 遍历所有事件 for x, negH, R in events: - while x >= hp[0][1]: + # 调整高度堆,移除不再有效的建筑物高度 + while x >= hp[0][1]: heapq.heappop(hp) + + # 如果当前事件为建筑物开始,则将其高度加入优先队列 if negH: heapq.heappush(hp, (negH, R)) + + # 判断并更新最高高度变化情况 if res[-1][1] + hp[0][0]: res += [x, -hp[0][0]], - return res[1:] \ No newline at end of file + + # 返回结果列表(去掉第一个默认的[0, 0]) + return res[1:] diff --git a/solutions/python3/219.py b/solutions/python3/219.py index d76b1a3..97fbedc 100644 --- a/solutions/python3/219.py +++ b/solutions/python3/219.py @@ -1,13 +1,20 @@ + class Solution: + # 判断给定列表 nums 中是否存在两个不同的索引 i 和 j,使得 nums[i] == nums[j] 且 abs(i - j) <= k + def containsNearbyDuplicate(self, nums, k): """ :type nums: List[int] :type k: int :rtype: bool """ - dic={} - for i,num in enumerate(nums): - if num in dic and i-dic[num]<=k: - return True - dic[num]=i - return False \ No newline at end of file + # 使用字典记录每个数字最后出现的位置 + dic = {} + for i, num in enumerate(nums): + # 检查当前数字是否已经存在于字典中,并且索引差值小于等于k + if num in dic and i - dic[num] <= k: + return True + # 更新字典记录当前数字的最新位置 + dic[num] = i + # 如果遍历完整个列表都没有找到符合条件的情况,则返回False + return False diff --git a/solutions/python3/22.py b/solutions/python3/22.py index b68635b..56c8621 100644 --- a/solutions/python3/22.py +++ b/solutions/python3/22.py @@ -1,6 +1,14 @@ + class Solution: + # Python 解决括号生成问题 + def generateParenthesis(self, n: int) -> List[str]: - bfs = [(0, 0, '')] - for c in range(n * 2): - bfs = [(l + 1, r, s + '(') for l, r, s in bfs if l + 1 <= n] + [(l, r + 1, s + ')') for l, r, s in bfs if l - r] - return [s for l, r, s in bfs] \ No newline at end of file + # 使用广度优先搜索(BFS)来构建所有可能的括号组合 + bfs = [(0, 0, '')] # 初始化状态队列,每个元素为 (左括号数, 右括号数, 当前生成的字符串) + + for c in range(n * 2): # 遍历生成 n 对括号的所有可能组合 + bfs = [(l + 1, r, s + '(') for l, r, s in bfs if l + 1 <= n] + \ + [(l, r + 1, s + ')') for l, r, s in bfs if l - r] + + # 返回最终生成的所有有效括号字符串 + return [s for l, r, s in bfs] diff --git a/solutions/python3/220.py b/solutions/python3/220.py index aa0af20..e0033a0 100644 --- a/solutions/python3/220.py +++ b/solutions/python3/220.py @@ -1,11 +1,28 @@ + class Solution: + # 定义一个类,用于解决附近近乎重复元素的问题 + def containsNearbyAlmostDuplicate(self, nums, k, t): - if t < 0: return False + """ + 判断在数组nums中是否存在两个不同的索引i和j使得 |i - j| <= k 且 |nums[i] - nums[j]| <= t + :param nums: List[int], 输入的整数列表 + :param k: int, 索引差的最大值限制 + :param t: int, 数字差的最大值限制 + :return: bool, 如果存在这样的两个元素返回True,否则返回False + """ + if t < 0: + # 时间复杂度为O(n),空间复杂度为O(min(n, k)),其中n是数组的长度 + return False + d = {} for i in range(len(nums)): m = nums[i] // (t + 1) + # 检查当前元素是否接近已存在的桶中的元素 if m in d or (m - 1 in d and nums[i] - d[m - 1] <= t) or (m + 1 in d and d[m + 1] - nums[i] <= t): return True + # 将当前元素放入对应桶中 d[m] = nums[i] - if i >= k: del d[nums[i - k] // (t + 1)] - return False \ No newline at end of file + # 移除超出窗口范围的元素 + if i >= k: + del d[nums[i - k] // (t + 1)] + return False diff --git a/solutions/python3/221.py b/solutions/python3/221.py index 2c57b9c..4dabbe0 100644 --- a/solutions/python3/221.py +++ b/solutions/python3/221.py @@ -1,23 +1,44 @@ + class Solution: def maximalSquare(self, matrix): """ :type matrix: List[List[str]] :rtype: int """ + # Initialize result and current square size res, count = 0, 0 + + # Iterate through the matrix for i in range(len(matrix)): for j in range(len(matrix[0])): + # Convert cell value to integer matrix[i][j] = int(matrix[i][j]) + + # Check if current cell can be part of a square if matrix[i][j] != 0: count = 1 - if j>0 and int(matrix[i][j-1]) != 0: matrix[i][j] += int(matrix[i][j-1]) - if i-1>=0 and int(matrix[i-1][j]) != 0: - k, curr = i-1, [] - while k>=0 and k>=i-matrix[i][j]+1 and int(matrix[k][j]) != 0: - if matrix[k][j]>= count+1: + + # Update the square size from left neighbor + if j > 0 and int(matrix[i][j - 1]) != 0: + matrix[i][j] += int(matrix[i][j - 1]) + + # Update the square size considering upper diagonal cells + if i - 1 >= 0 and int(matrix[i - 1][j]) != 0: + k, curr = i - 1, [] + + while k >= 0 and k >= i - matrix[i][j] + 1 and int(matrix[k][j]) != 0: + if matrix[k][j] >= count + 1: curr.append(matrix[k][j]) - if min(curr)>= count+1: count += 1 - else: break + + # Update current square size + if min(curr) >= count + 1: + count += 1 + else: + break + k -= 1 - res = max(res, count**2) - return res \ No newline at end of file + + # Update the maximum square size found + res = max(res, count ** 2) + + return res diff --git a/solutions/python3/222.py b/solutions/python3/222.py index 66f9879..c62ed5e 100644 --- a/solutions/python3/222.py +++ b/solutions/python3/222.py @@ -1,13 +1,31 @@ + class Solution: - + + # 计算节点总数 def countNodes(self, root): - if not root: return 0 - l = self.getDepth(root.left) - r = self.getDepth(root.right) + """ + :param root: 树的根节点 (Node) + :return: 树中节点总数 (int) + """ + if not root: + return 0 + + l = self.getDepth(root.left) # 获取左子树深度 + r = self.getDepth(root.right) # 获取右子树深度 + if l == r: + # 如果左右子树深度相同,则节点总数为2^l + 右子树节点数 return (1 << l) + self.countNodes(root.right) + + # 否则,节点总数为2^r + 左子树节点数 return (1 << r) + self.countNodes(root.left) - + + # 获取树的深度 def getDepth(self, root): - if not root: return 0 - return 1 + self.getDepth(root.left) \ No newline at end of file + """ + :param root: 树的根节点 (Node) + :return: 树的深度 (int) + """ + if not root: + return 0 + return 1 + self.getDepth(root.left) # 深度+1 diff --git a/solutions/python3/223.py b/solutions/python3/223.py index c64521c..7b43ee9 100644 --- a/solutions/python3/223.py +++ b/solutions/python3/223.py @@ -1,7 +1,20 @@ + class Solution: - def computeArea(self, a, b, c, d, e, f, g, h): - x1, x2, x3 = abs(a - c), abs(e - g), max(a, c, e, g) - min(a, c, e, g) - y1, y2, y3 = abs(b - d), abs(f - h), max(b, d, f, h) - min(b, d, f, h) - if x3 < x1 + x2 and y3 < y1 + y2: intrs = (x1 + x2 - x3) * (y1 + y2 - y3) - else: intrs = 0 - return x1 * y1 + x2 * y2 - intrs \ No newline at end of file + # 计算矩形的交集面积 + + def computeArea(self, ax1: int, ay1: int, ax2: int, ay2: int, bx1: int, by1: int, bx2: int, by2: int) -> int: + # 计算每个矩形的宽度和高度 + width_a = abs(ax1 - ax2) + height_a = abs(ay1 - ay2) + width_b = abs(bx1 - bx2) + height_b = abs(by1 - by2) + + # 计算重叠部分的宽度和高度 + overlap_width = max(min(ax2, bx2) - max(ax1, bx1), 0) + overlap_height = max(min(ay2, by2) - max(ay1, by1), 0) + + # 如果没有重叠,交集面积为0 + intersection_area = overlap_width * overlap_height if overlap_width > 0 and overlap_height > 0 else 0 + + # 总面积减去交集面积得到不重叠部分的面积 + return width_a * height_a + width_b * height_b - intersection_area diff --git a/solutions/python3/224.py b/solutions/python3/224.py index 080eb7d..fe65b1a 100644 --- a/solutions/python3/224.py +++ b/solutions/python3/224.py @@ -1,18 +1,31 @@ + class Solution: - def calculate(self, s): - def calc(n2, op, n1): + def calculate(self, s: str) -> int: + # 计算两个数根据运算符的加减操作 + def calc(n2: int, op: str, n1: int) -> int: return n1 + n2 if op == "+" else n1 - n2 - stack, i, num = [], 0, 0 + + stack = [] # 用于存储中间结果和操作符 + i, num = 0, 0 # 遍历字符串的索引与当前数字 + while i < len(s): j = i + # 将连续的数字转换为整数并记录位置 while j < len(s) and s[j].isdigit(): num, j = num * 10 + int(s[j]), j + 1 + if i != j: - stack.append(calc(num, stack.pop(), stack.pop()) if stack and s[i - 1] != "(" else num) + # 如果当前字符不是数字,说明之前解析了一个数字,进行计算 + stack.append(calc(num, stack.pop(), stack.pop()) + if stack and s[i - 1] != "(" else num) num, j = 0, j - 1 elif s[i] in "+-": + # 遇到加减号,直接压入栈中 stack.append(s[i]) elif s[i] == ")" and len(stack) > 1: + # 当遇到右括号时,进行相应的计算操作 stack.append(calc(stack.pop(), stack.pop(), stack.pop())) + i = j + 1 - return stack.pop() \ No newline at end of file + + return stack.pop() # 最终结果在栈顶 diff --git a/solutions/python3/225.py b/solutions/python3/225.py index 548067f..512c07a 100644 --- a/solutions/python3/225.py +++ b/solutions/python3/225.py @@ -1,44 +1,45 @@ + class MyStack: def __init__(self): """ - Initialize your data structure here. + 初始化栈数据结构。 """ self.data = [] - def push(self, x): + def push(self, x: int) -> None: """ - Push element x onto stack. - :type x: int - :rtype: void + 将元素x压入栈顶。 + :param x: 要添加的整数 + :return: 无返回值,仅为操作方法 """ self.data.append(x) - def pop(self): + def pop(self) -> int: """ - Removes the element on top of the stack and returns that element. - :rtype: int + 移除并返回栈顶元素。 + :return: 栈顶元素 """ return self.data.pop() - def top(self): + def top(self) -> int: """ - Get the top element. - :rtype: int + 返回栈顶元素,不移除。 + :return: 栈顶元素 """ return self.data[-1] - def empty(self): + def empty(self) -> bool: """ - Returns whether the stack is empty. - :rtype: bool + 判断栈是否为空。 + :return: True 表示栈空,False 表示非空 """ return not bool(self.data) -# Your MyStack object will be instantiated and called as such: +# 你的 MyStack 对象将被实例化并调用如下: # obj = MyStack() # obj.push(x) # param_2 = obj.pop() # param_3 = obj.top() -# param_4 = obj.empty() \ No newline at end of file +# param_4 = obj.empty() diff --git a/solutions/python3/226.py b/solutions/python3/226.py index a529fd7..3065b34 100644 --- a/solutions/python3/226.py +++ b/solutions/python3/226.py @@ -1,18 +1,26 @@ + # Definition for a binary tree node. -# class TreeNode: -# def __init__(self, x): -# self.val = x -# self.left = None -# self.right = None +class TreeNode: + def __init__(self, x): + self.val = x + self.left = None + self.right = None class Solution: - def invertTree(self, root): + # 递归翻转二叉树的左右子节点 + def invertTree(self, root: 'TreeNode') -> 'TreeNode': """ :type root: TreeNode :rtype: TreeNode """ - if not root: return - root.left, root.right= root.right, root.left + if not root: + return # 如果根节点为空,直接返回 + + # 交换当前节点的左、右子节点 + root.left, root.right = root.right, root.left + + # 递归翻转左右子树 self.invertTree(root.left) self.invertTree(root.right) - return root \ No newline at end of file + + return root # 返回根节点,已完成翻转操作 diff --git a/solutions/python3/227.py b/solutions/python3/227.py index 0af2411..84e21d2 100644 --- a/solutions/python3/227.py +++ b/solutions/python3/227.py @@ -1,34 +1,116 @@ + class Solution: - def calculate(self, s): + def calculate(self, s: str) -> int: + # 计算表达式s的结果,支持基本的加减乘除运算 + def calculate_expression(expression: list) -> int: + # 递归计算栈中的表达式结果 + stack = [] + i = 0 + n = len(expression) + + while i < n: + if expression[i] == " ": + i += 1 + continue + + while i < n and expression[i].isnumeric(): + num += expression[i] + i += 1 + + if stack and (stack[-1] in ["*", "/", "+", "-"]): + op = stack.pop() + num1 = stack.pop() + + if op == "*": + stack.append(num1 * int(num)) + elif op == "/": + stack.append(int(num1 / int(num))) + elif op == "+": + stack.append(num1 + int(expression[i])) + i += 1 + else: + stack.append(num1 - int(expression[i])) + i += 1 + + num = "" + + elif num: + stack.append(int(num)) + num = "" + + else: + stack.append(expression[i]) + i += 1 + + return sum(stack) + + # 初始处理 mod = 0 + while mod < 2: stack, i, n, num = [], 0, len(s), "" + + s = calculate_expression(list(s)) + + mod += 1 + + return s.pop() + + + +class Solution: + def calculate(self, s: str) -> int: + # 计算表达式s的结果,支持基本的加减乘除运算 + def calculate_expression(expression: list) -> int: + # 递归计算栈中的表达式结果 + stack = [] + i = 0 + n = len(expression) + while i < n: - if s[i] == " ": + if expression[i] == " ": i += 1 continue - while mod == 0 and i < n and s[i].isnumeric(): - num += s[i] + + while i < n and expression[i].isnumeric(): + num += expression[i] i += 1 - if stack and stack[-1] in [("*", "/"), ("+", "-")][mod]: - op, num1 = stack.pop(), stack.pop() + + if stack and (stack[-1] in ["*", "/", "+", "-"]): + op = stack.pop() + num1 = stack.pop() + if op == "*": stack.append(num1 * int(num)) elif op == "/": - stack.append(num1 // int(num)) + stack.append(int(num1 / int(num))) elif op == "+": - stack.append(num1 + s[i]) + stack.append(num1 + int(expression[i])) i += 1 else: - stack.append(num1 - s[i]) + stack.append(num1 - int(expression[i])) i += 1 + num = "" - elif num: + + elif num: stack.append(int(num)) num = "" + else: - stack.append(s[i]) + stack.append(expression[i]) i += 1 + + return sum(stack) + + # 初始处理 + mod = 0 + + while mod < 2: + stack, i, n, num = [], 0, len(s), "" + + s = calculate_expression(list(s)) + mod += 1 - s = stack - return stack.pop() \ No newline at end of file + + return s.pop() diff --git a/solutions/python3/228.py b/solutions/python3/228.py index 53f1ab7..b5a5c9f 100644 --- a/solutions/python3/228.py +++ b/solutions/python3/228.py @@ -1,12 +1,24 @@ + class Solution: def summaryRanges(self, nums): """ :type nums: List[int] :rtype: List[str] """ + # 初始化结果列表和栈 res, stack = [], [nums[0] if nums else None, None] + for i, num in enumerate(nums): - if i > 0 and nums[i - 1] == num - 1: stack[1] = num - if i > 0 and nums[i-1] != num - 1: res, stack[0], stack[1] = res + ["->".join(str(q) for q in stack if q != None)], num, None - if i == len(nums) - 1: res.append("->".join(str(q) for q in stack if q != None)) - return res \ No newline at end of file + # 检查当前数是否与前一个数连续,如果是,则更新栈顶元素 + if i > 0 and nums[i - 1] == num - 1: + stack[1] = num + + # 如果当前数不连续,则将栈中的范围加入结果,并清空栈 + elif i > 0 and nums[i-1] != num - 1: + res, stack[0], stack[1] = res + ["->".join(str(q) for q in stack if q != None)], num, None + + # 处理列表最后一个元素的情况 + if i == len(nums) - 1: + res.append("->".join(str(q) for q in stack if q != None)) + + return res diff --git a/solutions/python3/229.py b/solutions/python3/229.py index 06e55b0..989118d 100644 --- a/solutions/python3/229.py +++ b/solutions/python3/229.py @@ -1,16 +1,29 @@ + class Solution: + # 定义一个解决方案类 + def majorityElement(self, nums): + # 寻找数组中出现次数超过总数三分之一的元素(摩尔投票法) c1, c2, cnt1, cnt2 = 0, 1, 0, 0 + # 初始化候选元素和计数器,c1 和 c2 分别为两个候选值,cnt1 和 cnt2 用于统计候选值的出现次数 + for num in nums: if num == c1: cnt1 += 1 elif num == c2: cnt2 += 1 + # 如果当前数字等于c1,则增加c1的计数;如果等于c2,则增加c2的计数 + elif not cnt1: c1, cnt1 = num, 1 elif not cnt2: c2, cnt2 = num, 1 + # 如果cnt1为0,说明候选元素c1已经失效,选择当前数字作为新的候选元素,并初始化其计数器;相同逻辑处理c2 + else: cnt1 -= 1 cnt2 -= 1 - return [c for c in (c1, c2) if nums.count(c) > len(nums) // 3] \ No newline at end of file + # 其余情况下,减少两个候选值的计数 + + return [c for c in (c1, c2) if nums.count(c) > len(nums) // 3] + # 返回满足条件的最终候选元素(出现次数超过总数三分之一) diff --git a/solutions/python3/23.py b/solutions/python3/23.py index 2f70365..8b8f61e 100644 --- a/solutions/python3/23.py +++ b/solutions/python3/23.py @@ -1,17 +1,24 @@ + # Definition for singly-linked list. -# class ListNode: -# def __init__(self, x): -# self.val = x -# self.next = None +class ListNode: + def __init__(self, val=0, next=None): + self.val = val + self.next = next class Solution: - def mergeKLists(self, lists): + # 合并k个排序链表 + def mergeKLists(self, lists: List[ListNode]) -> ListNode: q = [] - for i in range(len(lists)): - while lists[i]: - q += lists[i], - lists[i] = lists[i].next - root = cur = ListNode(0) - for h in sorted(q, key = lambda x: x.val): - cur.next = cur = h - return root.next \ No newline at end of file + # 遍历所有链表,将节点值加入优先队列q中,并更新链表指针 + for li in lists: + while li: + q.append(li) + li = li.next + + root = cur = ListNode() # 创建新的链表头结点 + # 按照节点的val值从小到大排序,依次构建新链表 + for node in sorted(q, key=lambda x: x.val): + cur.next = node + cur = cur.next + + return root.next # 返回合并后的链表头部 diff --git a/solutions/python3/230.py b/solutions/python3/230.py index 90bf49a..ef77351 100644 --- a/solutions/python3/230.py +++ b/solutions/python3/230.py @@ -1,16 +1,38 @@ + # Definition for a binary tree node. -# class TreeNode: -# def __init__(self, x): -# self.val = x -# self.left = None -# self.right = None +class TreeNode: + def __init__(self, x): + self.val = x # 初始化节点值 + self.left = None # 初始化左子节点为None + self.right = None # 初始化右子节点为None class Solution: def __init__(self): - self.k, self.res = 0, None - def kthSmallest(self, root, k): - if self.k < k and root.left: self.kthSmallest(root.left, k) + self.k = 0 # 记录需要寻找的第k小元素的位置 + self.res = None # 存储结果,即找到的第k小元素 + + def kthSmallest(self, root: TreeNode, k: int) -> int: + """ + 寻找二叉搜索树中第k小的节点值。 + + :param root: 树根节点 + :param k: 需要寻找的第k小节点的位置 + :return: 第k小的节点值 + """ + + # 递归遍历左子树,找到第k小的元素 + if self.k < k and root.left: + self.kthSmallest(root.left, k) + + # 计数器加一,并检查是否已经找到了第k个元素 self.k += 1 - if self.k == k: self.res = root.val - if self.k < k and root.right: self.kthSmallest(root.right, k) - return self.res \ No newline at end of file + + # 如果是第k个元素,则记录其值 + if self.k == k: + self.res = root.val + + # 继续递归遍历右子树,找到第k小的元素 + if self.k < k and root.right: + self.kthSmallest(root.right, k) + + return self.res # 返回结果 diff --git a/solutions/python3/231.py b/solutions/python3/231.py index 4ce135d..9fce2f7 100644 --- a/solutions/python3/231.py +++ b/solutions/python3/231.py @@ -1,11 +1,15 @@ + class Solution: def isPowerOfTwo(self, n): """ - :type n: int - :rtype: bool + 判断一个整数是否为2的幂次方 + + :param n: int - 需要判断的整数 + :return: bool - 如果n是2的幂次方,返回True;否则返回False """ - i=0 - while 2**i<=n: - if 2**i==n: return True - i+=1 - return False \ No newline at end of file + i = 0 + while 2 ** i <= n: + if 2 ** i == n: + return True + i += 1 + return False diff --git a/solutions/python3/232.py b/solutions/python3/232.py index 0700c01..046638a 100644 --- a/solutions/python3/232.py +++ b/solutions/python3/232.py @@ -1,46 +1,47 @@ + class MyQueue: def __init__(self): """ - Initialize your data structure here. + 初始化队列数据结构。 """ self.data = [] - def push(self, x): + def push(self, x: int) -> None: """ - Push element x to the back of queue. - :type x: int - :rtype: void + 将元素x添加到队列末尾。 + :param x: 待添加的整数 + :return: 无返回值 """ self.data.append(x) - def pop(self): + def pop(self) -> int: """ - Removes the element from in front of queue and returns that element. - :rtype: int + 移除并返回队列前端的元素。 + :return: 前端元素,类型为int """ front = self.data[0] self.data = self.data[1:] return front - def peek(self): + def peek(self) -> int: """ - Get the front element. - :rtype: int + 返回队列前端的元素,不移除它。 + :return: 前端元素,类型为int """ return self.data[0] - def empty(self): + def empty(self) -> bool: """ - Returns whether the queue is empty. - :rtype: bool + 检查队列是否为空。 + :return: 如果队列为空返回True,否则返回False """ return not bool(self.data) -# 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() \ No newline at end of file +# param_4 = obj.empty() diff --git a/solutions/python3/233.py b/solutions/python3/233.py index 0629967..4f49b4d 100644 --- a/solutions/python3/233.py +++ b/solutions/python3/233.py @@ -1,15 +1,21 @@ + class Solution: - def countDigitOne(self, n): + # 定义一个计算从1到n之间数字中包含多少个1的方法 + def countDigitOne(self, n: int) -> int: if n <= 0: - return 0 - q, x, ans = n, 1, 0 - while q > 0: - digit = q % 10 - q //= 10 - ans += q * x + return 0 # 如果输入的数小于等于0,返回0 + + q, x, ans = n, 1, 0 # 初始化q为n,x为1,ans为0 + while q > 0: # 当q大于0时循环 + digit = q % 10 # 取当前位的数字 + q //= 10 # 更新q为去掉末尾数后的值 + + ans += q * x # 计算低位中每个位置上1出现的次数 + if digit == 1: - ans += n % x + 1 + ans += n % x + 1 # 当前位是1时,加上个位到n的贡献 elif digit > 1: - ans += x - x *= 10 - return ans \ No newline at end of file + ans += x # 当前位大于1时,当前位为1的情况要加x次 + + x *= 10 # 更新x的值,用于下一位数的计算 + return ans # 返回结果 diff --git a/solutions/python3/234.py b/solutions/python3/234.py index 5fd3bd7..1439494 100644 --- a/solutions/python3/234.py +++ b/solutions/python3/234.py @@ -1,11 +1,26 @@ + class Solution: + # 检查给定链表是否为回文结构 + def isPalindrome(self, head): + # 初始化快慢指针,初始时均指向头节点 r = fast = head + # 用于反转链表的部分的前驱节点 l = None + while fast and fast.next: + # 快指针每次移动两位 fast = fast.next.next + # 反转链表操作:将当前节点r连接到l之后,更新l和r指向 r.next, l, r = l, r, r.next - if fast: r = r.next + + if fast: + # 如果快指针走到底则表示节点数为奇数,此时r需要再向前一步 + r = r.next + + # 检查反转后的前半部分链表和未变的后半部分是否相等 while l and r and l.val == r.val: l, r = l.next, r.next - return not l \ No newline at end of file + + # 如果没有剩余节点,说明是回文结构 + return not l diff --git a/solutions/python3/235.py b/solutions/python3/235.py index f328f2c..bbf1b4e 100644 --- a/solutions/python3/235.py +++ b/solutions/python3/235.py @@ -1,10 +1,16 @@ + class Solution: + # 定义一个函数用于查找二叉搜索树的最近公共祖先节点 def lowestCommonAncestor( self, root: "TreeNode", p: "TreeNode", q: "TreeNode" ) -> "TreeNode": + # 如果p和q的值分别位于root左右,则当前root即为所求 if p.val < root.val > q.val: return self.lowestCommonAncestor(root.left, p, q) + + # 如果p和q的值分别位于root右左,则当前root即为所求 if p.val > root.val < q.val: return self.lowestCommonAncestor(root.right, p, q) + + # 返回当前节点作为最近公共祖先 return root - diff --git a/solutions/python3/236.py b/solutions/python3/236.py index c187792..867a472 100644 --- a/solutions/python3/236.py +++ b/solutions/python3/236.py @@ -1,7 +1,9 @@ + class Solution: - def lowestCommonAncestor( - self, root: "TreeNode", p: "TreeNode", q: "TreeNode" - ) -> "TreeNode": + # 寻找二叉树中两个节点的最近公共祖先 + + def lowestCommonAncestor(self, root: "TreeNode", p: "TreeNode", q: "TreeNode") -> "TreeNode": + # 使用字典记录每个节点的父节点,并使用栈进行深度优先搜索 parent, stack = {root: None}, [root] while p not in parent or q not in parent: node = stack.pop() @@ -11,10 +13,14 @@ def lowestCommonAncestor( if node.right: parent[node.right] = node stack.append(node.right) + + # 使用集合记录p的祖先节点 ancestors = set() while p: ancestors.add(p) p = parent[p] + + # 找到q的最近公共祖先 while q not in ancestors: q = parent[q] return q diff --git a/solutions/python3/237.py b/solutions/python3/237.py index bd59e3f..a0baa00 100644 --- a/solutions/python3/237.py +++ b/solutions/python3/237.py @@ -1,5 +1,14 @@ -class Solution: - def deleteNode(self, node): - node.val = node.next.val - node.next = node.next.next +class Solution: + # 删除链表中的节点 + def deleteNode(self, node: ListNode) -> None: + """ + :type node: ListNode + :rtype: None. Does not return anything, + modifies the linked list in place. + + 该方法用于删除给定的节点。它通过将当前节点的值设置为下一个节点的值,然后跳过下一个节点来实现。 + 这样就相当于移除了下一个节点。 + """ + node.val = node.next.val # 将当前节点值设为下一节点值 + node.next = node.next.next # 跳过下一节点,直接指向后继节点 diff --git a/solutions/python3/238.py b/solutions/python3/238.py index e01ae92..55d0fb1 100644 --- a/solutions/python3/238.py +++ b/solutions/python3/238.py @@ -1,15 +1,36 @@ + class Solution: - def productExceptSelf(self, nums): + def productExceptSelf(self, nums: list[int]) -> list[int]: """ - :type nums: List[int] - :rtype: List[int] + 计算每个索引位置的元素乘积,但不包括该位置的元素 + + 1. 初始化乘积结果和临时存储 + m = 1 # 用于累乘前半部分数组 + res = [] # 存储结果 + + 2. 遍历数组计算前缀积并存入结果列表中 + 对于每个元素,将其左侧所有元素的积累乘到m中,并将当前的m值存入结果列表 + + 3. 初始化右半部分的累积乘积为1 + m = 1 # 用于累乘后半部分数组 + + 4. 反向遍历数组,更新每个位置的结果为前缀积 * 后缀积 + 对于每个元素,将其右侧所有元素的积累乘到m中,并与结果列表中的值相乘 + + 5. 返回最终结果 + 返回累乘后的结果列表res """ m, res = 1, [] + + # 计算前缀积 for i in range(len(nums)): res.append(m) m *= nums[i] + + # 更新每个位置的结果为前缀积 * 后缀积 m = 1 - for i in range(len(nums)-1,-1,-1): + for i in range(len(nums) - 1, -1, -1): res[i] *= m m *= nums[i] - return res \ No newline at end of file + + return res diff --git a/solutions/python3/239.py b/solutions/python3/239.py index 486117b..32ab8fc 100644 --- a/solutions/python3/239.py +++ b/solutions/python3/239.py @@ -1,12 +1,29 @@ + class Solution: + # 定义一个类来解决滑动窗口最大值的问题 + def maxSlidingWindow(self, nums, k): - cnt, heap, res = collections.Counter(), [], [] + import collections + from heapq import heappush, heappop + + cnt = collections.Counter() # 统计元素出现次数 + heap = [] # 最大堆,用于维护当前窗口的最大值 + res = [] # 存储结果 + for i, num in enumerate(nums): - heapq.heappush(heap, -num) + # 将当前数的负值加入最大堆,并更新其在计数字典中的计数 + heappush(heap, -num) cnt[num] += 1 + + # 调整堆,确保堆顶元素为当前窗口的最大值 while not cnt[-heap[0]]: - heapq.heappop(heap) + heappop(heap) + + # 当遍历到第 k-1 个元素时开始填充结果数组 if i >= k - 1: - res.append(-heap[0]) + res.append(-heap[0]) # 将堆顶元素的正值加入结果数组 + + # 减少滑动窗口最左边元素的计数,以便在后续迭代中移除它 cnt[nums[i - k + 1]] -= 1 - return res \ No newline at end of file + + return res diff --git a/solutions/python3/24.py b/solutions/python3/24.py index 421fe33..e3a3445 100644 --- a/solutions/python3/24.py +++ b/solutions/python3/24.py @@ -1,14 +1,24 @@ + # Definition for singly-linked list. -# class ListNode: -# def __init__(self, x): -# self.val = x -# self.next = None +class ListNode: + def __init__(self, x): + self.val = x + self.next = None class Solution: + # 交换链表中每两个相邻节点 def swapPairs(self, head: ListNode) -> ListNode: - if not head or not head.next: return head - first = head.next - second = head - second.next = self.swapPairs(first.next) - first.next = second - return first \ No newline at end of file + """ + :param head: 链表头节点 + :return: 交换后的链表头节点 + """ + if not head or not head.next: + # 如果链表为空或只有一个节点,直接返回头节点 + return head + + first = head.next # 第一个要交换的节点 + second = head # 当前节点 + second.next = self.swapPairs(first.next) # 递归处理下一个pair + first.next = second # 完成当前pair的交换 + + return first # 返回新的头节点 diff --git a/solutions/python3/240.py b/solutions/python3/240.py index bb723ab..8ffd236 100644 --- a/solutions/python3/240.py +++ b/solutions/python3/240.py @@ -1,3 +1,16 @@ + class Solution: + # 检查二维矩阵中是否包含目标值 + def searchMatrix(self, matrix, target): - return any(target in row for row in matrix) \ No newline at end of file + # 使用任何一行中存在目标值来判断整个矩阵是否包含目标值 + return any(target in row for row in matrix) + + + +class Solution: + # Check if the target value is present in the given 2D matrix. + + def searchMatrix(self, matrix, target): + # Use any() to check if there exists a row that contains the target. + return any(target in row for row in matrix) diff --git a/solutions/python3/241.py b/solutions/python3/241.py index 653d266..a066928 100644 --- a/solutions/python3/241.py +++ b/solutions/python3/241.py @@ -1,15 +1,28 @@ + class Solution: + # 计算两个数按照指定操作符进行计算的结果 + def calc(self, l, op, r): + # 中文注释: 根据操作符执行加减乘运算并返回结果 + return l + r if op == "+" else l - r if op == "-" else l * r + + # 生成所有可能的计算方式,输入为表达式字符串 def diffWaysToCompute(self, input): + # 中文注释: 如果输入是一个数字直接返回该数字 if input.isdigit(): return [int(input)] + res = [] + # 遍历整个输入字符串 for i in range(len(input)): + # 检查当前字符是否为运算符 if input[i] in "-+*": + # 分别递归计算左右子表达式的所有可能结果 l = self.diffWaysToCompute(input[:i]) r = self.diffWaysToCompute(input[i + 1:]) + + # 将当前运算符应用到所有组合的结果中 for j in l: for k in r: res.append(self.calc(j, input[i], k)) + return res - def calc(self, l, op, r): - return l + r if op == "+" else l - r if op == "-" else l * r \ No newline at end of file diff --git a/solutions/python3/242.py b/solutions/python3/242.py index 485e58d..2db07b4 100644 --- a/solutions/python3/242.py +++ b/solutions/python3/242.py @@ -1,9 +1,12 @@ + class Solution: - def isAnagram(self, s, t): + def isAnagram(self, s: str, t: str) -> bool: """ - :type s: str - :type t: str - :rtype: bool + 判断两个字符串是否互为异位词(即包含相同的字符且每个字符出现的次数相同) + + :param s: 第一个字符串 + :param t: 第二个字符串 + :return: 如果s和t是异位词返回True,否则返回False """ - #return sum([ord(i) for i in s])==sum([ord(j) for j in t]) and set(s)==set(t) - return sorted(s)==sorted(t) \ No newline at end of file + # 直接比较排序后的字符串是否相等,简化了原始代码中计算ASCII码之和与集合比较的操作 + return sorted(s) == sorted(t) diff --git a/solutions/python3/243.py b/solutions/python3/243.py index 802a41b..1c9e7f2 100644 --- a/solutions/python3/243.py +++ b/solutions/python3/243.py @@ -1,13 +1,20 @@ + class Solution: + # 定义一个类来解决最短距离问题 + def shortestDistance(self, words, word1, word2): + # 初始化索引和最小距离变量 i1, i2, mn = -1, -1, float("inf") + + # 遍历单词列表,获取两个指定单词的最近距离 for i, w in enumerate(words): if w == word1: - i1 = i - if i2 >= 0: + i1 = i # 记录word1的索引 + if i2 >= 0: # 如果之前已经记录过word2的索引,则计算当前最短距离 mn = min(mn, i - i2) elif w == word2: - i2 = i - if i1 >= 0: + i2 = i # 记录word2的索引 + if i1 >= 0: # 如果之前已经记录过word1的索引,则计算当前最短距离 mn = min(mn, i - i1) - return mn \ No newline at end of file + + return mn # 返回找到的最短距离 diff --git a/solutions/python3/244.py b/solutions/python3/244.py index a180403..b22cd79 100644 --- a/solutions/python3/244.py +++ b/solutions/python3/244.py @@ -1,12 +1,33 @@ + class WordDistance: def __init__(self, words): + """ + 初始化字典和索引集合,用于存储单词及其位置。 + Initialize the dictionary and index set to store words and their positions. + :param words: 初始词列表 + :type words: List[str] + """ self.d = {} self.ind = collections.defaultdict(set) for i, w in enumerate(words): self.ind[w].add(i) - + def shortest(self, word1, word2): + """ + 计算两个单词之间的最短距离。 + Calculate the shortest distance between two words. + :param word1: 第一个单词 + :type word1: str + :param word2: 第二个单词 + :type word2: str + :return: 最短距离 + :rtype: int + """ if (word1, word2) not in self.d: - self.d[(word1, word2)] = self.d[(word2, word1)] = min(abs(j - i) for i in self.ind[word1] for j in self.ind[word2]) - return self.d[(word1, word2)] \ No newline at end of file + # 计算并存储两个单词之间的最短距离 + # Calculate and store the shortest distance between two words + self.d[(word1, word2)] = self.d[(word2, word1)] = min(abs(j - i) + for i in self.ind[word1] + for j in self.ind[word2]) + return self.d[(word1, word2)] diff --git a/solutions/python3/245.py b/solutions/python3/245.py index 2a1a862..5f82b5b 100644 --- a/solutions/python3/245.py +++ b/solutions/python3/245.py @@ -1,13 +1,28 @@ + class Solution: + # 定义一个类来解决最短距离问题 + def shortestWordDistance(self, words, word1, word2): + # 初始化索引和结果变量 i1 = i2 = -1 res, same = float("inf"), word1 == word2 + + # 遍历每个单词及其对应的索引 for i, w in enumerate(words): if w == word1: - if same: i2 = i1 + # 如果是相同的词,更新第二个词的索引为第一个词的旧索引 + if same: + i2 = i1 + # 更新第一个词的新索引 i1 = i - if i2 >= 0: res = min(res, i1 - i2) + # 如果两个词的索引都有值了,计算距离并更新结果变量 + if i2 >= 0: + res = min(res, abs(i1 - i2)) elif w == word2: + # 更新第二个词的新索引 i2 = i - if i1 >= 0: res = min(res, i2 - i1) - return res \ No newline at end of file + # 如果第一个词有索引了,计算距离并更新结果变量 + if i1 >= 0: + res = min(res, abs(i2 - i1)) + + return res # 返回最短距离 diff --git a/solutions/python3/246.py b/solutions/python3/246.py index d187d98..a8b0ccc 100644 --- a/solutions/python3/246.py +++ b/solutions/python3/246.py @@ -1,3 +1,7 @@ + class Solution: - def isStrobogrammatic(self, num): - return not any(num[i] + num[-1-i] not in ("88", "69", "96", "11", "00") for i in range((len(num) + 1) // 2)) \ No newline at end of file + # 判断一个数字是否是回文旋转变换数(strobogrammatic number) + + def isStrobogrammatic(self, num: str) -> bool: + # 检查每个可能的配对字符是否符合回文旋转变换的要求 + return not any(num[i] + num[-1-i] not in ("88", "69", "96", "11", "00") for i in range((len(num) + 1) // 2)) diff --git a/solutions/python3/247.py b/solutions/python3/247.py index 453c55f..457a775 100644 --- a/solutions/python3/247.py +++ b/solutions/python3/247.py @@ -1,6 +1,18 @@ + class Solution: - def findStrobogrammatic(self, n, q = [""]): - for i in range(n // 2): q = [s + c for s in q for c in "01689" if i != 0 or c != "0"] - if n % 2: q = [s + c for s in q for c in "018"] - for i in range(n // 2 - 1, -1, -1): q = [s + "9" if s[i] == "6" else s + "6" if s[i] == "9" else s + s[i] for s in q] - return q \ No newline at end of file + # 寻找所有n位的回文数(旋转对称数字) + + def findStrobogrammatic(self, n: int, q = [""]): + # 生成长度为1到n-1的所有可能的前半部分 + for i in range(n // 2): + q = [s + c for s in q for c in "01689" if i != 0 or c != "0"] + + # 如果n是奇数,需要在中间添加一个回文字符 + if n % 2: + q = [s + c for s in q for c in "018"] + + # 对生成的前半部分进行镜像拼接以形成完整的回文数 + for i in range(n // 2 - 1, -1, -1): + q = [s + "9" if s[i] == "6" else s + "6" if s[i] == "9" else s + s[i] for s in q] + + return q diff --git a/solutions/python3/248.py b/solutions/python3/248.py index bdcb73f..f555c6e 100644 --- a/solutions/python3/248.py +++ b/solutions/python3/248.py @@ -1,8 +1,16 @@ + class Solution: - def strobogrammaticInRange(self, low, high): + def strobogrammaticInRange(self, low: str, high: str) -> int: + # 初始化队列q和计数器cnt,低位low和高位high的整数值,以及字符串长度ln q, cnt, low, high, ln = ["", "0", "1", "8"], 0, int(low), int(high), len(high) + + # 使用广度优先搜索遍历所有可能的回文数字 while q: s = q.pop() - if s and s[0] != "0" and low <= int(s) <= high: cnt += 1 + if s and s[0] != "0" and low <= int(s) <= high: + cnt += 1 + # 根据规则添加新的候选字符串到队列中 q += [l + s + r for l, r in (("8", "8"), ("6", "9"), ("9", "6"), ("1", "1"), ("0", "0")) if len(s) <= ln - 2] - return cnt if low != 0 else cnt + 1 \ No newline at end of file + + # 返回计数结果,如果low为0则额外加1 + return cnt if low != 0 else cnt + 1 diff --git a/solutions/python3/249.py b/solutions/python3/249.py index 93cafe5..32bd391 100644 --- a/solutions/python3/249.py +++ b/solutions/python3/249.py @@ -1,16 +1,28 @@ + +import collections + class Solution: def groupStrings(self, strings): """ :type strings: List[str] :rtype: List[List[str]] """ + # 使用字典存储相同模式的字符串列表 + # defaultdict自动处理不存在键的情况,避免None检查 table = collections.defaultdict(list) + for w in strings: pattern = "" + # 遍历单词中的每个字符(从第二个开始) for i in range(1, len(w)): + # 计算两个连续字符之间的差值,并转换为模式字符串 if ord(w[i]) - ord(w[i - 1]) >= 0: pattern += str(ord(w[i]) - ord(w[i - 1])) else: pattern += str(ord(w[i]) - ord(w[i - 1]) + 26) + + # 根据计算出的模式字符串将当前单词添加到字典中对应的列表 table[pattern].append(w) - return [table[pattern] for pattern in table] \ No newline at end of file + + # 返回所有具有相同模式字符串的列表 + return [table[pattern] for pattern in table] diff --git a/solutions/python3/25.py b/solutions/python3/25.py index 79c76c5..024c3f3 100644 --- a/solutions/python3/25.py +++ b/solutions/python3/25.py @@ -1,21 +1,33 @@ + # Definition for singly-linked list. -# class ListNode: -# def __init__(self, x): -# self.val = x -# self.next = None +class ListNode: + def __init__(self, x): + self.val = x + self.next = None + class Solution: - def reverseKGroup(self, head, k): - dummy = last = ListNode(0) - cur = head + # 反转k个节点的链表 + def reverseKGroup(self, head: ListNode, k: int) -> ListNode: + dummy = last = ListNode(0) # 创建虚拟头结点和last指针 + cur = head # 当前处理的起始节点 + while cur: - first, cnt = cur, 1 + first, cnt = cur, 1 # 记录当前起始节点,计数器置为1 + + # 检查剩余是否达到k个节点 while cnt < k and cur: cur, cnt = cur.next, cnt + 1 - if cnt == k and cur: - cur, prev = first, None - for _ in range(k): - prev, cur.next, cur = cur, prev, cur.next - last.next, last = prev, first + + if cnt == k and cur: # 如果正好有k个节点 + cur, prev = first, None # 当前头结点,初始化prev为None + + for _ in range(k): # 反转k个节点 + next_node = cur.next # 保存当前节点的下一个节点 + cur.next, prev, cur = prev, cur, next_node + + last.next, last = prev, first # 更新last和链表结构 + else: - last.next = first - return dummy.next \ No newline at end of file + last.next = first # 不足k个节点,直接连接 + + return dummy.next # 返回新的头结点 diff --git a/solutions/python3/250.py b/solutions/python3/250.py index df96f20..a2ea41a 100644 --- a/solutions/python3/250.py +++ b/solutions/python3/250.py @@ -1,21 +1,29 @@ + # Definition for a binary tree node. -# class TreeNode(object): -# def __init__(self, x): -# self.val = x -# self.left = None -# self.right = None +class TreeNode(object): + def __init__(self, x): + self.val = x + self.left = None + self.right = None class Solution(object): + # 计算单值子树的数量 def countUnivalSubtrees(self, root): - res = [0] + res = [0] # 存储结果 + + # 深度优先搜索,判断节点是否为单值子树 def dfs(node, value): - if not node: + if not node: # 空节点返回True和默认的值 return True, value - left, lVal = dfs(node.left, node.val) - right, rVal = dfs(node.right, node.val) - cnt = left and right and lVal == rVal == node.val + + left, lVal = dfs(node.left, node.val) # 处理左子树 + right, rVal = dfs(node.right, node.val) # 处理右子树 + + cnt = left and right and lVal == rVal == node.val # 判断当前节点及其子树是否为单值子树 if cnt: - res[0] += 1 - return cnt, node.val - dfs(root, None) - return res[0] \ No newline at end of file + res[0] += 1 # 更新结果计数器 + + return cnt, node.val # 返回判断结果和当前节点的值 + + dfs(root, None) # 从根节点开始深度优先搜索 + return res[0] # 返回最终的结果 diff --git a/solutions/python3/251.py b/solutions/python3/251.py index 41ec488..38a0e53 100644 --- a/solutions/python3/251.py +++ b/solutions/python3/251.py @@ -1,18 +1,22 @@ + class Vector2D: + # 构造函数,初始化二维向量的数组和指针位置 def __init__(self, v: List[List[int]]): - self.arr = v - self.rows = len(v) - self.i = self.j = 0 + self.arr = v # 存储输入的二维数组 + self.rows = len(v) # 获取行数 + self.i = self.j = 0 # 初始化索引i和j def next(self) -> int: + # 返回下一个元素并移动指针 if self.hasNext(): - self.j += 1 - return self.arr[self.i][self.j - 1] + self.j += 1 # 移动列指针 + return self.arr[self.i][self.j - 1] # 返回当前元素 def hasNext(self) -> bool: - if self.arr and self.j == len(self.arr[self.i]): + # 判断是否有下一个元素 + if self.arr and self.j == len(self.arr[self.i]): # 当前行已遍历完,移动到下一行 self.i += 1 self.j = 0 - while self.i + 1 < self.rows and not self.arr[self.i]: + while self.i + 1 < self.rows and not self.arr[self.i]: # 跳过空行 self.i += 1 - return self.i < self.rows and self.arr[self.i] != [] + return self.i < self.rows and self.arr[self.i] != [] # 判断是否还有元素可遍历 diff --git a/solutions/python3/252.py b/solutions/python3/252.py index 0128ccd..141f9e5 100644 --- a/solutions/python3/252.py +++ b/solutions/python3/252.py @@ -1,12 +1,29 @@ + # Definition for an interval. -# class Interval: -# def __init__(self, s=0, e=0): -# self.start = s -# self.end = e +class Interval: + # 初始化区间对象,包含开始和结束时间 + def __init__(self, s=0, e=0): + self.start = s + self.end = e class Solution: + """ + 检查会议是否可以参加。 + + 参数: + intervals : List[Interval] - 一个表示区间的列表 + + 返回值: + bool - 如果所有区间不重叠,则返回 True,否则返回 False + """ def canAttendMeetings(self, intervals): - intervals.sort(key = lambda x: x.end) + # 根据区间的结束时间进行排序 + intervals.sort(key=lambda x: x.end) + + # 检查相邻两个区间的开始时间和前一个区间的结束时间是否冲突 for i in range(1, len(intervals)): - if intervals[i].start < intervals[i - 1].end: return False - return True \ No newline at end of file + if intervals[i].start < intervals[i - 1].end: + return False + + # 如果循环未返回 False,则所有区间不重叠 + return True diff --git a/solutions/python3/253.py b/solutions/python3/253.py index 6c9b07b..0b43888 100644 --- a/solutions/python3/253.py +++ b/solutions/python3/253.py @@ -1,3 +1,4 @@ + # Definition for an interval. # class Interval: # def __init__(self, s=0, e=0): @@ -5,13 +6,26 @@ # self.end = e class Solution: + # minMeetingRooms - 返回需要的最小会议室数量 + # @param intervals: List[Interval], 会议区间列表 + # @return: int, 最小会议室数量 def minMeetingRooms(self, intervals): - intervals.sort(key = lambda x: x.start) + # 按照会议开始时间排序 + intervals.sort(key=lambda x: x.start) + + # 使用最小堆记录当前使用中的会议结束时间 heap, time, rooms = [], 0, 0 + for intr in intervals: + # 弹出所有已经结束的会议,减少正在使用的会议室数量 while heap and heap[0] <= intr.start: heapq.heappop(heap) + + # 将当前会议结束时间入堆,并增加使用中的会议室数量 heapq.heappush(heap, intr.end) + if len(heap) > rooms: rooms += 1 - return rooms \ No newline at end of file + + return rooms + diff --git a/solutions/python3/254.py b/solutions/python3/254.py index c504e9c..8d8b512 100644 --- a/solutions/python3/254.py +++ b/solutions/python3/254.py @@ -1,18 +1,22 @@ + class Solution: - def getFactors(self, n): - factors = set() + # 定义一个用于获取因子列表的方法,输入为整数n + def getFactors(self, n: int) -> List[List[int]]: + factors = set() # 保存所有小于sqrt(n)的因子 + # 遍历从2到根号n之间的所有整数i,寻找能整除n的因子 for i in range(2, int(n ** 0.5) + 1): if n % i == 0: - factors |= {i, n // i} - q, res = [[f, [f]] for f in factors], [] - while q: - new = [] - for sm, arr in q: + factors |= {i, n // i} # 将因子及其对应的商加入集合 + + q, res = [[f, [f]] for f in factors], [] # 初始化队列q和结果列表res + while q: # 当队列不为空时循环执行以下操作 + new = [] # 用于保存新生成的子集 + for sm, arr in q: # 遍历当前队列中的每个元素(sm, arr) for f in factors: - if f >= arr[-1]: + if f >= arr[-1]: # 确保新因子f不小于当前子集的最后一个数 if sm * f < n: - new.append([sm * f, arr + [f]]) - elif sm * f == n: - res.append(arr + [f]) - q = new - return res \ No newline at end of file + new.append([sm * f, arr + [f]]) # 增加新的子集到队列中 + elif sm * f == n: # 如果新因子使当前子集乘积等于n + res.append(arr + [f]) # 将其加入结果列表res + + return res # 返回所有满足条件的因子组合列表 diff --git a/solutions/python3/255.py b/solutions/python3/255.py index bf02d1c..db24af5 100644 --- a/solutions/python3/255.py +++ b/solutions/python3/255.py @@ -1,8 +1,21 @@ + class Solution: + # 检查给定的前序遍历列表是否有效 def verifyPreorder(self, preorder): + # 使用栈辅助,lower表示上一个元素的值 stack, lower = [], -float("inf") + for x in preorder: - if x < lower: return False - while stack and x > stack[-1]: lower = stack.pop() + # 如果当前值小于lower,则无效 + if x < lower: + return False + + # 当栈不为空且当前值大于栈顶元素时,更新lower并弹出栈顶元素 + while stack and x > stack[-1]: + lower = stack.pop() + + # 将当前值压入栈中 stack.append(x) - return True \ No newline at end of file + + # 如果遍历完整个列表都没有返回False,则前序遍历有效 + return True diff --git a/solutions/python3/256.py b/solutions/python3/256.py index 0bf8bce..1636eda 100644 --- a/solutions/python3/256.py +++ b/solutions/python3/256.py @@ -1,9 +1,20 @@ + class Solution: + # 定义一个类来解决问题,使用动态规划解决最小成本路径问题 + def minCost(self, costs: List[List[int]]) -> int: + # 初始化一个长度为3的dp数组,用于记录每种颜色的成本 dp = [0] * 3 + + # 遍历每一栋房子的颜色成本 for a, b, c in costs: + # 计算重新涂成绿色、蓝色和红色时所需的最小成本 c1 = min(dp[1], dp[2]) + a c2 = min(dp[0], dp[2]) + b c3 = min(dp[0], dp[1]) + c + + # 更新dp数组,存储最新的成本值 dp = [c1, c2, c3] - return min(dp) \ No newline at end of file + + # 返回最终的最小成本 + return min(dp) diff --git a/solutions/python3/257.py b/solutions/python3/257.py index de9a0c8..185d660 100644 --- a/solutions/python3/257.py +++ b/solutions/python3/257.py @@ -1,21 +1,30 @@ + # Definition for a binary tree node. -# class TreeNode: -# def __init__(self, x): -# self.val = x -# self.left = None -# self.right = None +class TreeNode: + def __init__(self, x): + self.val = x + self.left = None + self.right = None class Solution: + # 找到二叉树的所有路径 def binaryTreePaths(self, root: TreeNode) -> List[str]: + # 深度优先搜索辅助函数 def dfs(node, arr): if not node.right and not node.left: - #print(arr) + # 如果当前节点没有左右子节点,则记录一条完整路径 self.res += ['->'.join(str(num) for num in arr)] if node.left: + # 递归处理左子树 dfs(node.left, arr + [node.left.val]) if node.right: + # 递归处理右子树 dfs(node.right, arr + [node.right.val]) + self.res = [] + # 如果根节点为空,直接返回空列表 if not root: return [] + # 开始深度优先搜索 dfs(root, [root.val]) - return self.res \ No newline at end of file + # 返回所有路径的结果 + return self.res diff --git a/solutions/python3/258.py b/solutions/python3/258.py index 0a3e001..72b6f7e 100644 --- a/solutions/python3/258.py +++ b/solutions/python3/258.py @@ -1,10 +1,11 @@ + class Solution: def addDigits(self, num): """ - :type num: int - :rtype: int + :type num: int # 输入的数字 + :rtype: int # 返回的结果,即所有位数之和连续求和直至结果为一位数 """ - num=str(num) - while len(num)>1: - num=str(sum([int(i) for i in num])) - return int(num) \ No newline at end of file + num = str(num) + while len(num) > 1: + num = str(sum([int(i) for i in num])) # 将字符串转换为整数列表并求和后再次转换为字符串 + return int(num) # 返回最终的结果 diff --git a/solutions/python3/259.py b/solutions/python3/259.py index 6be568b..918f95d 100644 --- a/solutions/python3/259.py +++ b/solutions/python3/259.py @@ -1,12 +1,27 @@ + class Solution: + # 定义一个类用于解决三个数之和小于目标值的问题 + def threeSumSmaller(self, nums, target): + """ + 计算数组中三个元素之和小于给定目标值的三元组个数 + + :param nums: List[int] - 一个整数列表 + :param target: int - 目标和 + :return: int - 满足条件的三元组数量 + """ + # 首先对数组进行排序,方便后续双指针操作 nums.sort() + res = 0 + # 遍历每个可能的第一个元素 for i in range(len(nums) - 2): r = len(nums) - 1 + # 确定第二个和第三个元素的位置,并使用双指针优化搜索过程 for j in range(i + 1, len(nums) - 1): while r > j + 1 and nums[i] + nums[j] + nums[r] >= target: r -= 1 + # 当找到满足条件的组合时,计数并调整指针位置 if nums[i] + nums[j] + nums[r] < target: res += r - j - return res \ No newline at end of file + return res diff --git a/solutions/python3/26.py b/solutions/python3/26.py index f4b7dfc..3cbb752 100644 --- a/solutions/python3/26.py +++ b/solutions/python3/26.py @@ -1,4 +1,19 @@ + class Solution: + # 定义一个移除数组中重复元素的方法,返回去重后数组的新长度 def removeDuplicates(self, nums): n = len(nums) - return n - len([nums.pop(i) for i in range(n -1, 0, -1) if nums[i] == nums[i - 1]]) \ No newline at end of file + # 遍历数组,从倒数第二个元素开始向前检查相邻两个元素是否相等 + # 如果相等,则删除该元素,并调整后续元素的位置 + [nums.pop(i) for i in range(n - 1, 0, -1) if nums[i] == nums[i - 1]] + return n - len(nums) + + + +class Solution: + # 定义一个移除数组中重复元素的方法,返回去重后数组的新长度 + def removeDuplicates(self, nums): + n = len(nums) + # 使用列表推导式逆向遍历并删除相邻相等的元素 + [nums.pop(i) for i in range(n - 1, 0, -1) if nums[i] == nums[i - 1]] + return n - len(nums) diff --git a/solutions/python3/260.py b/solutions/python3/260.py index a4e2f13..f1d67e3 100644 --- a/solutions/python3/260.py +++ b/solutions/python3/260.py @@ -1,7 +1,26 @@ + class Solution: + # 用于找出数组中出现一次的两个数字 + def singleNumber(self, nums): """ - :type nums: List[int] - :rtype: List[int] + :param nums: List[int] - 输入整数列表 + :return: List[int] - 返回出现一次的两个整数 + + 示例: + >>> s = Solution() + >>> s.singleNumber([1, 2, 1, 3, 2, 5]) + [3, 5] + + 思路: + 使用collections.Counter来统计每个数字出现的次数,然后获取出现一次的两个数字 """ - return [n[0] for n in collections.Counter(nums).most_common()[-2:]] \ No newline at end of file + from collections import Counter + + # 统计每个元素出现的频率 + num_counts = Counter(nums) + + # 获取出现一次的两个数字 + result = [num for num, count in num_counts.items() if count == 1] + + return result diff --git a/solutions/python3/261.py b/solutions/python3/261.py index af3e2bc..562b0ef 100644 --- a/solutions/python3/261.py +++ b/solutions/python3/261.py @@ -1,13 +1,55 @@ + class Solution: - def validTree(self, n, edges): + # 判断给定的边集是否构成一棵有效的树 + + def validTree(self, n: int, edges: list[list[int]]) -> bool: visited, adj = [0] * n, collections.defaultdict(set) + + # 构建邻接表表示图 for a, b in edges: adj[a].add(b) adj[b].add(a) - def dfs(i, pre): + + def dfs(i: int, pre: int) -> bool: + """ + 深度优先搜索检查节点 i 是否能访问且不形成环 + + :param i: 当前节点索引 + :param pre: 上一个访问的节点索引,用于跳过回边 + :return: 如果当前子树无环且所有节点均被访问,则返回 True;否则返回 False + """ visited[i] = 1 for v in adj[i]: if v != pre and (visited[v] or not dfs(v, i)): return False return True - return dfs(0, -1) and sum(visited) == n \ No newline at end of file + + # 检查从根节点开始的搜索是否无环且所有节点被访问 + valid_dfs = dfs(0, -1) + + # 验证所有节点均被访问 + all_visited = sum(visited) == n + + return valid_dfs and all_visited + + + +class Solution: + def validTree(self, n: int, edges: list[list[int]]) -> bool: + visited, adj = [0] * n, collections.defaultdict(set) + + for a, b in edges: + adj[a].add(b) + adj[b].add(a) + + def dfs(i: int, pre: int) -> bool: + visited[i] = 1 + for v in adj[i]: + if v != pre and (visited[v] or not dfs(v, i)): + return False + return True + + valid_dfs = dfs(0, -1) + all_visited = sum(visited) == n + + return valid_dfs and all_visited diff --git a/solutions/python3/263.py b/solutions/python3/263.py index 8e8ba2e..66f8887 100644 --- a/solutions/python3/263.py +++ b/solutions/python3/263.py @@ -1,10 +1,19 @@ -class Solution: - def isUgly(self, num): - """ - :type num: int - :rtype: bool - """ - while num>1: - if num%2!=0 and num%3!=0 and num%5!=0: return False - else: num/=[i for i in (2,3,5) if num%i==0][-1] - return num==1 \ No newline at end of file + + class Solution: + def isUgly(self, num): + """ + :type num: int + :rtype: bool + + 判断一个数是否只有质因数2、3或5,如果是返回True,否则返回False。 + 英文:Determine if a number has only prime factors 2, 3, or 5. Return True if so, otherwise False. + """ + while num > 1: + # 如果num不能被2、3或5整除,则不是丑数 + if all(num % i != 0 for i in [2, 3, 5]): + return False + # 否则,去除一个最小的质因数(2, 3, 或者5) + else: + num /= min([i for i in [2, 3, 5] if num % i == 0]) + return num == 1 + \ No newline at end of file diff --git a/solutions/python3/264.py b/solutions/python3/264.py index 3de7119..53adc54 100644 --- a/solutions/python3/264.py +++ b/solutions/python3/264.py @@ -1,11 +1,21 @@ + class Solution: - def nthUglyNumber(self, n): + # Python 类定义 + + def nthUglyNumber(self, n: int) -> int: + # 初始化数组、堆和已使用过的数字集合 arr, heap, used = [], [1], set() + for i in range(n): + # 从堆中弹出最小的丑数 num = heapq.heappop(heap) arr.append(num) + + # 对于每个可能的因数(2、3、5),生成新的候选丑数并加入堆和已使用集合 for p in (2, 3, 5): if p * num not in used: heapq.heappush(heap, p * num) used.add(p * num) - return arr[-1] \ No newline at end of file + + # 返回第 n 个丑数 + return arr[-1] diff --git a/solutions/python3/265.py b/solutions/python3/265.py index 62dbae8..8ffbd3b 100644 --- a/solutions/python3/265.py +++ b/solutions/python3/265.py @@ -1,5 +1,15 @@ + class Solution: + # 定义一个名为Solution的类,用于解决给定的最小成本问题 + def minCostII(self, costs): + # 计算每一轮中从上一层到当前层的成本最低路径 + for i in range(1, len(costs)): - for j in range(len(costs[0])): costs[i][j] += min(costs[i - 1][:j] + costs[i - 1][j + 1:]) - return costs and min(costs[-1]) or 0 \ No newline at end of file + for j in range(len(costs[0])): + # 对于每一行,更新当前房屋的最小成本 + # 通过加上前一行除自身外其他颜色的最小值来更新当前颜色的成本 + costs[i][j] += min(costs[i - 1][:j] + costs[i - 1][j + 1:]) + + # 返回最后一层的所有成本中的最小值,如果costs为空,则返回0 + return costs and min(costs[-1]) or 0 diff --git a/solutions/python3/266.py b/solutions/python3/266.py index 8c4620f..8075ac9 100644 --- a/solutions/python3/266.py +++ b/solutions/python3/266.py @@ -1,4 +1,10 @@ + class Solution: - def canPermutePalindrome(self, s): + # 判断给定字符串s是否可以通过重新排列形成回文串 + def canPermutePalindrome(self, s: str) -> bool: + # 使用collections.Counter统计每个字符出现的次数 cnt = collections.Counter(s) - return len([c for c in cnt if cnt[c] % 2]) <= 1 \ No newline at end of file + + # 检查有多少个字符的计数是奇数,返回这个数量小于等于1 + # 中文注释:检查有多少个字符出现了奇数次,如果不超过一个,则可以通过重新排列形成回文串 + return len([c for c in cnt if cnt[c] % 2]) <= 1 diff --git a/solutions/python3/267.py b/solutions/python3/267.py index e9451ca..16c7a59 100644 --- a/solutions/python3/267.py +++ b/solutions/python3/267.py @@ -1,13 +1,37 @@ + +from collections import Counter + class Solution: - def generatePalindromes(self, s): - cnt, n = collections.Counter(s), len(s) // 2 - odd, s, q = [c for c in cnt if cnt[c] % 2], "".join(k * (cnt[k] // 2) for k in cnt), {"#" * n} - if len(odd) > 1: return [] + def generatePalindromes(self, s: str) -> list[str]: + # 统计字符串s中每个字符出现的次数,使用Counter进行统计 + cnt = Counter(s) + + # 计算字符串长度的一半 + n = len(s) // 2 + + # 找出所有出现奇数次的字符 + odd = [c for c in cnt if cnt[c] % 2] + + # 构建初始中间部分,使用'#'填充 + s = "".join(k * (cnt[k] // 2) for k in cnt) + q = {"#" * n} + + # 如果出现奇数次的字符超过一个,则无法构成回文串 + if len(odd) > 1: + return [] + + # 遍历当前已有的字符串组合 for c in s: new = set() + + # 对于每个已有字符串,插入新的字符c生成新字符串 for w in q: for i in range(n): if w[i] == "#": new.add(w[:i] + c + w[i + 1:]) + + # 更新当前的已有的字符串组合 q = new - return [w + odd[0] + w[::-1] for w in q] if odd else [w + w[::-1] for w in q] \ No newline at end of file + + # 根据出现奇数次的字符生成最终回文串 + return [w + odd[0] + w[::-1]] if odd else [w + w[::-1] for w in q] diff --git a/solutions/python3/268.py b/solutions/python3/268.py index fc5ab13..bec06c3 100644 --- a/solutions/python3/268.py +++ b/solutions/python3/268.py @@ -1,7 +1,22 @@ + class Solution: + # 类名:Solution + def missingNumber(self, nums): """ - :type nums: List[int] - :rtype: int + :param nums: 数组,包含从0到n-1的整数,但缺少一个数字 + :return: 缺失的那个数字 + + 解题思路: + 1. 利用等差数列求和公式计算0到n-1的总和。 + 2. 计算给定数组nums中所有元素之和。 + 3. 两者的差值即为缺失的数字。 """ - return len(nums)*(len(nums)+1)//2-sum(nums) \ No newline at end of file + # 计算0到len(nums)的等差数列总和 + total_sum = len(nums) * (len(nums) + 1) // 2 + + # 计算数组nums中所有元素之和 + actual_sum = sum(nums) + + # 返回缺失的数字 + return total_sum - actual_sum diff --git a/solutions/python3/269.py b/solutions/python3/269.py index 0c269ad..7df3c43 100644 --- a/solutions/python3/269.py +++ b/solutions/python3/269.py @@ -1,20 +1,46 @@ + class Solution(object): + # 定义求解外星文排序的方法 def alienOrder(self, words): - if len(words) == 1: return words[0] + """ + :type words: List[str] + :rtype: str + """ + if len(words) == 1: + return words[0] + + # 辅助函数进行深度优先搜索 def dfs(i): + """ + :param i: 当前节点索引 + :return: True 表示没有环,False 表示有环 + """ visited[i] = 0 for v in graph[i]: - if visited[v] == 0 or (visited[v] == -1 and not dfs(v)): return False + if visited[v] == 0 or (visited[v] == -1 and not dfs(v)): + return False order.append(chr(97 + i)) visited[i] = 1 return True + + # 初始化图和访问数组,以及结果列表 graph, visited, order = collections.defaultdict(set), [1] * 26, [] + + # 构建图结构 for w1, w2 in zip(words, words[1:]): for c1, c2 in zip(w1, w2): if c1 != c2: graph[ord(c1) - ord("a")].add(ord(c2) - ord("a")) break - for c in w1 + w2: visited[ord(c) - ord("a")] = -1 + + # 将所有字符标记为未访问 + for c in (w1 + w2 for w1, w2 in zip(words, words[1:])): + visited[ord(c) - ord("a")] = -1 + + # 深度优先搜索构建拓扑排序 for i in range(26): - if visited[i] == -1 and not dfs(i): return "" - return "".join(order)[::-1] \ No newline at end of file + if visited[i] == -1 and not dfs(i): + return "" + + # 返回结果,注意反转顺序 + return "".join(order)[::-1] diff --git a/solutions/python3/27.py b/solutions/python3/27.py index fcc1af8..6ca0b23 100644 --- a/solutions/python3/27.py +++ b/solutions/python3/27.py @@ -1,8 +1,10 @@ + class Solution: + # 定义移除元素的方法,返回新数组的长度和修改后的数组内容 def removeElement(self, nums: List[int], val: int) -> int: - i = 0 - for num in nums: - if num != val: - nums[i] = num - i += 1 - return i \ No newline at end of file + i = 0 # 初始化索引指针 + for num in nums: # 遍历列表中的每个元素 + if num != val: # 如果当前元素不等于指定值val + nums[i] = num # 将该元素放到新数组对应位置 + i += 1 # 索引指针右移一位 + return i # 返回新数组的实际长度 diff --git a/solutions/python3/270.py b/solutions/python3/270.py index e2c0aaf..d96b3f7 100644 --- a/solutions/python3/270.py +++ b/solutions/python3/270.py @@ -1,27 +1,29 @@ + # Definition for a binary tree node. -# class TreeNode: -# def __init__(self, x): -# self.val = x -# self.left = None -# self.right = None +class TreeNode: + def __init__(self, x): + self.val = x + self.left = None + self.right = None class Solution: + # 寻找二叉树中最接近目标值的节点值 + # :type root: TreeNode 二叉树根节点 + # :type target: float 目标浮点数 + # :rtype: int 返回最接近目标值的整数值 def closestValue(self, root, target): - """ - :type root: TreeNode - :type target: float - :rtype: int - """ - res, d = [0], [float("inf")] + res, d = [0], [float("inf")] # 初始化结果和最小差值 + def dfs(node): if node: - new = node.val - target if node.val >= target else target - node.val + new = abs(target - node.val) # 计算当前节点与目标值的绝对差值 if new < d[0]: - d[0] = new - res[0] = node.val - if target < node.val: + d[0] = new # 更新最小差值 + res[0] = node.val # 更新结果 + if target < node.val: # 如果目标值小于当前节点值,搜索左子树 dfs(node.left) else: - dfs(node.right) - dfs(root) - return res[0] \ No newline at end of file + dfs(node.right) # 否则搜索右子树 + + dfs(root) # 开始深度优先遍历 + return res[0] # 返回最接近的节点值 diff --git a/solutions/python3/272.py b/solutions/python3/272.py index 2bddc29..e24aaca 100644 --- a/solutions/python3/272.py +++ b/solutions/python3/272.py @@ -1,17 +1,25 @@ + # Definition for a binary tree node. -# class TreeNode: -# def __init__(self, x): -# self.val = x -# self.left = None -# self.right = None +class TreeNode: + def __init__(self, x): + self.val = x + self.left = None + self.right = None class Solution: - def closestKValues(self, root, target, k): + # 寻找二叉树中与目标值最接近的k个节点 + def closestKValues(self, root: TreeNode, target: float, k: int) -> List[float]: d = [] + + # 深度优先搜索遍历二叉树,并维护一个最小堆,记录每个节点与其目标值的差值和节点值 def dfs(node): if node: heapq.heappush(d, (abs(node.val - target), node.val)) dfs(node.left) dfs(node.right) + + # 开始遍历二叉树 dfs(root) - return [node for val, node in heapq.nsmallest(k, d)] \ No newline at end of file + + # 从最小堆中取出k个最接近目标值的节点值 + return [node for val, node in heapq.nsmallest(k, d)] diff --git a/solutions/python3/273.py b/solutions/python3/273.py index 4c3537c..fe55a4b 100644 --- a/solutions/python3/273.py +++ b/solutions/python3/273.py @@ -1,25 +1,41 @@ + class Solution: def __init__(self): - self.lessThan20 = ["","One","Two","Three","Four","Five","Six","Seven","Eight","Nine","Ten","Eleven","Twelve","Thirteen","Fourteen","Fifteen","Sixteen","Seventeen","Eighteen","Nineteen"] - self.tens = ["","Ten","Twenty","Thirty","Forty","Fifty","Sixty","Seventy","Eighty","Ninety"] - self.thousands = ["","Thousand","Million","Billion"] + # 初始化小于20、十位数和千位数的单词列表 + self.lessThan20 = ["", "One", "Two", "Three", "Four", "Five", "Six", "Seven", "Eight", "Nine", + "Ten", "Eleven", "Twelve", "Thirteen", "Fourteen", "Fifteen", "Sixteen", + "Seventeen", "Eighteen", "Nineteen"] + self.tens = ["", "Ten", "Twenty", "Thirty", "Forty", "Fifty", "Sixty", "Seventy", "Eighty", "Ninety"] + self.thousands = ["", "Thousand", "Million", "Billion"] def numberToWords(self, num): + # 如果输入数字为0,直接返回"Zero" if not num: return "Zero" + res = "" - for thousand in self.thousands: + + # 遍历千位数数组 + for i in range(len(self.thousands)): if num % 1000: - res = self.helper(num%1000) + thousand + " " + res + # 处理当前千位数部分的数字并添加对应单位词,然后加到结果字符串前部 + res = self.helper(num % 1000) + self.thousands[i] + " " + res num //= 1000 + return res.strip() def helper(self, num): + # 如果输入数字为0,直接返回空字符串 if not num: return "" + + # 小于20的数字转换 elif num < 20: return self.lessThan20[num] + " " + + # 处理10到99之间的数 elif num < 100: - return self.tens[num//10] + " " + self.helper(num%10) - else: - return self.lessThan20[num//100] + " Hundred " + self.helper(num%100) \ No newline at end of file + return self.tens[num // 10] + " " + self.helper(num % 10) + + else: # 大于等于100 + return self.lessThan20[num // 100] + " Hundred " + self.helper(num % 100) diff --git a/solutions/python3/274.py b/solutions/python3/274.py index 9278ce2..4ba01fd 100644 --- a/solutions/python3/274.py +++ b/solutions/python3/274.py @@ -1,6 +1,16 @@ + class Solution: + # 定义一个类来解决h指数问题 + def hIndex(self, citations): + # 排序引用数组,以便后续处理 citations.sort() + + # 遍历排序后的引用数组 for i in range(len(citations)): - if len(citations) - i <= citations[i]: return len(citations) - i - return 0 \ No newline at end of file + if len(citations) - i <= citations[i]: + # 如果当前索引对应的引用数大于等于剩余的论文数量,则返回h指数 + return len(citations) - i + + # 若未找到满足条件的情况,返回0 + return 0 diff --git a/solutions/python3/275.py b/solutions/python3/275.py index 83fa9bf..34b5fb9 100644 --- a/solutions/python3/275.py +++ b/solutions/python3/275.py @@ -1,8 +1,20 @@ + class Solution: def hIndex(self, citations): + """ + :param citations: list[int] - 引用次数列表,每个元素代表一篇论文的引用次数 + :return: int - 返回h指数,即满足条件的最大整数k:有至少k篇论文,每篇论文的引用次数至少为k次 + + 优化说明: + - 使用二分查找法来提高效率。 + - 中文注释和英文注释双语提供以方便理解。 + """ l, r, res = 0, len(citations) - 1, 0 while l <= r: mid = (l + r) // 2 - if len(citations) - mid <= citations[mid]: res, r = len(citations) - mid, r - 1 - else: l = mid + 1 - return res \ No newline at end of file + # 检查当前mid位置是否满足h指数条件 + if len(citations) - mid <= citations[mid]: + res, r = len(citations) - mid, r - 1 + else: + l = mid + 1 + return res diff --git a/solutions/python3/276.py b/solutions/python3/276.py index 544d2de..87f1052 100644 --- a/solutions/python3/276.py +++ b/solutions/python3/276.py @@ -1,5 +1,19 @@ + class Solution: - def numWays(self, n, k): + def numWays(self, n: int, k: int) -> int: + """ + 计算n个连续栅栏涂色的方法数,每种颜色可以重复使用。 + + :param n: 栅栏的数量 (int) + :param k: 可用的颜色种类 (int) + :return: 涂色方法总数 (int) + """ + # 初始状态:第一段栅栏的相同和不同涂色方式 same, dif = 0, k - for _ in range(1, n): same, dif = dif, (same + dif) * (k - 1) - return n and same + dif or 0 \ No newline at end of file + + # 动态规划计算后续栅栏的涂色方式 + for _ in range(1, n): + same, dif = dif, (same + dif) * (k - 1) + + # 返回总数,考虑n为0的情况 + return same + dif if n else 0 diff --git a/solutions/python3/278.py b/solutions/python3/278.py index 303730c..aa06af7 100644 --- a/solutions/python3/278.py +++ b/solutions/python3/278.py @@ -1,19 +1,26 @@ + # The isBadVersion API is already defined for you. # @param version, an integer # @return a bool # def isBadVersion(version): class Solution: + """ + :type n: int # 输入整数n,表示要检查的版本号范围的最大值 + :rtype: int # 返回第一个坏版本的版本号 + """ def firstBadVersion(self, n): """ - :type n: int - :rtype: int + 二分查找法寻找第一个出现错误的版本号 + + :param n: 要检查的版本号范围的最大值 + :return: 第一个坏版本的版本号 """ - l, r = 0, n + l, r = 0, n # 初始化左右指针 while l <= r: - mid = (l + r) // 2 - if isBadVersion(mid): - r = mid - 1 - else: - l = mid + 1 - return r + 1 \ No newline at end of file + mid = (l + r) // 2 # 计算中间位置 + if isBadVersion(mid): # 如果当前mid是坏版本 + r = mid - 1 # 将右边界调整到mid左边,继续在左半部分查找 + else: # 否则,当前mid不是坏版本 + l = mid + 1 # 将左边界调整到mid右边,继续在右半部分查找 + return r + 1 # 最后返回的r是最后一个未出现错误的版本号,所以返回r+1即为第一个坏版本号 diff --git a/solutions/python3/279.py b/solutions/python3/279.py index f2645b6..b0f1e34 100644 --- a/solutions/python3/279.py +++ b/solutions/python3/279.py @@ -1,8 +1,20 @@ + class Solution: + # 定义一个类来解决数的平方表示问题 + def numSquares(self, n): + # 初始化候选集合q为所有小于等于n的平方数,并初始化步数move为1 q, move = {i ** 2 for i in range(1, int(n ** 0.5) + 1)}, 1 + + # 定义硬币集coins,即候选集合q的副本 coins = set(q) + + # 当候选集合q非空时循环 while q: - if n in q: return move + # 如果目标值n在候选集合q中,则返回当前步数move + if n in q: + return move + + # 更新候选集合q为新的候选集,并增加一步 q = {sm + c for sm in q for c in coins} - q - move += 1 \ No newline at end of file + move += 1 diff --git a/solutions/python3/28.py b/solutions/python3/28.py index 3c906ff..d36420d 100644 --- a/solutions/python3/28.py +++ b/solutions/python3/28.py @@ -1,3 +1,11 @@ + class Solution: - def strStr(self, haystack, needle): - return haystack.find(needle) \ No newline at end of file + # 中文注释:定义一个类Solution,用于实现字符串查找功能 + # 英文注释: Define a class Solution to implement string searching functionality + + def strStr(self, haystack: str, needle: str) -> int: + # 中文注释:重载strStr方法,接受两个参数haystack和needle分别代表主字符串和子字符串 + # 英文注释: Override the strStr method which accepts two parameters: haystack and needle representing the main string and substring respectively + + return haystack.find(needle) # 中文注释:使用内置find方法查找needle在haystack中的起始索引,返回结果 + # 英文注释: Use the built-in find method to search for the starting index of needle in haystack, and return the result diff --git a/solutions/python3/280.py b/solutions/python3/280.py index fa3046d..6e78016 100644 --- a/solutions/python3/280.py +++ b/solutions/python3/280.py @@ -1,14 +1,25 @@ + class Solution: - def wiggleSort(self, nums): + def wiggleSort(self, nums: list) -> None: + """ + Do not return anything, modify nums in-place instead. + """ n = len(nums) - for i in range(0, n -1, 2): - if i == n - 2: + + # 遍历数组,按照奇偶位置进行调整 + for i in range(0, n - 1, 2): + if i == n - 2: # 如果是最后一个元素前的一个元素 + # 检查最后两个元素的顺序是否符合要求 if nums[-1] < nums[-2]: nums[-2], nums[-1] = nums[-1], nums[-2] else: - if nums[i + 2] >= nums[i + 1] < nums[i]: - nums[i], nums[i + 1] = nums[i + 1], nums[i] - elif nums[i] > nums[i + 2] <= nums[i + 1]: - nums[i], nums[i + 2] = nums[i + 2], nums[i] - if nums[i + 2] > nums[i + 1]: - nums[i + 1], nums[i + 2] = nums[i + 2], nums[i + 1] \ No newline at end of file + # 检查当前元素和下一个元素的相对大小关系,决定是否交换 + if (nums[i + 2] >= nums[i + 1] and nums[i + 1] < nums[i]) or \ + (nums[i] > nums[i + 2] and nums[i + 2] <= nums[i + 1]): + # 根据条件进行元素交换 + if nums[i + 2] > nums[i + 1]: + nums[i + 1], nums[i + 2] = nums[i + 2], nums[i + 1] + else: + nums[i], nums[i + 1] = nums[i + 1], nums[i] + + # 这里也可以直接进行交换,简化逻辑 diff --git a/solutions/python3/282.py b/solutions/python3/282.py index fe68842..fc467d9 100644 --- a/solutions/python3/282.py +++ b/solutions/python3/282.py @@ -1,22 +1,35 @@ + class Solution: - def addOperators(self, num, target): + def addOperators(self, num: str, target: int) -> List[str]: """ :type num: str :type target: int :rtype: List[str] """ - # s, val, cur, coeff + + # 初始化队列,包含空字符串和初始的计算状态 (表达式串, 当前目标值, 当前数值, 乘数) q = {("", 0, 0, 1)} + + # 遍历数字中的每个字符 for i, c in enumerate(num): - new = set() + new = set() # 存储当前状态 + + # 对于每一个当前状态,生成新的状态并加入队列 for s, val, cur, coeff in q: - if i: + if i: # 如果不是第一个字符 new.add((s + "+" + c, val + int(c), int(c), 1)) new.add((s + "-" + c, val - int(c), int(c), -1)) new.add((s + "*" + c, val + cur * coeff * (int(c) - 1), int(c), cur * coeff)) - if s and s[-1] == "0" and cur == 0: continue - pre = cur - cur = cur * 10 + int(c) + + # 处理前导零的情况 + if s and s[-1] == "0" and cur == 0: + continue + + pre = cur # 保存当前数值 + cur = cur * 10 + int(c) # 构建新的数值 new.add((s + c, val + coeff * (cur - pre), cur, coeff)) - q = new - return [s for s, val, cur, coeff in q if val == target] \ No newline at end of file + + q = new # 更新队列 + + # 返回满足目标值的表达式串 + return [s for s, val, cur, coeff in q if val == target] diff --git a/solutions/python3/283.py b/solutions/python3/283.py index 06d0516..7fce7d4 100644 --- a/solutions/python3/283.py +++ b/solutions/python3/283.py @@ -1,10 +1,19 @@ + class Solution: def moveZeroes(self, nums): """ :type nums: List[int] :rtype: void Do not return anything, modify nums in-place instead. """ - i, items=0, 0 - while i "TreeNode": if not root: - return + return # 中文注释:如果根节点为空,直接返回 None。 + # 英文注释: If the root is None, return None. + if root.val > p.val: + # 中文注释:如果当前节点值大于给定节点值,则后继可能在左子树中(或左子树的最右节点)。 + # 英文注释: If current node value is greater than the given node's value, the successor might be in the left subtree (or its rightmost node). return self.inorderSuccessor(root.left, p) or root - return self.inorderSuccessor(root.right, p) + else: + # 中文注释:否则后继节点在右子树中,递归查找。 + # 英文注释: Otherwise, the successor is in the right subtree, recursively search there. + return self.inorderSuccessor(root.right, p) diff --git a/solutions/python3/286.py b/solutions/python3/286.py index 7a313d2..51ab958 100644 --- a/solutions/python3/286.py +++ b/solutions/python3/286.py @@ -1,13 +1,20 @@ + class Solution: + # 定义一个解题类 + def wallsAndGates(self, rooms): - m, n = len(rooms), len(rooms and rooms[0]) + m, n = len(rooms), len(rooms[0]) # 获取房间网格的行数和列数 + # 初始化队列和距离变量,将所有门的位置加入初始队列,并设置起始距离为0 q, dist = [(i, j) for i in range(m) for j in range(n) if not rooms[i][j]], 0 + while q: new = [] + # 每次循环增加一次距离 dist += 1 for i, j in q: for x, y in ((i - 1, j), (i + 1, j), (i, j - 1), (i, j + 1)): if 0 <= x < m and 0 <= y < n and rooms[x][y] == 2147483647: + # 如果找到新的未访问过的房间,更新其距离并加入队列 rooms[x][y] = dist new.append((x, y)) - q = new \ No newline at end of file + q = new # 更新当前待处理的房间列表 diff --git a/solutions/python3/287.py b/solutions/python3/287.py index 5df34eb..8c23270 100644 --- a/solutions/python3/287.py +++ b/solutions/python3/287.py @@ -1,14 +1,26 @@ + class Solution: def findDuplicate(self, nums): """ :type nums: List[int] :rtype: int """ - low, high, mid = 0, len(nums)-1, len(nums)-1 // 2 + # 初始化二分查找的边界 + low, high, mid = 0, len(nums) - 1, (len(nums) - 1) // 2 + + # 当搜索区间大于1时继续循环 while high - low > 1: + # 更新mid位置,并统计范围内元素数量 count, mid = 0, (high + low) // 2 + for k in nums: - if mid < k <= high: count += 1 - if count > high - mid: low = mid - else: high = mid - return high \ No newline at end of file + if mid < k <= high: + count += 1 + + # 根据计数结果调整搜索区间 + if count > high - mid: + low = mid + else: + high = mid + + return high diff --git a/solutions/python3/288.py b/solutions/python3/288.py index 80f0064..956582f 100644 --- a/solutions/python3/288.py +++ b/solutions/python3/288.py @@ -1,15 +1,24 @@ + +from collections import defaultdict + class ValidWordAbbr: def __init__(self, dictionary: List[str]): - self.pool = collections.defaultdict(set) + """ + 初始化字典,构建一个映射关系。使用哈希表存储单词的缩写形式和实际单词。 + :param dictionary: 初始词汇列表 + """ + self.pool = defaultdict(set) for w in dictionary: - self.pool[w[2:] and w[0] + str(len(w) - 2) + w[-1] or w].add(w) - + # 计算单词的缩写形式 + abbr = (w[0] + str(len(w) - 2) + w[-1]) if len(w) > 2 else w + # 将实际单词添加到对应的缩写集合中 + self.pool[abbr].add(w) def isUnique(self, w: str) -> bool: - return not self.pool[w[2:] and w[0] + str(len(w) - 2) + w[-1] or w] - {w} - - -# Your ValidWordAbbr object will be instantiated and called as such: -# obj = ValidWordAbbr(dictionary) -# param_1 = obj.isUnique(word) \ No newline at end of file + """ + 判断给定的单词是否唯一。如果该单词在哈希表中的映射集合不包含这个单词,则返回True。 + :param w: 待检查的单词 + :return: 如果单词是唯一的则返回True,否则返回False + """ + return not self.pool[(w[0] + str(len(w) - 2) + w[-1]) if len(w) > 2 else w] - {w} diff --git a/solutions/python3/289.py b/solutions/python3/289.py index d3a88ba..971eaa0 100644 --- a/solutions/python3/289.py +++ b/solutions/python3/289.py @@ -1,13 +1,29 @@ + class Solution: - def gameOfLife(self, board): + # 游戏生命函数 + def gameOfLife(self, board: List[List[int]]) -> None: + # 获取矩阵的行数和列数 m, n = len(board), len(board[0]) - matrix = [[0] * n for i in range(m)] + + # 创建一个新的矩阵用于存储新的状态 + matrix = [[0] * n for _ in range(m)] + + # 遍历原矩阵中的每个元素 for i in range(m): for j in range(n): cnt = 0 - for x, y in ((i - 1, j), (i + 1, j), (i, j - 1), (i, j + 1), (i - 1, j - 1), (i + 1, j + 1), (i - 1, j + 1), (i + 1, j - 1)): - if 0 <= x < m and 0 <= y < n and board[x][y] == 1: cnt += 1 - if (board[i][j] and 2 <= cnt <= 3) or (not board[i][j] and cnt == 3): matrix[i][j] = 1 + + # 计算当前元素周围的存活细胞数量 + for x, y in ((i - 1, j), (i + 1, j), (i, j - 1), (i, j + 1), + (i - 1, j - 1), (i + 1, j + 1), (i - 1, j + 1), (i + 1, j - 1)): + if 0 <= x < m and 0 <= y < n and board[x][y] == 1: + cnt += 1 + + # 根据规则更新新矩阵中的状态 + if (board[i][j] and 2 <= cnt <= 3) or (not board[i][j] and cnt == 3): + matrix[i][j] = 1 + + # 将原矩阵的状态更新为新的状态 for i in range(m): for j in range(n): - board[i][j] = matrix[i][j] \ No newline at end of file + board[i][j] = matrix[i][j] diff --git a/solutions/python3/29.py b/solutions/python3/29.py index cd86694..bdb21cd 100644 --- a/solutions/python3/29.py +++ b/solutions/python3/29.py @@ -1,18 +1,54 @@ + class Solution: - def divide(self, dividend, divisor): + def divide(self, dividend: int, divisor: int) -> int: """ - :type dividend: int - :type divisor: int - :rtype: int + :type dividend: int 被除数 + :type divisor: int 除数 + :rtype: int 返回结果 """ + + # 判断正负号 positive = (dividend < 0) is (divisor < 0) dividend, divisor, res = abs(dividend), abs(divisor), 0 + while dividend >= divisor: temp, i = divisor, 1 + # 快速减法,二进制左移实现快速计算 while dividend >= temp: dividend -= temp res += i i <<= 1 temp <<= 1 - if not positive: res = -res - return min(max(-2 ** 31, res), 2 ** 31 - 1) \ No newline at end of file + + if not positive: + res = -res + + return min(max(-2 ** 31, res), 2 ** 31 - 1) + + + +class Solution: + def divide(self, dividend: int, divisor: int) -> int: + """ + :type dividend: int 被除数 + :type divisor: int 除数 + :rtype: int 返回结果 + """ + + # 判断正负号 + positive = (dividend < 0) is (divisor < 0) + dividend, divisor, res = abs(dividend), abs(divisor), 0 + + while dividend >= divisor: + temp, i = divisor, 1 + # 快速减法,二进制左移实现快速计算 + while dividend >= temp: + dividend -= temp + res += i + i <<= 1 + temp <<= 1 + + if not positive: + res = -res + + return min(max(-2 ** 31, res), 2 ** 31 - 1) diff --git a/solutions/python3/290.py b/solutions/python3/290.py index 6d53be3..752baaf 100644 --- a/solutions/python3/290.py +++ b/solutions/python3/290.py @@ -1,16 +1,27 @@ + class Solution: - def wordPattern(self, pattern, str): + def wordPattern(self, pattern: str, str: str) -> bool: """ - :type pattern: str - :type str: str - :rtype: bool + :param pattern: 字符模式字符串 + :param str: 由空格分隔的单词组成的字符串 + :return: 如果str中的每个单词可以一一对应于pattern中的字符,则返回True,否则返回False """ - if len(str.split())!=len(pattern): return False - dic={} + + if len(str.split()) != len(pattern): + return False + + dic = {} + for word in str.split(): - if not pattern[0] in dic.values() and not word in dic: dic[word]=pattern[0] + # 检查当前模式字符是否已被映射过且不是当前单词 + if pattern[0] not in dic.values() and word not in dic: + dic[word] = pattern[0] else: - if not word in dic or dic[word]!=pattern[0]: return False - pattern=pattern[1:] + # 如果当前模式字符已经映射过或不匹配,则返回False + if word not in dic or dic[word] != pattern[0]: + return False + + # 移除已处理的模式字符 + pattern = pattern[1:] + return True - \ No newline at end of file diff --git a/solutions/python3/291.py b/solutions/python3/291.py index 55ac61e..8e7393f 100644 --- a/solutions/python3/291.py +++ b/solutions/python3/291.py @@ -1,17 +1,46 @@ + class Solution: - def wordPatternMatch(self, pattern, s): - m, n = len(pattern), len(s) - def dfs(i, j, dic, used): - if i >= m or j >= n: - return i == m and j == n + def wordPatternMatch(self, pattern: str, s: str) -> bool: + """ + 判断给定的模式 pattern 是否可以匹配字符串 s。 + + :param pattern: 字符串,表示模式 + :param s: 字符串,待匹配的目标字符串 + :return: 如果存在一种一一对应关系使得 pattern 能完全匹配 s,则返回 True + + 例如: + pattern = "abab", s = "redblueredblue" -> True (a -> red, b -> blue) + pattern = "aaaa", s = "asdasdasdasd" -> False (无法找到满足条件的映射关系) + """ + + def dfs(i: int, j: int, dic: dict, used: set) -> bool: + """ + 深度优先搜索,递归地检查 pattern 是否能匹配 s。 + + :param i: 当前处理到 pattern 中的第几个字符 + :param j: 当前处理到字符串 s 中的起始位置 + :param dic: 已经确定好的字符 -> 子串 映射关系字典 + :param used: 已经使用的子串集合,防止重复使用同一个子串 + + 返回值: + 如果存在一种匹配方式使得 pattern[i:] 能完全匹配 s[j:], 则返回 True + """ + + if i >= len(pattern) or j >= len(s): + # 模式遍历完或字符串遍历完且相等才成立 + return i == len(pattern) and j == len(s) elif pattern[i] in dic: + # 当前字符已经匹配过,检查是否能继续匹配 return s[j:j + len(dic[pattern[i]])] == dic[pattern[i]] and dfs(i + 1, j + len(dic[pattern[i]]), dic, used) else: - for k in range(j + 1, n + 1): + for k in range(j + 1, len(s) + 1): + # 尝试所有可能的子串 if s[j:k] not in used: dic[pattern[i]] = s[j:k] if dfs(i + 1, j + len(dic[pattern[i]]), dic, used | {s[j:k]}): return True + # 恢复现场,回溯检查其他可能的子串 dic.pop(pattern[i]) return False - return dfs(0, 0, {}, set()) \ No newline at end of file + + return dfs(0, 0, {}, set()) diff --git a/solutions/python3/292.py b/solutions/python3/292.py index a56eadc..22d40df 100644 --- a/solutions/python3/292.py +++ b/solutions/python3/292.py @@ -1,7 +1,9 @@ + class Solution: + # 判断给定的n是否能赢nim游戏(1到3步胜利) def canWinNim(self, n): """ - :type n: int - :rtype: bool + :type n: int # 输入整数n,表示游戏中的石子数量 + :rtype: bool # 返回布尔值,True表示可以获胜,False表示无法获胜 """ - return False if n%4==0 else True \ No newline at end of file + return False if n % 4 == 0 else True diff --git a/solutions/python3/293.py b/solutions/python3/293.py index 7b90a1a..0e80493 100644 --- a/solutions/python3/293.py +++ b/solutions/python3/293.py @@ -1,3 +1,6 @@ + class Solution: - def generatePossibleNextMoves(self, s): - return [s[:i] + "--" + s[i + 2:] for i in range(len(s) - 1) if s[i] == s[i + 1] == "+"] \ No newline at end of file + # 定义一个生成可能的下一步移动的方法 + def generatePossibleNextMoves(self, s: str) -> list[str]: + # 使用列表推导式找到所有相邻且相等为'+'的索引对,并将这些位置替换为"--" + return [s[:i] + "--" + s[i + 2:] for i in range(len(s) - 1) if s[i] == s[i + 1] == "+"] diff --git a/solutions/python3/294.py b/solutions/python3/294.py index 706167f..d0165bf 100644 --- a/solutions/python3/294.py +++ b/solutions/python3/294.py @@ -1,11 +1,40 @@ + class Solution: def canWin(self, s): - choices = {i for i in range(1, len(s)) if s[i] == s[i - 1] == "+"} + """ + 判断给定字符串s是否可以赢。如果通过翻转连续两个'+'可以获得一个新状态,且在该状态下对手无法获胜,则认为当前玩家可以赢得游戏。 + + 参数: + s (str): 由 '+' 和 '-' 组成的字符串 + + 返回值: + bool: 如果当前玩家能赢则返回True + """ + # 找到所有连续两个'+'的位置,用于后续dfs搜索 + choices = {i for i in range(1, len(s)) if s[i] == s[i - 1] == "+"} + def dfs(arr, moves, turn): + """ + 深度优先搜索辅助函数。 + + 参数: + arr (list): 当前状态数组,用于存储已经翻转的位置 + moves (set): 可以选择的移动集合,表示可以翻转的位置索引 + turn (int): 轮到哪一方走,1表示当前玩家,0表示对手 + + 返回值: + bool: 如果当前玩家在给定的状态下能获胜则返回True + """ if not moves: + # 当没有可移动的点时,检查是否轮到了当前玩家并且赢了 return turn == 1 - elif turn: - return all(dfs(arr + [m], moves - {m - 1, m, m + 1}, 1 - turn) for m in moves) + + if turn: + # 轮到当前玩家走,需要所有对手可能的选择都输掉 + return all(dfs(arr + [m], moves - {m - 1, m, m + 1}, 1 - turn) for m in moves) else: - return any(dfs(arr + [m], moves - {m - 1, m, m + 1}, 1 - turn) for m in moves) - return not dfs([], choices, 1) \ No newline at end of file + # 轮到对手走,只要有一个选择使得对手输掉即可 + return any(dfs(arr + [m], moves - {m - 1, m, m + 1}, 1 - turn) for m in moves) + + # 初始状态下没有任何翻转,且轮到当前玩家开始 + return not dfs([], choices, 1) diff --git a/solutions/python3/295.py b/solutions/python3/295.py index 3994c3c..b3e31dc 100644 --- a/solutions/python3/295.py +++ b/solutions/python3/295.py @@ -1,33 +1,43 @@ + class MedianFinder: + # 初始化数据结构,用于存储左右两部分和中间值 def __init__(self): - self.l = [] - self.r = [] - self.m = [] + import heapq # 引入堆模块 + self.l = [] # 左侧小顶堆 + self.r = [] # 右侧大顶堆 + self.m = [] # 中间值列表 def addNum(self, num): + # 如果中间值为空,直接加入第一个数 if not self.m: self.m = [num] - elif len(self.m) == 1: + elif len(self.m) == 1: # 如果中间值只有一个元素 m = self.m[0] if num >= m: + # 新数字大于等于当前中间值,左右两堆分别加入 self.m = [m, heapq.heappushpop(self.r, num)] else: + # 新数字小于当前中间值,调整堆并更新中间值 self.m = [-heapq.heappushpop(self.l, -num), m] - else: + else: # 如果中间值有两个元素 m1, m2 = self.m if num >= m2: + # 新数字大于等于第二个中间值 heapq.heappush(self.r, num) heapq.heappush(self.l, -m1) self.m = [m2] elif num <= m1: + # 新数字小于第一个中间值 heapq.heappush(self.l, -num) heapq.heappush(self.r, m2) self.m = [m1] else: + # 新数字在两个中间值之间,调整堆并更新中间值 heapq.heappush(self.l, -m1) heapq.heappush(self.r, m2) self.m = [num] def findMedian(self): - return sum(self.m) / len(self.m) \ No newline at end of file + # 计算当前所有中间值的平均数作为中位数 + return sum(self.m) / len(self.m) diff --git a/solutions/python3/296.py b/solutions/python3/296.py index fc01579..75276f8 100644 --- a/solutions/python3/296.py +++ b/solutions/python3/296.py @@ -1,7 +1,17 @@ + class Solution: + # 初始化解决方案类 + def minTotalDistance(self, grid): - m, n = len(grid), len(grid[0]) - x, y = sorted(i for i in range(m) for j in range(n) if grid[i][j]), sorted(j for i in range(m) for j in range(n) if grid[i][j]) + m, n = len(grid), len(grid[0]) # 获取网格的行数m和列数n + + # 提取所有有1的位置的x坐标和y坐标分别排序 + x = sorted(i for i in range(m) for j in range(n) if grid[i][j]) + y = sorted(j for i in range(m) for j in range(n) if grid[i][j]) + + # 计算中位数作为平均位置 avg_x = len(x) % 2 and x[len(x) // 2] or (x[len(x) // 2 - 1] + x[len(x) // 2]) / 2 avg_y = len(y) % 2 and y[len(y) // 2] or (y[len(y) // 2 - 1] + y[len(y) // 2]) / 2 - return int(sum(abs(avg_x - i) + abs(avg_y - j) for i, j in zip(x, y))) \ No newline at end of file + + # 计算所有点到平均位置的曼哈顿距离之和 + return int(sum(abs(avg_x - i) + abs(avg_y - j) for i, j in zip(x, y))) diff --git a/solutions/python3/297.py b/solutions/python3/297.py index 839448a..6a7f6cb 100644 --- a/solutions/python3/297.py +++ b/solutions/python3/297.py @@ -1,6 +1,16 @@ + class Codec: def serialize(self, root): + """ + 序列化二叉树,将二叉树转换为字符串形式。 + + 参数: + root (TreeNode): 二叉树的根节点 + + 返回: + str: 表示二叉树的字符串 + """ q, s = root and collections.deque([root]), "" while q: node = q.popleft() @@ -10,11 +20,21 @@ def serialize(self, root): s += str(node.val) + "#" q += [node.left, node.right] return s - def deserialize(self, data): - data = data and collections.deque(data.split("#")) - q, root = data and collections.deque([TreeNode(int(data.popleft()))]), None + """ + 反序列化字符串,将字符串转换为二叉树。 + + 参数: + data (str): 表示二叉树的字符串 + + 返回: + TreeNode: 重构后的二叉树根节点 + """ + if not data: + return None + data = collections.deque(data.split("#")) + q, root = collections.deque([TreeNode(int(data.popleft()))]), None while q: node = q.popleft() if not root: @@ -26,4 +46,4 @@ def deserialize(self, data): if r != "null": node.right = TreeNode(int(r)) q.append(node.right) - return root \ No newline at end of file + return root diff --git a/solutions/python3/298.py b/solutions/python3/298.py index b69e2c5..f9a05e7 100644 --- a/solutions/python3/298.py +++ b/solutions/python3/298.py @@ -1,15 +1,19 @@ + # Definition for a binary tree node. -# class TreeNode: -# def __init__(self, x): -# self.val = x -# self.left = None -# self.right = None +class TreeNode: + def __init__(self, x): + self.val = x + self.left = None + self.right = None +# Solution class to solve the longest consecutive sequence problem in a binary tree class Solution: - def longestConsecutive(self, root): + # Find the length of the longest consecutive sequence path in a binary tree + def longestConsecutive(self, root: TreeNode) -> int: q, l = root and [(root, 1)] or [], 0 while q: node, path = q.pop() l = max(l, path) + # Append children to the queue with updated path lengths if they are consecutive q += [(child, child.val == node.val + 1 and path + 1 or 1) for child in (node.left, node.right) if child] - return l \ No newline at end of file + return l diff --git a/solutions/python3/299.py b/solutions/python3/299.py index 7ff2db6..ce54829 100644 --- a/solutions/python3/299.py +++ b/solutions/python3/299.py @@ -1,10 +1,25 @@ + class Solution: - def getHint(self, secret, guess): - s, g, a, b = collections.defaultdict(int), collections.defaultdict(int), 0, 0 + def getHint(self, secret: str, guess: str) -> str: + # 初始化计数器s和g,分别用于记录秘密中未匹配的数字及其在猜测中的数量、猜测中未匹配的数字及其在秘密中的数量 + s, g = collections.defaultdict(int), collections.defaultdict(int) + a, b = 0, 0 # a表示正确位置的数量,b表示正确数字但位置错误的数量 + for i in range(len(secret)): - if secret[i] == guess[i]: a += 1; continue - if s[guess[i]] > 0: b, s[guess[i]] = b + 1, s[guess[i]] - 1 - else: g[guess[i]] += 1 - if g[secret[i]] > 0: b, g[secret[i]] = b + 1, g[secret[i]] - 1 - else: s[secret[i]] += 1 - return "%dA%dB" % (a, b) \ No newline at end of file + # 如果当前位置上的数字匹配,则a加1 + if secret[i] == guess[i]: + a += 1 + continue + + # 如果猜测中的数字在秘密中已出现过,则增加b计数,减少s中相应计数,并将猜测中的该数字加入g记录 + if s[guess[i]] > 0: + b, s[guess[i]] = b + 1, s[guess[i]] - 1 + g[guess[i]] += 1 + + # 如果秘密中的数字在猜测中已出现过,则增加b计数,减少g中相应计数,并将秘密中的该数字加入s记录 + if g[secret[i]] > 0: + b, g[secret[i]] = b + 1, g[secret[i]] - 1 + s[secret[i]] += 1 + + # 返回结果格式化字符串,包含正确位置和正确数字但位置错误的数量 + return "%dA%dB" % (a, b) diff --git a/solutions/python3/3.py b/solutions/python3/3.py index 2482cd9..917e9de 100644 --- a/solutions/python3/3.py +++ b/solutions/python3/3.py @@ -1,12 +1,24 @@ + class Solution: - def lengthOfLongestSubstring(self, s): + # 定义一个方法,用于计算最长不含重复字符的子串长度 + def lengthOfLongestSubstring(self, s: str) -> int: """ - :type s: str - :rtype: int + :type s: str # 输入字符串s + :rtype: int # 返回最长不含重复字符的子串长度 """ - mx, start, chars = 0, 0, {} + + max_len, start, char_map = 0, 0, {} # 初始化最大长度,起始位置和字符索引映射字典 + for i in range(len(s)): - if s[i] in chars and start <= chars[s[i]]: start = chars[s[i]] + 1 - else: mx = max(mx, i - start + 1) - chars[s[i]] = i - return mx \ No newline at end of file + # 如果当前字符已经在映射字典中,并且其上次出现的位置在当前起始位置之前或等于 + if s[i] in char_map and start <= char_map[s[i]]: + # 更新起始位置为该字符上一次出现位置的下一个位置 + start = char_map[s[i]] + 1 + else: + # 更新最大长度,确保每次都是当前子串的最新长度 + max_len = max(max_len, i - start + 1) + + # 更新字符映射字典 + char_map[s[i]] = i + + return max_len # 返回最长不含重复字符的子串长度 diff --git a/solutions/python3/30.py b/solutions/python3/30.py index 3ce75d4..8b08e51 100644 --- a/solutions/python3/30.py +++ b/solutions/python3/30.py @@ -1,15 +1,51 @@ + class Solution: - def findSubstring(self, s, words): - if not s or not words: return [] - cnt, l_words, l_word, cnt_words, res = collections.Counter(words), len(words[0]) * len(words), len(words[0]), len(words), [] + def findSubstring(self, s: str, words: list) -> list: + """ + 找出给定字符串中包含所有单词的子串起始位置。 + + :param s: 输入字符串 + :param words: 单词列表 + :return: 包含所有单词的子串起始位置列表 + """ + if not s or not words: + return [] + + from collections import Counter + + # 统计每个单词出现次数 + cnt = Counter(words) + + # 计算所有单词总长度 + l_words = len(words[0]) * len(words) + + # 单词的单个长度 + l_word = len(words[0]) + + # 单词数量 + cnt_words = len(words) + + res = [] + for i in range(len(s) - l_words + 1): cur, j = dict(cnt), i + for _ in range(cnt_words): w = s[j:j + l_word] + if w in cur: - if cur[w] == 1: cur.pop(w) - else: cur[w] -= 1 - else: break + # 如果单词计数为1,移除该键值对 + if cur[w] == 1: + cur.pop(w) + else: + cur[w] -= 1 + + else: + break + j += l_word - if not cur: res += i, - return res \ No newline at end of file + + if not cur: + res.append(i) + + return res diff --git a/solutions/python3/300.py b/solutions/python3/300.py index 4fce8cf..e8e3745 100644 --- a/solutions/python3/300.py +++ b/solutions/python3/300.py @@ -1,12 +1,26 @@ + class Solution: def lengthOfLIS(self, nums): """ :type nums: List[int] :rtype: int + + 中文注释: + 1. 使用二分查找优化寻找最长递增子序列的长度。 + 2. `tails` 数组用于存储当前所有递增子序列中最后一个元素的最小值。 + 3. `size` 表示当前能构造的最大递增子序列的长度。 + + 英文注释: + 1. Use binary search to optimize finding the length of the longest increasing subsequence. + 2. The `tails` array stores the minimum values of the last elements in all current increasing subsequences. + 3. `size` indicates the maximum length of the increasing subsequence that can be constructed currently. """ tails = [0] * len(nums) size = 0 for x in nums: + # 使用二分查找在 tails 中找到第一个大于等于 x 的位置 i + # Chinese: Use binary search to find the first position `i` where `tails[i] >= x` + # English: Use binary search to find the first position `i` where `tails[i] >= x` i, j = 0, size while i != j: m = (i + j) // 2 @@ -15,5 +29,8 @@ def lengthOfLIS(self, nums): else: j = m tails[i] = x + # 更新 size,确保它总是表示当前最大子序列长度 + # Chinese: Update `size` to always indicate the current maximum subsequence length + # English: Update `size` to always indicate the current maximum subsequence length size = max(i + 1, size) - return size \ No newline at end of file + return size diff --git a/solutions/python3/301.py b/solutions/python3/301.py index ee00970..29e1c2f 100644 --- a/solutions/python3/301.py +++ b/solutions/python3/301.py @@ -1,27 +1,50 @@ + class Solution: - def removeInvalidParentheses(self, s): + def removeInvalidParentheses(self, s: str) -> List[str]: + """ + 移除无效的括号,使字符串合法。该函数会返回所有可能的结果。 + + Args: + s (str): 输入的包含字母和括号的字符串 + + Returns: + List[str]: 一个列表,其中包含所有移除了无效括号后的合法字符串 + """ + l = r = 0 + # 计算需要移除的左括号和右括号数量 for c in s: - if c.isalpha(): continue - if c == "(": l += 1 - elif l: l -= 1 - else: r += 1 + if c.isalpha(): + continue + if c == "(": + l += 1 + elif l: + l -= 1 + else: + r += 1 + q = {("", l, r, 0, 0)} + # 使用集合模拟队列,存储状态 (字符串, 需移除的左括号数, 需移除的右括号数, 当前左括号计数, 当前右括号计数) + for c in s: new = set() + # 生成新的状态集合 for st, l, r, lCur, rCur in q: if c == "(": new.add((st + c, l, r, lCur + 1, rCur)) - if l: + if l: new.add((st, l - 1, r, lCur, rCur)) elif c == ")": - if lCur: + if lCur: new.add((st + c, l, r, lCur - 1, rCur)) - else: + else: new.add((st + c, l, r, lCur, rCur + 1)) - if r: + if r: new.add((st, l, r - 1, lCur, rCur)) else: new.add((st + c, l, r, lCur, rCur)) q = new - return list({st for st, l, r, lCur, rCur in q if l == r == lCur == rCur == 0}) \ No newline at end of file + # 更新状态集合 + + return list({st for st, l, r, lCur, rCur in q if l == r == lCur == rCur == 0}) + # 返回所有满足条件的合法字符串列表 diff --git a/solutions/python3/302.py b/solutions/python3/302.py index fa656b6..484a111 100644 --- a/solutions/python3/302.py +++ b/solutions/python3/302.py @@ -1,14 +1,38 @@ + class Solution: - def minArea(self, image, x, y): - l, r, u, d, m, n = [y], [y], [x], [x], len(image), len(image[0]) - def dfs(i, j): - if i < u[0]: u[0] = i + def minArea(self, image: List[List[str]], x: int, y: int) -> int: + """ + Given an "image" represented by a 2D array of '1's (land) and '0's (water), + return the area of the smallest rectangle that contains all land in the matrix. + + Args: + image: A list of lists of strings representing the image. Each cell is either '1' or '0'. + x, y: Coordinates within the image to start searching for the bounding box. + + Returns: + The area (number of pixels) of the smallest rectangle containing all land in the matrix. + """ + + l, r, u, d = [y], [y], [x], [x] # 初始化左右上下边界 + m, n = len(image), len(image[0]) # 获取图像的行数和列数 + + def dfs(i: int, j: int) -> None: + """ + Depth-first search to explore the land cells and update the boundaries. + + Args: + i: Current row index in the image. + j: Current column index in the image. + """ + if i < u[0]: u[0] = i # 更新上边界 elif i > d[0]: d[0] = i - if j < l[0]: l[0] = j + if j < l[0]: l[0] = j # 更新左边界 elif j > r[0]: r[0] = j for x, y in ((i - 1, j), (i + 1, j), (i, j - 1), (i, j + 1)): if 0 <= x < m and 0 <= y < n and image[x][y] == "1": - image[x][y] = "0" + image[x][y] = "0" # 标记已访问过的陆地 dfs(x, y) - dfs(x, y) - return (r[0] - l[0] + 1) * (d[0] - u[0] + 1) \ No newline at end of file + + dfs(x, y) # 从起始点进行深度优先搜索 + + return (r[0] - l[0] + 1) * (d[0] - u[0] + 1) # 计算矩形面积 diff --git a/solutions/python3/303.py b/solutions/python3/303.py index 99b4628..e37f97f 100644 --- a/solutions/python3/303.py +++ b/solutions/python3/303.py @@ -1,10 +1,21 @@ + class NumArray: + # 初始化类,传入一个整数列表nums + # 中文: 初始化类,传入一个整数列表nums + # 英文: Initialize the class with a list of integers nums + def __init__(self, nums): - self.nums = nums + self.nums = nums # 存储输入的数字列表 + # 中文: 存储输入的数字列表 + # English: Store the input list of numbers + for i in range(1, len(nums)): self.nums[i] += self.nums[i - 1] - + # 中文: 使用前缀和优化求区间和 + # 英文: Use prefix sum to optimize range sum queries def sumRange(self, i, j): - return self.nums[j] - self.nums[i - 1] if i else self.nums[j] \ No newline at end of file + return self.nums[j] - self.nums[i - 1] if i else self.nums[j] + # 中文: 返回从索引i到j的区间和 + # 英文: Return the sum of elements from index i to j diff --git a/solutions/python3/304.py b/solutions/python3/304.py index 5df98ea..7870dfd 100644 --- a/solutions/python3/304.py +++ b/solutions/python3/304.py @@ -1,10 +1,21 @@ + class NumMatrix: def __init__(self, matrix): - self.sums = [[0] * (len(matrix and matrix[0]) + 1) for _ in range(len(matrix) + 1)] + # 初始化二维前缀和数组,大小比原矩阵大1 + # Chinese: 初始化一个二维前缀和数组 sums,其大小比输入的矩阵多一行一列。 + self.sums = [[0] * (len(matrix) and len(matrix[0]) + 1) for _ in range(len(matrix) + 1)] + + # 遍历原矩阵填充前缀和数组 + # Chinese: 遍历输入的矩阵,计算并填充前缀和数组。 for i in range(len(matrix)): - for j in range(len(matrix and matrix[0])): - self.sums[i + 1][j + 1] = self.sums[i][j + 1] + self.sums[i + 1][j] - self.sums[i][j] + matrix[i][j] + for j in range(len(matrix[0])): + self.sums[i + 1][j + 1] = (self.sums[i][j + 1] + + self.sums[i + 1][j] - + self.sums[i][j] + + matrix[i][j]) def sumRegion(self, row1, col1, row2, col2): - return self.sums[row2 + 1][col2 + 1] - self.sums[row2 + 1][col1] - self.sums[row1][col2 + 1] + self.sums[row1][col1] \ No newline at end of file + # 根据前缀和计算指定区域的和 + # Chinese: 使用前缀和数组快速求解给定矩形区域的元素总和。 + return self.sums[row2 + 1][col2 + 1] - self.sums[row2 + 1][col1] - self.sums[row1][col2 + 1] + self.sums[row1][col1] diff --git a/solutions/python3/305.py b/solutions/python3/305.py index 18ca188..f06a507 100644 --- a/solutions/python3/305.py +++ b/solutions/python3/305.py @@ -1,18 +1,30 @@ + class Solution: - def numIslands2(self, m, n, positions): + def numIslands2(self, m: int, n: int, positions: List[Tuple[int, int]]) -> List[int]: + # 获取父节点,路径压缩优化 def getParent(i): if i != parent[i]: parent[i] = getParent(parent[i]) return parent[i] + islands, res, parent, Id = set(), [], {}, 1 + for i, j in positions: + # 添加新陆地并初始化其父节点 parent[(i, j)] = parent[Id] = Id + + # 遍历四个方向,合并相邻陆地 for x, y in ((i - 1, j), (i + 1, j), (i, j - 1), (i, j + 1)): if (x, y) in parent: p = getParent(parent[(x, y)]) islands.discard(p) parent[p] = Id + + # 添加新的岛屿标识 islands.add(Id) Id += 1 + + # 更新结果集 res.append(len(islands)) - return res \ No newline at end of file + + return res diff --git a/solutions/python3/306.py b/solutions/python3/306.py index 59b26f0..5cc5db8 100644 --- a/solutions/python3/306.py +++ b/solutions/python3/306.py @@ -1,20 +1,27 @@ + class Solution: - def isAdditiveNumber(self, num): + def isAdditiveNumber(self, num: str) -> bool: + # 获取起始数对 def getStarter(): arr = [] for i in range(1, len(num) - 1): for j in range(i + 1, len(num)): s1, s2 = num[:i], num[i:j] - if (s1[0] == "0" and len(s1) > 1) or (s2[0] == "0" and len(s2) > 1): + # 跳过以0开头且长度大于1的字符串 + if (s1[0] == "0" and len(s1) > 1) or (s2[0] == "0" and len(s2) > 1): continue arr.append((int(s1), int(s2), j)) - return arr + return arr + + # 深度优先搜索,验证是否为添加型数字序列 def dfs(pre1, pre2, i): - if i == len(num): + if i == len(num): # 遍历完整个字符串 return True - sm = pre1 + pre2 - l = len(str(sm)) - new = int(num[i:i + l]) - return new == sm and dfs(pre2, new, i + l) + sm = pre1 + pre2 # 计算前两个数的和 + l = len(str(sm)) # 获得该和的长度 + new = int(num[i:i + l]) # 获取新生成的数 + return new == sm and dfs(pre2, new, i + l) # 检查是否相等并递归 + + # 找出所有可能的起始组合,并进行验证 q = getStarter() - return any(dfs(p1, p2, i) for p1, p2, i in q) \ No newline at end of file + return any(dfs(p1, p2, i) for p1, p2, i in q) diff --git a/solutions/python3/307.py b/solutions/python3/307.py index 03bea23..bf951de 100644 --- a/solutions/python3/307.py +++ b/solutions/python3/307.py @@ -1,29 +1,42 @@ + class NumArray: + # 初始化树状数组,传入一个整数列表nums def __init__(self, nums): - if nums: + if nums: # 如果输入的nums不为空 self.n = len(nums) - self.tree = [0] * (2 * (2 ** int(math.ceil(math.log(self.n, 2)))) - 1) + self.tree = [0] * (2 * (2 ** int(math.ceil(math.log(self.n, 2)))) - 1) # 初始化树状数组,大小为4*n-1 + def dfs(node, s, e): + # 如果是叶子节点,则直接赋值 if s == e: self.tree[node] = nums[s] else: - m = (s + e) // 2 - dfs(2 * node + 1, s, m) - dfs(2 * node + 2, m + 1, e) - self.tree[node] = self.tree[2 * node + 1] + self.tree[2 * node + 2] - dfs(0, 0, self.n - 1) + m = (s + e) // 2 # 找到中间节点 + dfs(2 * node + 1, s, m) # 递归左子树 + dfs(2 * node + 2, m + 1, e) # 递归右子树 + self.tree[node] = self.tree[2 * node + 1] + self.tree[2 * node + 2] # 更新当前节点值 + + dfs(0, 0, self.n - 1) # 从根节点开始构建 + def update(self, i, val): + # 更新树状数组中索引i的值为val def dfs(node, s, e, idx, val): - if s == e: self.tree[node] = val + if s == e: self.tree[node] = val # 如果是叶子节点,直接更新 else: - m = (s + e) // 2 - if s <= idx <= m: dfs(2 * node + 1, s, m, idx, val) - else: dfs(2 * node + 2, m + 1, e, idx, val) - self.tree[node] = self.tree[2 * node + 1] + self.tree[2 * node + 2] - dfs(0, 0, self.n - 1, i, val) + m = (s + e) // 2 # 找到中间节点 + if s <= idx <= m: # 在左子树中递归查找 + dfs(2 * node + 1, s, m, idx, val) + else: # 在右子树中递归查找 + dfs(2 * node + 2, m + 1, e, idx, val) + self.tree[node] = self.tree[2 * node + 1] + self.tree[2 * node + 2] # 更新当前节点值 + + dfs(0, 0, self.n - 1, i, val) # 从根节点开始更新 + def sumRange(self, i, j): + # 计算索引i到j的区间和 def dfs(node, s, e, l, r): - if r < s or l > e: return 0 - if l <= s and e <= r: return self.tree[node] - m = (s + e) // 2 - return dfs(2 * node + 1, s, m, l, r) + dfs(2 * node + 2, m + 1, e, l, r) - return dfs(0, 0, self.n - 1, i, j) \ No newline at end of file + if r < s or l > e: return 0 # 如果区间为空,则返回0 + if l <= s and e <= r: return self.tree[node] # 如果当前节点完全在查询范围内,直接返回其值 + m = (s + e) // 2 # 找到中间节点 + return dfs(2 * node + 1, s, m, l, r) + dfs(2 * node + 2, m + 1, e, l, r) # 分别递归查询左右子树的和 + + return dfs(0, 0, self.n - 1, i, j) # 从根节点开始计算区间和 diff --git a/solutions/python3/308.py b/solutions/python3/308.py index b84ebbe..e8ff8e7 100644 --- a/solutions/python3/308.py +++ b/solutions/python3/308.py @@ -1,44 +1,48 @@ + class NumMatrix(object): + def __init__(self, matrix): """ - initialize your data structure here. + 初始化数据结构。 :type matrix: List[List[int]] """ + # 前缀和优化,累加每一行的前一个元素 for row in matrix: for col in range(1, len(row)): row[col] += row[col-1] self.matrix = matrix - def update(self, row, col, val): """ - update the element at matrix[row,col] to val. + 更新矩阵[row,col]位置的值为val。 :type row: int :type col: int :type val: int :rtype: void """ + # 计算原值与差值 original = self.matrix[row][col] if col != 0: original -= self.matrix[row][col-1] - + diff = original - val - + for y in range(col, len(self.matrix[0])): self.matrix[row][y] -= diff def sumRegion(self, row1, col1, row2, col2): """ - sum of elements matrix[(row1,col1)..(row2,col2)], inclusive. + 计算矩阵中[(row1,col1)..(row2,col2)]范围内元素的和。 :type row1: int :type col1: int :type row2: int :type col2: int :rtype: int """ + # 计算指定区域的和 sum = 0 - for x in range(row1, row2+1): + for x in range(row1, row2 + 1): sum += self.matrix[x][col2] if col1 != 0: - sum -= self.matrix[x][col1-1] - return sum \ No newline at end of file + sum -= self.matrix[x][col1 - 1] + return sum diff --git a/solutions/python3/309.py b/solutions/python3/309.py index 406797b..75f3cc6 100644 --- a/solutions/python3/309.py +++ b/solutions/python3/309.py @@ -1,6 +1,18 @@ + class Solution: + # 定义一个解决方案类 + def maxProfit(self, prices): + # 初始化动态规划变量:dp1表示持有股票的最大利润,dp2表示首次卖出股票后的最大利润, + # dp3表示第二次买入股票后的最大累计亏损(负值) + dp1, dp2, dp3 = 0, 0, -float("inf") + for p in prices: + # 遍历每一天的价格 + + # 更新持有股票的最大利润 dp1, dp2, dp3 = dp3 + p, max(dp1, dp2), max(dp2 - p, dp3) - return max(dp1, dp2) \ No newline at end of file + # 依次更新dp1, dp2, dp3 + + return max(dp1, dp2) # 返回最大利润 diff --git a/solutions/python3/31.py b/solutions/python3/31.py index c95c990..e231e95 100644 --- a/solutions/python3/31.py +++ b/solutions/python3/31.py @@ -1,13 +1,28 @@ + class Solution: def nextPermutation(self, nums): + # 寻找第一个从后向前递减的元素位置 l + # Find the first element from right to left that is smaller than its right neighbor perm, l = False, len(nums) - 2 + while 0 <= l: + # 寻找比 l 元素大的最右元素 r + # Find the rightmost element that is larger than nums[l] r = len(nums) - 1 while l < r and nums[r] <= nums[l]: r -= 1 + if r <= l: + # 如果没有找到更大的元素,则 l 左移一位 + # If no such element found, move l left one step l -= 1 else: + # 交换 l 和 r 元素的位置,并对剩余部分进行排序,生成下一个排列 + # Swap nums[l] and nums[r], sort the remaining part to get the next permutation nums[l], nums[l + 1:], perm = nums[r], sorted(nums[l + 1:r] + [nums[l]] + nums[r + 1:]), True break - if not perm: nums.sort() \ No newline at end of file + + if not perm: + # 如果没有找到下一个排列,则将整个数组排序 + # If no next permutation found, sort the whole array + nums.sort() diff --git a/solutions/python3/310.py b/solutions/python3/310.py index 109509f..203ffcb 100644 --- a/solutions/python3/310.py +++ b/solutions/python3/310.py @@ -1,18 +1,38 @@ + class Solution: + # 寻找具有最小高度的树根节点 def findMinHeightTrees(self, n, edges): - if n == 1: return [0] + """ + :param n: 图中的节点数 (int) + :param edges: 表示图中边的列表,每个元素是一个长度为2的元组 (List[List[int]]) + :return: 具有最小高度的树根节点的索引列表 (List[int]) + """ + + if n == 1: + # 如果只有一个节点,则返回该节点 + return [0] + + # 构建邻接表表示图 adj = [set() for i in range(n)] for i, j in edges: adj[i].add(j) adj[j].add(i) + + # 找出所有叶子节点(度为1的节点) leaves = [i for i in range(n) if len(adj[i]) == 1] + while n > 2: + # 更新节点数量 n -= len(leaves) newleaves = [] + + # 移除叶子节点并更新邻接表 for i in leaves: j = adj[i].pop() adj[j].remove(i) - if len(adj[j]) == 1: + if len(adj[j]) == 1: newleaves.append(j) + leaves = newleaves - return leaves \ No newline at end of file + + return leaves diff --git a/solutions/python3/311.py b/solutions/python3/311.py index 8d5ff77..d032045 100644 --- a/solutions/python3/311.py +++ b/solutions/python3/311.py @@ -1,3 +1,10 @@ + class Solution: + # 中文: 实现矩阵乘法,给定两个二维数组A和B,返回它们的乘积。 + # 英文: Implement matrix multiplication. Given two 2D arrays A and B, return their product. + def multiply(self, A, B): - return [[sum(a * b for a, b in zip(A[i], [B[k][j] for k in range(len(B))])) for j in range(len(B[0]))] for i in range(len(A))] \ No newline at end of file + # 中文: 使用列表推导式遍历矩阵A的每一行 + # 英文: Use list comprehension to iterate over each row of matrix A + return [[sum(a * b for a, b in zip(A[i], [B[k][j] for k in range(len(B))])) for j in range(len(B[0]))] + for i in range(len(A))] diff --git a/solutions/python3/312.py b/solutions/python3/312.py index cc68e11..1153200 100644 --- a/solutions/python3/312.py +++ b/solutions/python3/312.py @@ -1,8 +1,21 @@ + class Solution: def maxCoins(self, nums): + # 初始化备忘录和扩充后的数组 memo, nums = {}, [1] + [num for num in nums if num] + [1] + def dfs(l, r): - if r - l == 1: return 0 - if (l, r) not in memo: memo[(l, r)] = max(nums[l] * nums[i] * nums[r] + dfs(l, i) + dfs(i, r) for i in range(l + 1, r)) + # 基线条件:只有两个元素时,无需爆破气球 + if r - l == 1: + return 0 + + # 如果该子问题未被解决,则尝试所有可能的中间点进行计算,并记录结果到备忘录中 + if (l, r) not in memo: + memo[(l, r)] = max(nums[l] * nums[i] * nums[r] + dfs(l, i) + dfs(i, r) + for i in range(l + 1, r)) + + # 返回子问题的解 return memo[(l, r)] - return dfs(0, len(nums) - 1) \ No newline at end of file + + # 调用深度优先搜索从第一个气球到最后一个气球爆破的所有可能情况 + return dfs(0, len(nums) - 1) diff --git a/solutions/python3/313.py b/solutions/python3/313.py index 81ee832..6c103ad 100644 --- a/solutions/python3/313.py +++ b/solutions/python3/313.py @@ -1,11 +1,25 @@ + class Solution: - def nthSuperUglyNumber(self, n, primes): + # 定义一个类来解决寻找第n个超级丑数的问题 + + def nthSuperUglyNumber(self, n: int, primes: list) -> int: + # 初始化结果数组arr,包含第一个超级丑数1;primes是给定的素数列表; arr, heap, used = [1], primes[:], set() + + # 从第二个超级丑数开始计算直到第n个 for i in range(1, n): + # 取出堆中的最小值作为当前super-ugly number num = heapq.heappop(heap) + + # 将该值加入结果数组 arr.append(num) + + # 生成新的super-ugly number并加入堆中,同时标记为已使用 for p in primes: - if p * num not in used: - heapq.heappush(heap, p * num) - used.add(p * num) - return arr[-1] \ No newline at end of file + new_num = p * num + if new_num not in used: + heapq.heappush(heap, new_num) + used.add(new_num) + + # 返回结果数组中的最后一个元素即第n个super-ugly number + return arr[-1] diff --git a/solutions/python3/314.py b/solutions/python3/314.py index d4f8bf3..29f7362 100644 --- a/solutions/python3/314.py +++ b/solutions/python3/314.py @@ -1,3 +1,4 @@ + # Definition for a binary tree node. # class TreeNode: # def __init__(self, x): @@ -6,15 +7,26 @@ # self.right = None class Solution: - def verticalOrder(self, root): - q, arrays = root and collections.deque([(root, 0)]) or None, collections.defaultdict(list) + # 该方法用于按垂直顺序遍历二叉树并返回节点值列表 + def verticalOrder(self, root: 'TreeNode') -> list[list[int]]: + # 初始化队列和字典,记录每个垂直线上的节点值 + q, arrays = (root and collections.deque([(root, 0)]) or None), collections.defaultdict(list) + while q: + # 创建一个新的deque来存储下一层的节点及其索引 new = collections.deque() + for node, ind in q: + # 将当前节点值添加到对应的垂直线列表中 arrays[ind].append(node.val) - if node.left: + + if node.left: # 如果左子节点存在,将其加入队列并调整索引为-1 new.append((node.left, ind - 1)) - if node.right: + + if node.right: # 如果右子节点存在,将其加入队列并调整索引为+1 new.append((node.right, ind + 1)) - q = new - return [arr for i, arr in sorted(arrays.items())] \ No newline at end of file + + q = new # 更新当前层的队列为下一层的队列 + + # 按照垂直线索引排序并返回结果 + return [arr for i, arr in sorted(arrays.items())] diff --git a/solutions/python3/315.py b/solutions/python3/315.py index 2ae1b56..5317669 100644 --- a/solutions/python3/315.py +++ b/solutions/python3/315.py @@ -1,7 +1,22 @@ + class Solution: - def countSmaller(self, nums): + def countSmaller(self, nums: list[int]) -> list[int]: + """ + 计算每个元素左侧比其小的元素个数 + + Args: + nums (list[int]): 输入整数列表 + + Returns: + list[int]: 每个元素左侧比其小的元素个数 + """ + + # 从后向前遍历,确保插入排序时保持相对顺序 r = [] for i in range(len(nums) - 1, -1, -1): + # 在已有序列表中插入当前值,并返回新位置索引 bisect.insort(r, nums[i]) + # 计算并更新原列表对应位置为左侧小于当前元素的个数 nums[i] = bisect.bisect_left(r, nums[i]) - return nums \ No newline at end of file + + return nums diff --git a/solutions/python3/316.py b/solutions/python3/316.py index b73e7f6..085eb1e 100644 --- a/solutions/python3/316.py +++ b/solutions/python3/316.py @@ -1,10 +1,19 @@ + class Solution: - def removeDuplicateLetters(self, s): + # 定义一个类来解决移除重复字符的问题 + + def removeDuplicateLetters(self, s: str) -> str: + # 创建一个字典,记录每个字符最后出现的位置 rindex = {c: i for i, c in enumerate(s)} + result = '' + # 遍历字符串中的每一个字符 for i, c in enumerate(s): if c not in result: - while c < result[-1:] and i < rindex[result[-1]]: + # 如果当前字符不在结果中,则需要判断是否可以加入结果中 + while result and c < result[-1] and i < rindex[result[-1]]: result = result[:-1] + # 将符合条件的字符添加到结果中 result += c - return result \ No newline at end of file + # 返回最终的结果 + return result diff --git a/solutions/python3/317.py b/solutions/python3/317.py index 42a9559..8b9f8c8 100644 --- a/solutions/python3/317.py +++ b/solutions/python3/317.py @@ -1,11 +1,27 @@ + class Solution: def shortestDistance(self, grid: List[List[int]]) -> int: + """ + 初始化网格的行数和列数,以及起始步长d。 + 使用defaultdict存储每个空地被哪些源点可达及其累积距离。 + 找到所有源点(值为1的位置)并初始化队列bfs。 + 总共有total个源点,res用于存储最短距离结果列表。 + """ m, n, d = len(grid), len(grid[0]), 1 piled = collections.defaultdict(set) dist = collections.defaultdict(int) + bfs = [(i, j, i, j) for i in range(m) for j in range(n) if grid[i][j] == 1] total, res = len(bfs), [] + while bfs: + """ + 每次遍历,记录新的bfs队列new。 + 对于当前层的所有点(x, y),检查其四个方向上的邻点(ii, jj): + - 如果是有效空地且未被当前源点访问过,则标记此访问并更新距离; + - 当该空地被所有源点可达时,将其距离加入结果列表。 + 更新bfs为new,并增加步长d。 + """ new = [] for x, y, i, j in bfs: for ii, jj in ((i + 1, j), (i - 1, j), (i, j + 1), (i, j - 1)): @@ -17,4 +33,8 @@ def shortestDistance(self, grid: List[List[int]]) -> int: new.append((x, y, ii, jj)) bfs = new d += 1 - return min(res) if res else -1 \ No newline at end of file + + """ + 返回最短距离,若无有效结果则返回-1。 + """ + return min(res) if res else -1 diff --git a/solutions/python3/318.py b/solutions/python3/318.py index d4e3702..347e0ba 100644 --- a/solutions/python3/318.py +++ b/solutions/python3/318.py @@ -1,11 +1,21 @@ + class Solution: + # 定义一个解决方案类,包含求解最大乘积的方法 + def maxProduct(self, words): + # 初始化字典和最大乘积变量 sets, mx = {w: set(w) for w in words}, 0 - words.sort(key = len, reverse = True) + # 按单词长度降序排序 + words.sort(key=len, reverse=True) + + # 双重循环遍历所有可能的单词对组合 for i in range(len(words) - 1): for j in range(i + 1, len(words)): + # 如果当前两词长度乘积小于等于最大乘积,跳出内层循环 if len(words[i]) * len(words[j]) <= mx: break + # 判断两个单词是否无交集字符 elif not sets[words[i]] & sets[words[j]]: + # 更新最大乘积 mx = len(words[i]) * len(words[j]) - return mx \ No newline at end of file + return mx # 返回最大乘积 diff --git a/solutions/python3/319.py b/solutions/python3/319.py index 026768c..f3af966 100644 --- a/solutions/python3/319.py +++ b/solutions/python3/319.py @@ -1,3 +1,9 @@ + class Solution: - def bulbSwitch(self, n): - return int(n ** 0.5) \ No newline at end of file + # 返回从1到n中亮着的灯的数量 + # English: Return the number of bulbs that are on from 1 to n + + def bulbSwitch(self, n: int) -> int: + # 计算小于等于n的最大整数平方根,即为最终亮着的灯的数量 + # English: Calculate the integer square root of n, which is the final number of bulbs that remain on. + return int(n ** 0.5) diff --git a/solutions/python3/32.py b/solutions/python3/32.py index 3e099fc..61c86a4 100644 --- a/solutions/python3/32.py +++ b/solutions/python3/32.py @@ -1,9 +1,24 @@ + class Solution: def longestValidParentheses(self, s): + """ + :param s: 输入字符串,包含括号 '()'。 + :return: 返回最长有效括号序列的长度。 + + 使用栈来存储索引,遍历字符串时遇到左括号入栈,右括号匹配成功出栈;否则将当前索引入栈。最后通过计算相邻索引差值获取最大有效括号长度。 + """ stack, mx = [], 0 for i, c in enumerate(s): - if c == ")" and stack and s[stack[-1]] == "(": stack.pop() - else: stack.append(i) + if c == ")" and stack and s[stack[-1]] == "(": # 右括号匹配成功,出栈 + stack.pop() + else: # 入栈当前索引或左括号 + stack.append(i) + + # 在栈中添加哨兵节点 -1 和字符串长度 len(s),方便后续计算间隔 stack = [-1] + stack + [len(s)] - for i1, i2 in zip(stack, stack[1:]): mx = max(mx, i2 - i1 - 1) - return mx if len(stack) > 2 else len(s) \ No newline at end of file + + # 计算相邻索引差值,更新最大有效括号序列的长度 mx + for i1, i2 in zip(stack, stack[1:]): + mx = max(mx, i2 - i1 - 1) + + return mx if len(stack) > 2 else len(s) diff --git a/solutions/python3/320.py b/solutions/python3/320.py index f193d3a..b7789b9 100644 --- a/solutions/python3/320.py +++ b/solutions/python3/320.py @@ -1,13 +1,20 @@ + class Solution: - def generateAbbreviations(self, word): - l, res = len(word), [] - def dfs(s, i): + # Python 解决方案类 + + def generateAbbreviations(self, word: str) -> List[str]: + # 给定单词生成所有可能的缩写形式 + l, res = len(word), [] # 记录单词长度,初始化结果列表 + + def dfs(s: str, i: int): + # 深度优先搜索函数,s是当前构建的字符串,i是当前处理到的位置索引 if i == l: - res.append(s) + res.append(s) # 到达单词末尾,将当前构造的结果加入结果列表中 else: - dfs(s + word[i], i + 1) - if not s or s[-1] > "9": + dfs(s + word[i], i + 1) # 继续处理下一个字符 + if not s or s[-1] > "9": # 当前构建字符串为空或最后一个字符不是数字时 for j in range(i + 1, l + 1): - dfs(s + str(j - i), j) - dfs("", 0) - return res \ No newline at end of file + dfs(s + str(j - i), j) # 尝试将字符数加入结果中 + + dfs("", 0) # 初始调用深度优先搜索,空字符串从索引0开始 + return res # 返回所有可能的缩写形式 diff --git a/solutions/python3/321.py b/solutions/python3/321.py index 04d8c48..3faa0a5 100644 --- a/solutions/python3/321.py +++ b/solutions/python3/321.py @@ -1,30 +1,47 @@ + class Solution: - def maxNumber(self, nums1, nums2, k): - def merge(arr1, arr2): - res, i, j = [], 0, 0 - while i < len(arr1) and j < len(arr2): - if arr1[i:] >= arr2[j:]: - res.append(arr1[i]) - i += 1 - else: - res.append(arr2[j]) - j += 1 - if i < len(arr1): res += arr1[i:] - elif j < len(arr2): res += arr2[j:] - return res + # 定义一个方法来合并两个数组,返回一个新的最大数数组 + def merge(self, arr1, arr2): + # 初始化结果列表和指针 + res, i, j = [], 0, 0 + + # 当两个子数组都有剩余元素时循环 + while i < len(arr1) and j < len(arr2): + # 比较剩余部分的大小,将较大的数加入结果中 + if arr1[i:] >= arr2[j:]: + res.append(arr1[i]) + i += 1 + else: + res.append(arr2[j]) + j += 1 - def makeArr(arr, l): - i, res = 0, [] - for r in range(l - 1, -1, -1): - num, i = max(arr[i:-r] or arr[i:]) - i = -i + 1 - res.append(num) - return res + # 将未处理完的子数组剩余部分添加到结果列表 + if i < len(arr1): res += arr1[i:] + elif j < len(arr2): res += arr2[j:] + return res + + # 定义一个方法来构造最大数数组 + def makeArr(self, arr, l): + i, res = 0, [] + for r in range(l - 1, -1, -1): + num, i = max(arr[i:-r] or arr[i:]) + i = -i + 1 + res.append(num) + return res + + # 主方法,寻找两个数组合并后的最大k长度子数组 + def maxNumber(self, nums1, nums2, k): + # 将原始数组转换为包含索引的元组列表,并反转排序 nums1, nums2, choices = [(num, -i) for i, num in enumerate(nums1)], [(num, -i) for i, num in enumerate(nums2)], [] + + # 遍历所有可能的选择组合 for m in range(k + 1): if m > len(nums1) or k - m > len(nums2): continue - arr1, arr2 = makeArr(nums1, m), makeArr(nums2, k - m) - choices.append(merge(arr1, arr2)) + + # 构造两个数组并合并它们 + arr1, arr2 = self.makeArr(nums1, m), self.makeArr(nums2, k - m) + choices.append(self.merge(arr1, arr2)) + + # 返回所有组合中的最大值 return max(choices) - \ No newline at end of file diff --git a/solutions/python3/322.py b/solutions/python3/322.py index ebebc91..f4fadb1 100644 --- a/solutions/python3/322.py +++ b/solutions/python3/322.py @@ -1,10 +1,20 @@ + class Solution: - def coinChange(self, coins, amount): + # 定义一个求硬币组合问题的方法,输入为可选硬币列表和目标金额 + def coinChange(self, coins: List[int], amount: int) -> int: """ - :type coins: List[int] - :type amount: int - :rtype: int + :type coins: List[int] # 硬币面值列表 + :type amount: int # 目标金额 + :rtype: int # 返回最少硬币数量或-1(表示无法构成目标金额) """ + + # 初始化动态规划表,dp[i] 表示凑成 i 元所需的最小硬币数,默认为正无穷大 dp = [0] + [float('inf')] * amount - for i in range(1, amount + 1): dp[i] = min([dp[i - c] if i - c >= 0 else float('inf') for c in coins]) + 1 - return dp[amount] if dp[amount] != float('inf') else -1 \ No newline at end of file + + # 遍历从 1 到目标金额的每种可能值 + for i in range(1, amount + 1): + # 尝试使用不同面值硬币凑成当前金额,选择最小的硬币数 + dp[i] = min([dp[i - c] if i - c >= 0 else float('inf') for c in coins]) + 1 + + # 如果最终结果仍为正无穷大,则表示无法构成目标金额;否则返回所需最少硬币数量 + return dp[amount] if dp[amount] != float('inf') else -1 diff --git a/solutions/python3/323.py b/solutions/python3/323.py index dbe227e..6447613 100644 --- a/solutions/python3/323.py +++ b/solutions/python3/323.py @@ -1,16 +1,27 @@ + class Solution: - def countComponents(self, n, edges): + # 定义一个类用于求解图的连通分量数量 + + def countComponents(self, n: int, edges: List[Tuple[int, int]]) -> int: + # 初始化已访问集合、结果计数器和邻接表 visited, res, adj = set(), 0, collections.defaultdict(set) + + # 构建图的邻接表表示 for a, b in edges: adj[a].add(b) adj[b].add(a) + + # 深度优先搜索函数,用于遍历连通分量 def dfs(i): visited.add(i) for v in adj[i]: if v not in visited: dfs(v) + + # 遍历所有节点,统计连通分量数量 for i in range(n): if i not in visited: res += 1 dfs(i) - return res \ No newline at end of file + + return res diff --git a/solutions/python3/324.py b/solutions/python3/324.py index ddc1eb7..b2669f6 100644 --- a/solutions/python3/324.py +++ b/solutions/python3/324.py @@ -1,11 +1,18 @@ + class Solution: def wiggleSort(self, nums: List[int]) -> None: """ - Do not return anything, modify nums in-place instead. + 不返回任何内容,而是就地修改nums。 """ + + # 将数组中的元素取负值,并构建最小堆 heap = [-num for num in nums] heapq.heapify(heap) + + # 交替填充奇数索引位置(1, 3, 5...),从堆顶弹出最大值 for i in range(1, len(nums), 2): nums[i] = -heapq.heappop(heap) + + # 交替填充偶数索引位置(0, 2, 4...),从堆顶弹出最大值 for i in range(0, len(nums), 2): - nums[i] = -heapq.heappop(heap) \ No newline at end of file + nums[i] = -heapq.heappop(heap) diff --git a/solutions/python3/325.py b/solutions/python3/325.py index 32d21c9..22047d8 100644 --- a/solutions/python3/325.py +++ b/solutions/python3/325.py @@ -1,11 +1,23 @@ + class Solution: - def maxSubArrayLen(self, nums, k): - index, l, sm = {}, 0, 0 + # 定义一个类来解决最大子数组长度问题 + + def maxSubArrayLen(self, nums: list[int], k: int) -> int: + # 初始化索引字典、当前和以及结果长度 + index, sm, l = {}, 0, 0 + # 将初始和为0的索引设为-1 index[0] = -1 + for i, num in enumerate(nums): + # 累加当前元素值到总和 sm += num - if sm - k in index: - l = max(l, i - index[sm - k]) + + # 如果当前和减去k在字典中存在,更新最大长度 + if (sm_k := sm - k) in index: + l = max(l, i - index[sm_k]) + + # 将当前和对应的索引加入字典(避免重复计算) if sm not in index: index[sm] = i - return l \ No newline at end of file + + return l # 返回最大子数组长度 diff --git a/solutions/python3/326.py b/solutions/python3/326.py index d6497ae..026449e 100644 --- a/solutions/python3/326.py +++ b/solutions/python3/326.py @@ -1,6 +1,10 @@ + class Solution: + # 判断一个数是否是3的幂次方 def isPowerOfThree(self, n: int) -> bool: i = 1 + # 使用循环计算3的幂次,直到i >= n while i < n: - i *=3 - return i == n \ No newline at end of file + i *= 3 + # 检查最终结果是否等于n + return i == n diff --git a/solutions/python3/327.py b/solutions/python3/327.py index 9352c0a..85a1fe3 100644 --- a/solutions/python3/327.py +++ b/solutions/python3/327.py @@ -1,8 +1,41 @@ + class Solution: + # 定义一个类来解决计数区间和问题 + def countRangeSum(self, nums, lower, upper): + """ + 计算数组中满足特定条件的子数组数量。 + + 参数: + nums (List[int]): 输入整数列表。 + lower (int): 区间下限。 + upper (int): 区间上限。 + + 返回: + int: 满足条件的子数组数量。 + """ + sums, sm, res = [0], 0, 0 + # 初始化前缀和列表、当前累积和sm以及结果计数器res + for num in nums: - sm += num + sm += num # 更新当前累积和 + # 计算满足条件的子数组数量,使用二分查找加速计算过程 + res += bisect.bisect_right(sums, sm - lower) - bisect.bisect_left(sums, sm - upper) + + bisect.insort(sums, sm) # 插入新的累积和到前缀和列表中保持有序 + return res # 返回满足条件的子数组数量 + + + + +class Solution: + def countRangeSum(self, nums, lower, upper): + + sums, sm, res = [0], 0, 0 + + for num in nums: + sm += num res += bisect.bisect_right(sums, sm - lower) - bisect.bisect_left(sums, sm - upper) bisect.insort(sums, sm) - return res \ No newline at end of file + return res diff --git a/solutions/python3/328.py b/solutions/python3/328.py index 6491270..19751ac 100644 --- a/solutions/python3/328.py +++ b/solutions/python3/328.py @@ -1,21 +1,24 @@ + # Definition for singly-linked list. -# class ListNode: -# def __init__(self, x): -# self.val = x -# self.next = None +class ListNode: + def __init__(self, x): + self.val = x + self.next = None class Solution: - def oddEvenList(self, head): - """ - :type head: ListNode - :rtype: ListNode - """ - root, i, last, first = head, 1, None, None - if head and head.next: first = head.next + # 处理单链表,将奇数位置节点和偶数位置节点分离 + def oddEvenList(self, head: 'ListNode') -> 'ListNode': + root, i, last, first = head, 1, None, None # 初始化指针和计数器 + if head and head.next: first = head.next # 获取第一个偶数节点 + while head: - latter = head.next - if i%2 != 0: last = head - if head.next: head.next = head.next.next - head, i = latter, i+1 - if last: last.next = first - return root \ No newline at end of file + latter = head.next # 当前节点的后继节点 + if i % 2 != 0: last = head # 奇数位置节点连接到last指针上 + + if head.next: head.next = head.next.next # 跳过一个偶数节点 + + head, i = latter, i + 1 # 更新当前节点和计数器 + + if last: last.next = first # 将奇数位置节点与偶数位置节点相连 + + return root # 返回重组后的链表头 diff --git a/solutions/python3/329.py b/solutions/python3/329.py index 336add1..e8f1ab9 100644 --- a/solutions/python3/329.py +++ b/solutions/python3/329.py @@ -1,9 +1,23 @@ + class Solution: + # 定义解决方案类 + def longestIncreasingPath(self, matrix): + # 计算给定矩阵中的最长递增路径长度 + def dfs(i, j): + # 深度优先搜索,计算从(i,j)位置开始的最长递增路径长度 if not dp[i][j]: - dp[i][j] = 1+max((dfs(x,y) for x,y in ((i-1,j),(i+1,j),(i,j-1),(i,j+1)) if 0 <=x matrix[i][j]),default=0) + # 如果dp[i][j]未被初始化,则进行计算 + dp[i][j] = 1 + max( + (dfs(x, y) for x, y in ((i-1, j), (i+1, j), (i, j-1), (i, j+1)) + if 0 <= x < m and 0 <= y < n and matrix[x][y] > matrix[i][j]), + default=0 + ) return dp[i][j] - m, n, = len(matrix), len(matrix and matrix[0]) + # 初始化矩阵的行数m和列数n + m, n = len(matrix), len(matrix[0]) + # 初始化dp数组,用于存储每个位置的最大递增路径长度 dp = [[0] * n for _ in range(m)] - return max((dfs(i,j) for i in range(m) for j in range(n)),default=0) \ No newline at end of file + # 返回整个矩阵中所有起点的最长递增路径中的最大值 + return max((dfs(i, j) for i in range(m) for j in range(n)), default=0) diff --git a/solutions/python3/33.py b/solutions/python3/33.py index 84aa96f..d533631 100644 --- a/solutions/python3/33.py +++ b/solutions/python3/33.py @@ -1,12 +1,29 @@ + class Solution: + # 中文:初始化二分查找的左右指针,分别指向列表的第一个元素和最后一个元素。 + # English: Initialize the left and right pointers for binary search, pointing to the first and last elements of the list. + def search(self, nums, target): l, r = 0, len(nums) - 1 + # 中文:当左指针小于等于右指针时,继续查找。 + # English: Continue searching while the left pointer is less than or equal to the right pointer. + while l <= r: mid = (l + r) // 2 + # 中文:如果中间元素等于目标值,则返回中间索引。 + # English: If the middle element equals the target, return the middle index. + if nums[mid] == target: return mid - elif sum((target < nums[l], nums[l] <= nums[mid], nums[mid] < target)) == 2: - l = mid + 1 - else: - r = mid - 1 - return -1 \ No newline at end of file + else: + # 中文:判断目标值与左右边界的关系,调整搜索范围 + # English: Determine the relationship between the target value and the boundaries to adjust the search range + + if (target < nums[l], nums[l] <= nums[mid], nums[mid] < target).count(True) == 2: + l = mid + 1 + else: + r = mid - 1 + # 中文:若未找到目标值,返回-1。 + # English: If the target is not found, return -1. + + return -1 diff --git a/solutions/python3/330.py b/solutions/python3/330.py index 26582e2..e13a7f3 100644 --- a/solutions/python3/330.py +++ b/solutions/python3/330.py @@ -1,11 +1,23 @@ + class Solution: def minPatches(self, nums, n): + """ + :param nums: List[int] - 可选补丁数组 + :param n: int - 目标最大值 + :return: int - 最小需要添加的补丁数量 + """ + miss, added, i = 1, 0, 0 + + # 当缺失值小于等于目标值时,继续循环 while miss <= n: if i < len(nums) and nums[i] <= miss: + # 如果当前数字可以覆盖到miss,则更新miss,并移动索引i miss += nums[i] i += 1 else: + # 否则将miss加倍,表示需要添加一个补丁来覆盖该范围 miss *= 2 added += 1 - return added \ No newline at end of file + + return added diff --git a/solutions/python3/331.py b/solutions/python3/331.py index e97908b..bde9085 100644 --- a/solutions/python3/331.py +++ b/solutions/python3/331.py @@ -1,12 +1,31 @@ + class Solution: def isValidSerialization(self, preorder: str) -> bool: + """ + 判断给定的前序序列是否可以构成一棵有效的二叉树 + + :param preorder: 字符串形式的前序遍历序列,节点间用逗号分隔 + :return: 如果该前序序列能构成有效二叉树,则返回 True;否则返回 False + """ stack = [] + for c in preorder.split(','): + # 将当前字符压入栈中 stack.append(c) - while stack[-2:] == ['#', '#']: + + # 当栈顶两个元素为 '#' 时,进行处理 + while len(stack) > 1 and stack[-2:] == ['#', '#']: + # 弹出栈顶的两个 '#' stack.pop() stack.pop() - if not stack: return False + + # 如果此时栈为空,则当前序列无法构成有效二叉树 + if not stack: + return False + + # 弹出下一个元素,并压入一个 '#' 表示已处理该节点的子树 stack.pop() stack.append('#') - return stack == ['#'] \ No newline at end of file + + # 最终检查栈是否只包含一个 '#',则说明可构成有效二叉树 + return stack == ['#'] diff --git a/solutions/python3/332.py b/solutions/python3/332.py index bd9618b..28f6d5e 100644 --- a/solutions/python3/332.py +++ b/solutions/python3/332.py @@ -1,8 +1,18 @@ + class Solution: def findItinerary(self, tickets): + # 初始化图、栈和已到达路径 graph, stack, reached = collections.defaultdict(list), ["JFK"], [] - for a, b in tickets: heapq.heappush(graph[a], b) + + # 将航班信息按起点排序并加入图中 + for a, b in tickets: + heapq.heappush(graph[a], b) + + # 使用深度优先搜索遍历路径 while stack: - if graph[stack[-1]]: stack.append(heapq.heappop(graph[stack[-1]])) - else: reached.append(stack.pop()) - return reached[::-1] \ No newline at end of file + if graph[stack[-1]]: # 如果当前节点还有未访问的邻接点 + stack.append(heapq.heappop(graph[stack[-1]])) # 推入下一个目的地 + else: # 当前节点所有邻接点都已访问完,加入已到达路径 + reached.append(stack.pop()) + + return reached[::-1] # 反转路径以获得正确的飞行顺序 diff --git a/solutions/python3/333.py b/solutions/python3/333.py index 05379cc..d65c3f1 100644 --- a/solutions/python3/333.py +++ b/solutions/python3/333.py @@ -1,14 +1,41 @@ + class Solution: def largestBSTSubtree(self, root): + """ + 寻找二叉树中最大的BST子树的大小 + + @param root: 二叉树的根节点 + """ + def dfs(node): + """ + 深度优先搜索,递归判断以当前节点为根的最大BST子树信息 + + @param node: 当前处理的节点 + @return: 元组 (是否是BST, 节点数量, 最大值, 最小值, 大BST子树的大小) + """ if not node: + # 空节点,视为BST,且节点数为0 return True, 0, None, None, 0 - lBool, lSize, lMx, lMn, lTree = dfs(node.left) - rBool, rSize, rMx, rMn, rTree = dfs(node.right) - lVal = lMx if lMx != None else -float("inf") - rVal = rMn if rMn != None else float("inf") - curMx = max(val for val in (lMx, rMx, node.val) if val != None) - curMn = min(val for val in (lMn, rMn, node.val) if val != None) - curBool = lBool and rBool and lVal < node.val < rVal - return curBool, lSize + rSize + 1, curMx, curMn, curBool and lSize + rSize + 1 or max(lTree, rTree) - return dfs(root)[4] \ No newline at end of file + + lBool, lSize, lMx, lMn, lTree = dfs(node.left) # 左子树信息 + rBool, rSize, rMx, rMn, rTree = dfs(node.right) # 右子树信息 + + lVal = lMx if lMx is not None else -float("inf") # 左子树的最大值 + rVal = rMn if rMn is not None else float("inf") # 右子树的最小值 + + curMx = max(val for val in (lMx, rMx, node.val) if val is not None) # 当前节点的最大值 + curMn = min(val for val in (lMn, rMn, node.val) if val is not None) # 当前节点的最小值 + + curBool = lBool and rBool and lVal < node.val < rVal # 判断当前子树是否为BST + # 返回元组: 是否是BST,节点总数,当前最大值,当前最小值,当前子树中的最大BST大小 + return ( + curBool, + lSize + rSize + 1, + curMx, + curMn, + curBool and (lSize + rSize + 1) or max(lTree, rTree) + ) + + # 返回根节点的最大BST子树的大小 + return dfs(root)[4] diff --git a/solutions/python3/334.py b/solutions/python3/334.py index e752514..bc18e2c 100644 --- a/solutions/python3/334.py +++ b/solutions/python3/334.py @@ -1,17 +1,21 @@ + class Solution: + # 检查是否存在一个严格递增的三元组 def increasingTriplet(self, nums): - mn = None + mn = None # 初始化最小值为None for i in range(len(nums)): - if mn == None or nums[i] < mn: + if mn is None or nums[i] < mn: mn = nums[i] - if mn < nums[i]: - nums[i] = [True, nums[i]] - else: - nums[i] = [False, nums[i]] - mn = None + # 更新nums数组,包含是否是严格递增的标志和当前元素值 + nums[i] = [False, nums[i]] if mn >= nums[i] else [True, nums[i]] + + mn = None # 清空最小值变量 for i in range(len(nums)): - if nums[i][0] and (mn == None or nums[i][1] < mn): + # 如果当前元素是严格递增且小于已记录的最小值,更新最小值 + if nums[i][0] and (mn is None or nums[i][1] < mn): mn = nums[i][1] - elif mn != None and mn < nums[i][1]: + # 检查是否存在一个严格递增的三元组 + elif mn is not None and mn < nums[i][1]: return True - return False \ No newline at end of file + + return False # 如果没有找到,返回False diff --git a/solutions/python3/335.py b/solutions/python3/335.py index 3109a57..3bc39bd 100644 --- a/solutions/python3/335.py +++ b/solutions/python3/335.py @@ -1,8 +1,20 @@ + class Solution: def isSelfCrossing(self, x: List[int]) -> bool: + """ + 判断路径是否会自相交 + + 参数: + x (List[int]): 路径的长度列表 + + 返回: + bool: 如果路径会自相交返回True,否则返回False + """ b = c = d = e = 0 for a in x: - if d >= b > 0 and (a >= c or a >= c-e >= 0 and f >= d-b): + # 判断当前段是否会与前一段发生交叉 + if d >= b > 0 and (a >= c or a >= c - e >= 0 and f >= d - b): return True + # 更新变量 b, c, d, e, f = a, b, c, d, e - return False \ No newline at end of file + return False diff --git a/solutions/python3/336.py b/solutions/python3/336.py index 5e5f8b3..2bab0cd 100644 --- a/solutions/python3/336.py +++ b/solutions/python3/336.py @@ -1,15 +1,36 @@ + class Solution: def palindromePairs(self, words): + """ + 中文注释:构建一个映射,将单词及其索引对应起来。 + 英文注释: Build a mapping to associate each word with its index. + """ index, res = {w:i for i, w in enumerate(words)}, [] + + """ + 中文注释:遍历每个单词,并将其拆分为前后两部分,检查前半部分是否为回文。 + 英文注释: Iterate over each word and split it into two parts. Check if the first part is a palindrome. + """ for i, w in enumerate(words): for j in range(len(w) + 1): pre, suf = w[:j], w[j:] + + """ + 中文注释:如果前半部分是回文,反转后半部分并检查是否在字典中且不等于原单词。 + 英文注释: If the first part is a palindrome, reverse the second part and check if it exists in the dictionary and is not equal to the original word. + """ if pre == pre[::-1]: suf = suf[::-1] if suf != w and suf in index: res.append([index[suf], i]) + + """ + 中文注释:检查后半部分是否为回文,如果不是开头部分,则反转前半部分并检查是否在字典中。 + 英文注释: Check if the second part is a palindrome, and if not the first part, reverse the first part and check if it exists in the dictionary. + """ if j != len(w) and suf == suf[::-1]: pre = pre[::-1] if pre != w and pre in index: res.append([i, index[pre]]) - return res \ No newline at end of file + + return res diff --git a/solutions/python3/337.py b/solutions/python3/337.py index 4c74c0d..8a0a0eb 100644 --- a/solutions/python3/337.py +++ b/solutions/python3/337.py @@ -1,7 +1,22 @@ + class Solution: + # 定义一个解决方案类 + def rob(self, root): + # 给定一棵二叉树,实现打家劫舍II:不能同时从两个相邻节点偷窃。 + def dfs(node): - if not node: return 0, 0 - l, r = dfs(node.left), dfs(node.right) - return max(l) + max(r), node.val + l[0] + r[0] - return max(dfs(root)) \ No newline at end of file + if not node: + return 0, 0 # 如果当前节点为空,则返回两个0 + l, r = dfs(node.left), dfs(node.right) # 递归处理左子树和右子树 + + # 不偷当前节点的最大值 + no_steal = max(l) + max(r) + + # 偷当前节点的总收益,等于左右子树分别不偷的最大值之和加上当前节点的价值 + steal = node.val + l[0] + r[0] + + return no_steal, steal # 返回两个结果:不偷当前节点的最大值 和 偷当前节点的总收益 + + # 最终答案是从dfs(root)返回的结果中取最大值 + return max(dfs(root)) diff --git a/solutions/python3/338.py b/solutions/python3/338.py index 171208b..7b112af 100644 --- a/solutions/python3/338.py +++ b/solutions/python3/338.py @@ -1,3 +1,5 @@ + class Solution: + # 计算0到num之间每个数的二进制表示中1的个数 def countBits(self, num: int) -> List[int]: - return [bin(i)[2:].count('1') for i in range(num + 1)] \ No newline at end of file + return [bin(i)[2:].count('1') for i in range(num + 1)] diff --git a/solutions/python3/339.py b/solutions/python3/339.py index 64f084e..e140709 100644 --- a/solutions/python3/339.py +++ b/solutions/python3/339.py @@ -1,3 +1,4 @@ + # """ # This is the interface that allows for creating nested lists. # You should not implement it, or speculate about its implementation @@ -42,7 +43,11 @@ # """ class Solution: + # 计算嵌套列表的深度总和 def depthSum(self, nestedList): - def dfs(obj, d): return obj.getInteger() * d if obj.isInteger() else sum(dfs(new, d + 1) for new in obj.getList()) + # 深度优先搜索辅助函数,计算当前元素在给定深度下的贡献值 + def dfs(obj, d): + return obj.getInteger() * d if obj.isInteger() else sum(dfs(new, d + 1) for new in obj.getList()) + + # 计算整个嵌套列表的总和 return sum(dfs(item, 1) for item in nestedList) - \ No newline at end of file diff --git a/solutions/python3/34.py b/solutions/python3/34.py index 79e66d5..a2aa00c 100644 --- a/solutions/python3/34.py +++ b/solutions/python3/34.py @@ -1,4 +1,13 @@ + class Solution(object): + # 搜索目标值target在有序数组nums中的起始和结束位置 + def searchRange(self, nums, target): - l, r = bisect.bisect_left(nums, target), bisect.bisect_right(nums, target) - 1 - return [l, r] if 0 <= l <= r else [-1, -1] \ No newline at end of file + # 使用二分查找确定左边界 + l = bisect.bisect_left(nums, target) + + # 使用二分查找确定右边界,注意需要减1以获取正确的索引 + r = bisect.bisect_right(nums, target) - 1 + + # 检查左右边界是否有效 + return [l, r] if 0 <= l <= r else [-1, -1] diff --git a/solutions/python3/340.py b/solutions/python3/340.py index 42196c9..5fd5059 100644 --- a/solutions/python3/340.py +++ b/solutions/python3/340.py @@ -1,15 +1,27 @@ + class Solution: def lengthOfLongestSubstringKDistinct(self, s: str, k: int) -> int: - if not k: + """ + 获取最长不含重复字符的子字符串长度,最多包含k个不同字符。 + + :param s: 输入字符串 + :param k: 最多允许的不同字符数 + :return: 符合条件的最大子串长度 + """ + if not k: # 如果k为0,直接返回0 return 0 - cnt = collections.Counter() - i = res = 0 - for j, c in enumerate(s): - while len(cnt) == k and c not in cnt: - cnt[s[i]] -= 1 + + cnt = collections.Counter() # 使用Counter统计滑动窗口内的字符数量 + i = res = 0 # 初始化左指针i和结果res + + for j, c in enumerate(s): # 遍历字符串s的每个字符c,其索引为j + while len(cnt) == k and c not in cnt: # 当当前窗口内的不同字符数达到k且新加入的字符不在窗口内时 + cnt[s[i]] -= 1 # 减少左指针指向字符的计数值 if cnt[s[i]] == 0: - cnt.pop(s[i]) - i += 1 - cnt[c] += 1 - res = max(res, j - i + 1) - return res \ No newline at end of file + cnt.pop(s[i]) # 如果该字符数量为0,从Counter中移除 + i += 1 # 移动左指针i + + cnt[c] += 1 # 增加当前字符c的计数值 + res = max(res, j - i + 1) # 更新最大长度 + + return res # 返回结果res diff --git a/solutions/python3/342.py b/solutions/python3/342.py index 11901ba..c24dff2 100644 --- a/solutions/python3/342.py +++ b/solutions/python3/342.py @@ -1,9 +1,15 @@ + class Solution: + # 判断给定整数是否是4的幂 def isPowerOfFour(self, num: int) -> bool: + # 如果数字小于0,直接返回False if num < 0: return False - i = 1 + + i = 1 # 初始化i为1,因为4的幂至少从1开始 while i < num: - i = i * 4 + # 将i乘以4,在循环中逐步增加i的值 + i *= 4 + + # 如果最终i等于num,则说明num是4的幂 return i == num - \ No newline at end of file diff --git a/solutions/python3/343.py b/solutions/python3/343.py index 99ed253..a3481e0 100644 --- a/solutions/python3/343.py +++ b/solutions/python3/343.py @@ -1,8 +1,19 @@ + class Solution: - def integerBreak(self, n): + # 定义一个整数分割问题的解决方案类 + + def integerBreak(self, n: int) -> int: + # 初始化一个列表pre,用于存储n小于7时的结果 pre = [0, 1, 1, 2, 4, 6, 9] + if n < 7: + # 如果输入的整数n小于7,直接返回预计算的结果 return pre[n] + for i in range(7, n + 1): + # 对于大于等于7的n值,通过动态规划的方式填充列表pre pre.append(max(pre[i - 2] * 2, pre[i - 3] * 3)) - return pre[-1] \ No newline at end of file + + # 返回最终的结果 + return pre[-1] + \ No newline at end of file diff --git a/solutions/python3/344.py b/solutions/python3/344.py index c1859bb..70ecdf5 100644 --- a/solutions/python3/344.py +++ b/solutions/python3/344.py @@ -1,7 +1,11 @@ + class Solution: + # 不返回任何内容,原地修改字符串列表s def reverseString(self, s: List[str]) -> None: """ Do not return anything, modify s in-place instead. """ + # 遍历列表前半部分 for i in range(len(s) // 2): - s[i], s[-i-1] = s[-i-1], s[i] \ No newline at end of file + # 交换位置i和对应的末尾元素-i-1 + s[i], s[-i-1] = s[-i-1], s[i] diff --git a/solutions/python3/345.py b/solutions/python3/345.py index eb5deb2..b3017fd 100644 --- a/solutions/python3/345.py +++ b/solutions/python3/345.py @@ -1,4 +1,10 @@ + class Solution: + # 定义一个方法 reverseVowels,用于翻转字符串中的元音字母顺序 + def reverseVowels(self, s): + # 创建包含所有元音的列表 r = [c for c in s if c in "aeiouAEIOU"] - return "".join(c in "aeiouAEIOU" and r.pop() or c for c in s) \ No newline at end of file + + # 使用生成器表达式构建新字符串,其中每个元音字符被从列表 r 中弹出并替换原来的非元音字符 + return "".join(c in "aeiouAEIOU" and r.pop() or c for c in s) diff --git a/solutions/python3/346.py b/solutions/python3/346.py index b4fcdf0..8ef472d 100644 --- a/solutions/python3/346.py +++ b/solutions/python3/346.py @@ -1,16 +1,27 @@ + +from collections import deque + class MovingAverage: def __init__(self, size: int): """ - Initialize your data structure here. + 初始化滑动平均值结构体。 + Initialize the moving average structure. + :param size: 滑动窗口的大小 """ - self.arr = collections.deque(maxlen = size) + self.arr = deque(maxlen=size) def next(self, val: int) -> float: + """ + 添加一个新的数值到队列中,并返回当前窗口内的平均值。 + Add a new value to the queue and return the current window's average. + :param val: 新的数值 + :return: 当前滑动窗口内的平均值 + """ self.arr.append(val) return sum(self.arr) / len(self.arr) - - -# Your MovingAverage object will be instantiated and called as such: + + +# 你的 MovingAverage 对象将被实例化并调用如下: # obj = MovingAverage(size) -# param_1 = obj.next(val) \ No newline at end of file +# param_1 = obj.next(val) diff --git a/solutions/python3/347.py b/solutions/python3/347.py index 8b131af..c8cfed3 100644 --- a/solutions/python3/347.py +++ b/solutions/python3/347.py @@ -1,9 +1,12 @@ -class Solution: - def topKFrequent(self, nums, k): - """ - :type nums: List[int] - :type k: int - :rtype: List[int] - """ - from collections import Counter as ct - return [k for (k,v) in ct(nums).most_common(k)] \ No newline at end of file + + class Solution: + def topKFrequent(self, nums, k): + """ + :type nums: List[int] # 输入列表,包含整数 + :type k: int # 需要返回的高频元素个数 + :rtype: List[int] # 返回最频繁出现的k个整数 + """ + from collections import Counter as ct # 引入Counter类用于统计频率 + + return [key for key, value in ct(nums).most_common(k)] # 使用Counter统计nums中每个元素的频率,取前k个高频元素 + \ No newline at end of file diff --git a/solutions/python3/348.py b/solutions/python3/348.py index e304609..2015185 100644 --- a/solutions/python3/348.py +++ b/solutions/python3/348.py @@ -1,21 +1,44 @@ + class TicTacToe: - def __init__(self, n): + def __init__(self, n: int): + """ + 初始化游戏,设定棋盘大小n,并初始化行、列计数器和对角线计数器。 + + :param n: 棋盘的大小 + """ self.n = n + # 使用defaultdict存储每行和每列的得分情况 self.rows, self.cols = collections.defaultdict(int), collections.defaultdict(int) - self.d = self.ad = 0 + # 初始化两个对角线的计数器 + self.d = 0 + self.ad = 0 + + def move(self, row: int, col: int, player: int) -> int: + """ + 执行玩家在指定位置下的棋子,并判断是否有人获胜。 + + :param row: 棋子所在的行 + :param col: 棋子所在的列 + :param player: 玩家标识(1或2) + :return: 返回获胜的玩家编号,若无玩家获胜则返回0 + """ + add = 1 if player == 1 else -1 - def move(self, row, col, player): - add = player == 1 and 1 or -1 + # 更新行和列对应的得分情况 self.rows[row] += add self.cols[col] += add + + # 检查是否在主对角线或副对角线上 if row == col: self.d += add if row == self.n - col - 1: self.ad += add - if self.rows[row] == self.n or self.cols[col] == self.n or self.d == self.n or self.ad == self.n: - return 1 + + # 判断当前操作后是否有人获胜 + if abs(self.rows[row]) == self.n or abs(self.cols[col]) == self.n or abs(self.d) == self.n or abs(self.ad) == self.n: + return player elif self.rows[row] == -self.n or self.cols[col] == -self.n or self.d == -self.n or self.ad == -self.n: - return 2 + return 3 - player # 如果是玩家2获胜,返回1;如果是玩家1获胜,则返回2 else: - return 0 \ No newline at end of file + return 0 diff --git a/solutions/python3/349.py b/solutions/python3/349.py index 52d3bd9..4763cd4 100644 --- a/solutions/python3/349.py +++ b/solutions/python3/349.py @@ -1,8 +1,13 @@ + class Solution: - def intersection(self, nums1, nums2): + # 定义一个名为intersection的方法,用于找出两个整数列表的交集 + def intersection(self, nums1: list[int], nums2: list[int]) -> list[int]: """ - :type nums1: List[int] - :type nums2: List[int] - :rtype: List[int] + :param nums1: 第一个整数列表 + :param nums2: 第二个整数列表 + :return: 两个列表的交集作为整数列表返回 + + 通过将两个列表转换为集合并求交集,然后将结果转换回列表。 + 这种方法利用了集合去重和高效查找特性来提高效率。 """ - return list(set(nums1)&set(nums2)) \ No newline at end of file + return list(set(nums1) & set(nums2)) diff --git a/solutions/python3/35.py b/solutions/python3/35.py index 51fd153..1147170 100644 --- a/solutions/python3/35.py +++ b/solutions/python3/35.py @@ -1,3 +1,7 @@ + class Solution: + # 搜索插入位置 - Search Insert Position + def searchInsert(self, nums: List[int], target: int) -> int: - return bisect.bisect_left(nums, target) \ No newline at end of file + # 使用 bisect_left 方法找到目标值应插入的位置,保持原有序列不变 + return bisect.bisect_left(nums, target) diff --git a/solutions/python3/350.py b/solutions/python3/350.py index e994d03..37203f9 100644 --- a/solutions/python3/350.py +++ b/solutions/python3/350.py @@ -1,2 +1,6 @@ + class Solution: - intersect = lambda *x: [k for k, v in (collections.Counter(x[1]) & collections.Counter(x[2])).items() for _ in range(v)] \ No newline at end of file + # 使用lambda表达式定义交集方法,输入三个可迭代对象,返回它们的交集列表 + intersect = lambda self, nums1, nums2, nums3: [k for k, v in (collections.Counter(nums1) & collections.Counter(nums2)).items() for _ in range(v)] \ + + [k for k, v in (collections.Counter(nums2) & collections.Counter(nums3)).items() for _ in range(v)] \ + + [k for k, v in (collections.Counter(nums1) & collections.Counter(nums3)).items() for _ in range(v)] diff --git a/solutions/python3/351.py b/solutions/python3/351.py index 893a036..abdbd16 100644 --- a/solutions/python3/351.py +++ b/solutions/python3/351.py @@ -1,40 +1,61 @@ + class Solution: - def numberOfPatterns(self, m, n): + # 定义一个解决方案类 + + def numberOfPatterns(self, m: int, n: int) -> int: + # 方法:计算从m到n个数字的模式数量 + + # 初始化起点列表和模式计数器 q, pattern = [[c] for c in range(1, 10)], 0 + while q: + # 开始广度优先搜索 new = [] + for arr in q: - if m <= len(arr) <= n: + if m <= len(arr) <= n: # 如果当前路径长度在给定范围内,则计数器加一 pattern += 1 - if len(arr) < n: - last = arr[-1] + + if len(arr) < n: # 如果当前路径长度小于n,继续扩展 + last = arr[-1] # 获取上一步选择的数字 + for c in range(1, 10): - if c not in arr: + if c not in arr: # 确保新的选择不在已选列表中 + # 根据起点位置的不同,设定不同的跳转规则 if last in (1, 4, 7) and c == last + 2: if last + 1 in arr: new.append(arr + [c]) + elif last in (3, 6, 9) and c == last - 2: if last - 1 in arr: new.append(arr + [c]) + elif last in (1, 2, 3) and c == last + 6: if last + 3 in arr: new.append(arr + [c]) + elif last in (7, 8, 9) and c == last - 6: if last - 3 in arr: new.append(arr + [c]) + elif last == 1 and c == 9: if 5 in arr: new.append(arr + [9]) + elif last == 9 and c == 1: if 5 in arr: new.append(arr + [1]) + elif last == 3 and c == 7: if 5 in arr: new.append(arr + [7]) + elif last == 7 and c == 3: if 5 in arr: new.append(arr + [3]) + else: new.append(arr + [c]) + q = new - return pattern \ No newline at end of file + return pattern diff --git a/solutions/python3/352.py b/solutions/python3/352.py index ebcd0bb..5610150 100644 --- a/solutions/python3/352.py +++ b/solutions/python3/352.py @@ -1,22 +1,44 @@ + class SummaryRanges: def __init__(self): - self.starts, self.ends, self.used = [-float("inf"), float("inf")], [-float("inf"), float("inf")], set() + """ + 初始化数据结构,用于存储区间起始和结束点以及使用过的数字。 + English: Initialize the data structure to store interval starts, ends, and used numbers. + """ + self.starts, self.ends, self.used = [-float("inf"), float("inf")], [-float("inf"), float("inf")], set() + def addNum(self, val): + """ + 添加一个数字到区间中,并更新区间状态。 + + English: Add a number to the intervals and update interval states. + :param val: int - 要添加的数字 + """ if val not in self.used: self.used.add(val) i = bisect.bisect_left(self.starts, val) - 1 - if self.ends[i] + 1 == val and val + 1 == self.starts[i + 1]: # if val is the gap btw 2 intervals + # 如果val正好位于两个区间的间隙处,则合并这两个区间 + if self.ends[i] + 1 == val and val + 1 == self.starts[i + 1]: del self.starts[i + 1] del self.ends[i] - elif self.ends[i] + 1 == val: #if val is adjacent to current end + # 如果val紧邻当前区间的结束点 + elif self.ends[i] + 1 == val: self.ends[i] += 1 - elif self.starts[i + 1] == val + 1: # if val is adjacent to next start + # 如果val紧邻下一个区间的起始点 + elif self.starts[i + 1] == val + 1: self.starts[i + 1] -= 1 - elif val > self.ends[i]: # if val is independent of those 2 intervals - self.starts.insert(i + 1, val) + # 如果val独立于当前区间和下一个区间 + elif val > self.ends[i]: + self.starts.insert(i + 1, val) self.ends.insert(i + 1, val) - + def getIntervals(self): - return [[s, e] for s, e in zip(self.starts[1:-1], self.ends[1:-1])] #exclude infinity \ No newline at end of file + """ + 获取所有有效区间的列表。 + + English: Get the list of all valid intervals. + :return: List[List[int]] - 区间列表 + """ + return [[s, e] for s, e in zip(self.starts[1:-1], self.ends[1:-1])] # exclude infinity diff --git a/solutions/python3/353.py b/solutions/python3/353.py index d398575..5005fa9 100644 --- a/solutions/python3/353.py +++ b/solutions/python3/353.py @@ -1,16 +1,37 @@ + class SnakeGame: - def __init__(self, width, height, food): - self.foods = collections.deque(food) - self.i = self.j = 0 - self.w, self.h = width, height - self.score = 0 - self.snake = collections.OrderedDict() - self.snake[(0, 0)] = 1 + def __init__(self, width: int, height: int, food: list[list[int]]): + """ + 初始化蛇游戏,设置初始宽度、高度和食物位置。 + 参数: + width (int): 场景的宽度 + height (int): 场景的高度 + food (list[list[int]]): 食物的位置列表 + """ + from collections import deque, OrderedDict + + self.foods = deque(food) # 使用deque存储食物位置,便于从头部移除已吃的食物 + self.snake = OrderedDict() # 使用OrderedDict维护蛇的身体,确保插入顺序正确 + self.snake[(0, 0)] = 1 # 初始时蛇的头部在(0, 0)位置 + + self.w, self.h = width, height # 场景宽度和高度 + self.score = 0 # 蛇的得分 + + + def move(self, direction: str) -> int: + """ + 根据给定的方向移动蛇,返回当前得分或-1表示游戏结束。 + + 参数: + direction (str): 移动方向 'U' (上), 'D' (下), 'R' (右), 'L' (左) + + 返回: + int: 当前得分或-1 + """ + x, y = self.snake.popitem(last=False) # 移除并返回蛇头部的位置 - def move(self, direction): - x, y = self.snake.popitem(last = False) if direction == "U": self.i -= 1 elif direction == "D": @@ -19,13 +40,18 @@ def move(self, direction): self.j += 1 else: self.j -= 1 + + # 更新蛇头位置,检查是否吃到食物或撞墙 if 0 <= self.i < self.h and 0 <= self.j < self.w and (self.i, self.j) not in self.snake: self.snake[(self.i, self.j)] = 1 + + # 如果吃到了食物 if self.foods and self.i == self.foods[0][0] and self.j == self.foods[0][1]: - self.score += 1 - self.foods.popleft() - self.snake[(x, y)] = 1 - self.snake.move_to_end((x, y), last = False) + self.score += 1 # 分数加1 + self.foods.popleft() # 移除已吃到的食物 + + # 将蛇头重新加入到snake中,并保持在最前端 + self.snake.move_to_end((x, y), last=False) return self.score else: - return -1 \ No newline at end of file + return -1 # 越界或撞自己,游戏结束返回-1 diff --git a/solutions/python3/354.py b/solutions/python3/354.py index c17427e..28ad034 100644 --- a/solutions/python3/354.py +++ b/solutions/python3/354.py @@ -1,8 +1,19 @@ + class Solution: + # 定义一个类来解决信封嵌套问题 + def maxEnvelopes(self, envelopes): + """ + :param envelopes: List[List[int]], 二维列表表示每个信封的宽和高 + :return: int,可以相互嵌套的最大信封数 + """ + # 对信封按照宽度升序、高度降序排序 tails = [] - for w, h in sorted(envelopes, key = lambda x: (x[0], -x[1])): + for w, h in sorted(envelopes, key=lambda x: (x[0], -x[1])): + # 使用二分查找找到tails中第一个大于等于当前高度的位置i i = bisect.bisect_left(tails, h) - if i == len(tails): tails.append(h) - else: tails[i] = h - return len(tails) \ No newline at end of file + if i == len(tails): # 如果插入位置在尾巴末端,说明找到了一个更长的递增子序列 + tails.append(h) + else: # 否则用当前高度替换tails中对应位置的高度 + tails[i] = h + return len(tails) # 返回最长递增子序列的长度,即最大嵌套信封数 diff --git a/solutions/python3/355.py b/solutions/python3/355.py index 3a09254..92729b8 100644 --- a/solutions/python3/355.py +++ b/solutions/python3/355.py @@ -1,49 +1,59 @@ + +import collections + class Twitter: def __init__(self): """ - Initialize your data structure here. + 初始化数据结构。 """ self.tweets = collections.defaultdict(list) self.following = collections.defaultdict(set) self.order = 0 - def postTweet(self, userId, tweetId): + + def postTweet(self, userId: int, tweetId: int) -> None: """ - Compose a new tweet. + 发布一条新推文。 :type userId: int :type tweetId: int :rtype: void """ - self.tweets[userId] += (self.order, tweetId), + # 将推文添加到用户列表中,并更新顺序值 + self.tweets[userId].append((self.order, tweetId)) self.order -= 1 - def getNewsFeed(self, userId): + def getNewsFeed(self, userId: int) -> list[int]: """ - Retrieve the 10 most recent tweet ids in the user's news feed. Each item in the news feed must be posted by users who the user followed or by the user herself. Tweets must be ordered from most recent to least recent. + 获取用户的最新十条推文。 :type userId: int :rtype: List[int] """ - tw = sorted(tw for i in self.following[userId] | {userId} for tw in self.tweets[i])[:10] - return [news for i, news in tw] - + # 对用户关注的用户和自身发布的推文进行排序 + tweets = sorted( + tweet for follower in self.following[userId] | {userId} + for tweet in self.tweets[follower] + )[:10] + + # 提取推文ID + return [tweet_id for _, tweet_id in tweets] - def follow(self, followerId, followeeId): + def follow(self, followerId: int, followeeId: int) -> None: """ - Follower follows a followee. If the operation is invalid, it should be a no-op. + 粉丝关注一个博主。如果操作无效,则应忽略。 :type followerId: int :type followeeId: int :rtype: void """ self.following[followerId].add(followeeId) - def unfollow(self, followerId, followeeId): + def unfollow(self, followerId: int, followeeId: int) -> None: """ - Follower unfollows a followee. If the operation is invalid, it should be a no-op. + 粉丝取消关注一个博主。如果操作无效,则应忽略。 :type followerId: int :type followeeId: int :rtype: void """ - self.following[followerId].discard(followeeId) + self.following[followerId].discard(followeeId) # Your Twitter object will be instantiated and called as such: @@ -51,4 +61,4 @@ def unfollow(self, followerId, followeeId): # obj.postTweet(userId,tweetId) # param_2 = obj.getNewsFeed(userId) # obj.follow(followerId,followeeId) -# obj.unfollow(followerId,followeeId) \ No newline at end of file +# obj.unfollow(followerId,followeeId) diff --git a/solutions/python3/356.py b/solutions/python3/356.py index 54cbf3a..fe7abb1 100644 --- a/solutions/python3/356.py +++ b/solutions/python3/356.py @@ -1,23 +1,39 @@ + class Solution: def isReflected(self, points): + """ + 判断给定点集是否关于某条直线对称。 + + 参数: + points: List[Tuple[int, int]], 点的集合 + + 返回: + bool, 如果点集关于某条直线对称则返回 True,否则返回 False + """ + if len(points) < 2: - return True + return True # 如果点的数量少于2,则直接返回True,因为不可能不对称 + + # 计算所有x坐标的中位线 x = (min(x for x, y in points) + max(x for x, y in points)) / 2 - left, right, on = set(), set(), set() + + left_set, right_set, on_line_set = set(), set(), set() for i, j in points: - if i < x: - left.add((i, j)) - elif i > x: - right.add((i, j)) - else: - on.add((i, j)) + if i < x: # 点位于中位线左边 + left_set.add((i, j)) + elif i > x: # 点位于中位线右边 + right_set.add((i, j)) + else: # 点在中位线上 + on_line_set.add((i, j)) + for i, j in points: - if i < x and (2 * x - i, j) in right: + if i < x and (2 * x - i, j) in right_set: # 检查左边点的对称点是否在右边集合中 continue - elif i > x and (2 * x - i, j) in left: + elif i > x and (2 * x - i, j) in left_set: # 检查右边点的对称点是否在左边集合中 continue - elif i == x and (2 * x - i, j) in on: + elif i == x and (2 * x - i, j) in on_line_set: # 检查中位线上点的对称点是否也在中位线集合中 continue else: return False - return True \ No newline at end of file + + return True diff --git a/solutions/python3/357.py b/solutions/python3/357.py index 7d74fbb..d1c0ea6 100644 --- a/solutions/python3/357.py +++ b/solutions/python3/357.py @@ -1,3 +1,10 @@ + class Solution: - def countNumbersWithUniqueDigits(self, n): - return [1, 10, 91, 739, 5275, 32491, 168571, 712891, 2345851, 5611771, 8877691][n % 11] \ No newline at end of file + # 计算具有唯一数字的数的数量 + + def countNumbersWithUniqueDigits(self, n: int) -> int: + # 使用预计算数组来提高效率,避免多次重复计算 + unique_digit_counts = [1, 10, 91, 739, 5275, 32491, 168571, 712891, 2345851, 5611771, 8877691] + + # 返回预计算数组中对应位置的值 + return unique_digit_counts[n % 11] diff --git a/solutions/python3/358.py b/solutions/python3/358.py index d6b8375..53ce2a8 100644 --- a/solutions/python3/358.py +++ b/solutions/python3/358.py @@ -1,13 +1,38 @@ + class Solution: - def rearrangeString(self, s, k): - q, last, res, wq = [(-v, k) for k, v in collections.Counter(s).items()], {}, "", [] + def rearrangeString(self, s: str, k: int) -> str: + """ + s: 需要重新排列的字符串 + k: 重排后两个相同字符之间至少需要间隔的最小距离 + 返回值:按要求重新排列后的字符串,如果无法满足要求则返回空字符串 + """ + + from collections import Counter + import heapq + + # 统计每个字符出现的次数,并构建优先队列 + q, last, res, wq = [(-v, k) for k, v in Counter(s).items()], {}, "", [] heapq.heapify(q) + + # 主循环,处理字符串 s 中的每个字符 for i in range(len(s)): - if wq and (wq[0][1] not in last or last[wq[0][1]] + k <= i): cnt, char = heapq.heappop(wq) + if wq and (wq[0][1] not in last or last[wq[0][1]] + k <= i): + cnt, char = heapq.heappop(wq) else: - while q and not (q[0][1] not in last or last[q[0][1]] + k <= i): heapq.heappush(wq, heapq.heappop(q)) - if not q: return "" + # 当优先队列为空或者没有满足插入条件时,从主队列中取出元素并处理 + while q and (not (q[0][1] not in last or last[q[0][1]] + k <= i)): + heapq.heappush(wq, heapq.heappop(q)) + if not q: + return "" cnt, char = heapq.heappop(q) - res, cnt, last[char] = res + char, cnt + 1, i - if cnt: heapq.heappush(q, (cnt, char)) - return res \ No newline at end of file + + # 将字符添加到结果字符串中,并更新相关数据 + res += char + cnt += 1 + last[char] = i + + # 如果该字符还有剩余,则重新加入优先队列 + if cnt: + heapq.heappush(q, (cnt, char)) + + return res diff --git a/solutions/python3/359.py b/solutions/python3/359.py index b552d77..dba25e2 100644 --- a/solutions/python3/359.py +++ b/solutions/python3/359.py @@ -1,10 +1,16 @@ + class Logger: + # 构造函数,初始化日志字典 def __init__(self): self.logs = {} - def shouldPrintMessage(self, timestamp, message): + # 检查是否应打印消息 + def shouldPrintMessage(self, timestamp: int, message: str) -> bool: if message not in self.logs or timestamp - self.logs[message] >= 10: + # 如果消息不在日志中或时间戳与上次记录的时间差大于等于10,则更新日志并返回True self.logs[message] = timestamp return True - return False \ No newline at end of file + else: + # 否则返回False + return False diff --git a/solutions/python3/36.py b/solutions/python3/36.py index 21e1e95..bb9f82b 100644 --- a/solutions/python3/36.py +++ b/solutions/python3/36.py @@ -1,10 +1,22 @@ + class Solution: + # 检查给定的数独是否有效 + def isValidSudoku(self, board): rows, cols, triples = collections.defaultdict(set), collections.defaultdict(set), collections.defaultdict(set) - for i, row in enumerate(board): - for j, c in enumerate(row): - if c != "." and c in rows[i] or c in cols[j] or c in triples[(i //3, j // 3)]: - return False - elif c != ".": - rows[i].add(c); cols[j].add(c); triples[(i // 3, j // 3)].add(c) - return True \ No newline at end of file + + # 遍历每一行和每一列,检查每个数字是否出现重复 + for i, row in enumerate(board): # 遍历board中的每一行 + for j, c in enumerate(row): # 遍历当前行中的每一个元素 + if c != ".": # 如果不是空格"." + # 检查该数字是否已经在当前行、列或子方块中出现过 + if c in rows[i] or c in cols[j] or c in triples[(i // 3, j // 3)]: + return False + + # 将该数字添加到对应的集合中 + rows[i].add(c) + cols[j].add(c) + triples[(i // 3, j // 3)].add(c) + + # 如果所有检查都通过,返回True表示数独有效 + return True diff --git a/solutions/python3/360.py b/solutions/python3/360.py index 0028579..3018714 100644 --- a/solutions/python3/360.py +++ b/solutions/python3/360.py @@ -1,16 +1,37 @@ + class Solution: def sortTransformedArray(self, nums, a, b, c): + """ + 对给定的数组进行变换并排序。 + + 参数: + nums (List[int]): 输入的整数列表。 + a, b, c (int): 二次多项式系数,用于对每个元素进行变换: ax^2 + bx + c。 + + 返回: + List[int]: 变换后的数组,并按升序排列。 + """ arr, l, r, ind = [0] * len(nums), 0, len(nums) - 1, a >= 0 and len(nums) - 1 or 0 + # 使用双指针法,分别指向列表的起始和末尾 while l <= r: - n1, n2 = a * nums[l] * nums[l] + b * nums[l] + c, a * nums[r] * nums[r] + b * nums[r] + c - if a >= 0: - if n1 >= n2: l += 1 - else: r -= 1 - arr[ind] = n1 >= n2 and n1 or n2 - ind -= 1 - else: - if n1 < n2: l += 1 - else: r -= 1 - arr[ind] = n1 < n2 and n1 or n2 - ind += 1 - return arr \ No newline at end of file + n1 = a * nums[l] * nums[l] + b * nums[l] + c # 计算左指针对应位置的值 + n2 = a * nums[r] * nums[r] + b * nums[r] + c # 计算右指针对应位置的值 + + if a >= 0: # 当a>=0时,开口向上 + if n1 >= n2: + arr[ind] = n1 # 将较大的数填入结果数组 + l += 1 + else: + arr[ind] = n2 + r -= 1 + ind -= 1 # 索引从后向前填写 + else: # 当a<0时,开口向下 + if n1 < n2: + arr[ind] = n1 + l += 1 + else: + arr[ind] = n2 + r -= 1 + ind += 1 # 索引从前向后填写 + + return arr diff --git a/solutions/python3/361.py b/solutions/python3/361.py index 3bb39a7..e4b4640 100644 --- a/solutions/python3/361.py +++ b/solutions/python3/361.py @@ -1,23 +1,32 @@ + class Solution: + # 初始化解决方案类 + def maxKilledEnemies(self, grid): - m, n, res = len(grid), len(grid and grid[0]), 0 - dp = [[[0, 0, 0, 0] for j in range(n + 1)] for i in range(m + 1)] + m, n, res = len(grid), len(grid and grid[0]), 0 # 获取行数m和列数n,初始化结果res为0 + dp = [[[0, 0, 0, 0] for j in range(n + 1)] for i in range(m + 1)] # 初始化动态规划表dp + + # 从左上到右下遍历网格 for i in range(m): for j in range(n): if grid[i][j] == "0": - dp[i][j][0] = dp[i][j - 1][0] - dp[i][j][1] = dp[i - 1][j][1] + dp[i][j][0] = dp[i][j - 1][0] # 左侧相同行的敌人数量 + dp[i][j][1] = dp[i - 1][j][1] # 上方相同列的敌人数量 elif grid[i][j] == "E": - dp[i][j][0] = dp[i][j - 1][0] + 1 - dp[i][j][1] = dp[i - 1][j][1] + 1 + dp[i][j][0] = dp[i][j - 1][0] + 1 # 左侧相同行增加一个敌人 + dp[i][j][1] = dp[i - 1][j][1] + 1 # 上方相同列增加一个敌人 + + # 从右下到左上反向遍历网格,更新dp表 for i in range(m - 1, -1, -1): for j in range(n - 1, -1, -1): if grid[i][j] == "0": - dp[i][j][2] = dp[i][j + 1][2] - dp[i][j][3] = dp[i + 1][j][3] + dp[i][j][2] = dp[i][j + 1][2] # 右侧相同行的敌人数量 + dp[i][j][3] = dp[i + 1][j][3] # 下方相同列的敌人数量 elif grid[i][j] == "E": - dp[i][j][2] = dp[i][j + 1][2] + 1 - dp[i][j][3] = dp[i + 1][j][3] + 1 + dp[i][j][2] = dp[i][j + 1][2] + 1 # 右侧相同行增加一个敌人 + dp[i][j][3] = dp[i + 1][j][3] + 1 # 下方相同列增加一个敌人 + if grid[i][j] == "0": - res = max(res, sum(dp[i][j])) - return res \ No newline at end of file + res = max(res, sum(dp[i][j])) # 更新最大敌人数量结果 + + return res diff --git a/solutions/python3/362.py b/solutions/python3/362.py index 19b0366..9ade9a7 100644 --- a/solutions/python3/362.py +++ b/solutions/python3/362.py @@ -1,12 +1,17 @@ + class HitCounter(object): + # 初始化计数器,使用最小堆来存储时间戳 def __init__(self): self.hits = [] + # 记录一次访问,并将时间戳加上300秒存入堆中 def hit(self, timestamp): heapq.heappush(self.hits, timestamp + 300) + # 获取过去300秒内的访问次数 def getHits(self, timestamp): + # 移除过期的时间戳(即小于当前时间减去300秒) while self.hits and self.hits[0] <= timestamp: heapq.heappop(self.hits) - return len(self.hits) \ No newline at end of file + return len(self.hits) diff --git a/solutions/python3/363.py b/solutions/python3/363.py index 37fd5ef..fb880eb 100644 --- a/solutions/python3/363.py +++ b/solutions/python3/363.py @@ -1,14 +1,34 @@ + class Solution: - def maxSumSubmatrix(self, matrix, k, mxTotal = -float("inf")): + def maxSumSubmatrix(self, matrix: List[List[int]], k: int, mxTotal: float = -float("inf")) -> float: + """ + 寻找矩阵中和小于k的最大子矩阵的和。 + + 参数: + matrix (List[List[int]]): 输入的二维整数数组 + k (int): 目标和 + mxTotal (float, 可选): 当前记录的最大和,默认为负无穷 + + 返回值: + float: 符合条件的最大子矩阵和,若无符合条件的返回-无穷 + """ for l in range(len(matrix[0])): + # 初始化当前行的累加数组 dp = [0] * len(matrix) for r in range(l, len(matrix[0])): + # 从第l列到第r列计算每一行的累积和 for i in range(len(matrix)): dp[i] += matrix[i][r] + + # 初始化辅助数组及当前最大值 sums, cur, mx = [float("inf")], 0, -float("inf") for sm in dp: bisect.insort(sums, cur) cur += sm + # 更新最大子矩阵和 mx = max(mx, cur - sums[bisect.bisect_left(sums, cur - k)]) + + # 更新全局最大值 mxTotal = max(mxTotal, mx) - return mxTotal \ No newline at end of file + + return mxTotal diff --git a/solutions/python3/364.py b/solutions/python3/364.py index e47976e..b1a4d95 100644 --- a/solutions/python3/364.py +++ b/solutions/python3/364.py @@ -1,3 +1,4 @@ + # """ # This is the interface that allows for creating nested lists. # You should not implement it, or speculate about its implementation @@ -42,10 +43,18 @@ # """ class Solution: + # 计算最大深度 def depthSumInverse(self, nestedList): + # 深度优先搜索,计算每个元素的最大深度 def dfs(obj, d): - return obj.isInteger() and d or max((dfs(item, d + 1) for item in obj.getList()), default = 0) + return obj.isInteger() and d or max((dfs(item, d + 1) for item in obj.getList()), default = 0) + + # 深度优先搜索,计算加权和 def dfs2(obj, d): return obj.isInteger() and d * obj.getInteger() or sum(dfs2(item, d - 1) for item in obj.getList()) + + # 计算最大深度 mx = max((dfs(item, 1) for item in nestedList), default = 0) - return mx and sum(dfs2(item, mx) for item in nestedList) or 0 \ No newline at end of file + + # 如果存在最大深度,则计算加权和,否则返回0 + return mx and sum(dfs2(item, mx) for item in nestedList) or 0 diff --git a/solutions/python3/365.py b/solutions/python3/365.py index e281966..11efe23 100644 --- a/solutions/python3/365.py +++ b/solutions/python3/365.py @@ -1,7 +1,12 @@ + class Solution: - def canMeasureWater(self, x, y, z): - def gcd(x, y): - for i in range(min(x, y), -1, -1): - if not x % i and not y % i: return i - div = gcd(x, y) if x * y else 0 - return not z % div and z <= x + y if div else not z \ No newline at end of file + # 定义一个求最大公约数的辅助函数 + def gcd(self, a, b): + for i in range(min(a, b), 0, -1): + if not a % i and not b % i: + return i + + # 主函数,判断给定的水箱容量x和y能否量出恰好z单位的水量 + def canMeasureWater(self, x: int, y: int, z: int) -> bool: + div = self.gcd(x, y) if x * y else 0 # 计算x和y的最大公约数div,特殊情况处理 + return not z % div and z <= x + y if div else not z # 判断是否能量出恰好z单位的水量 diff --git a/solutions/python3/366.py b/solutions/python3/366.py index cde94d9..4dde907 100644 --- a/solutions/python3/366.py +++ b/solutions/python3/366.py @@ -1,18 +1,30 @@ + # Definition for a binary tree node. -# class TreeNode: -# def __init__(self, x): -# self.val = x -# self.left = None -# self.right = None +class TreeNode: + def __init__(self, x): + self.val = x + self.left = None + self.right = None class Solution: - def findLeaves(self, root): + # 寻找二叉树的每层最外侧节点 + def findLeaves(self, root: TreeNode) -> List[List[int]]: res = [] + + # 深度优先搜索,返回当前节点所在层数 def dfs(node): - if not node: return -1 - i = max(dfs(node.left), dfs(node.right)) + 1 - try: res[i].append(node.val) - except: res.append([node.val]) + if not node: + return -1 # 空节点标记为-1 + + i = max(dfs(node.left), dfs(node.right)) + 1 # 计算左右子树的最大深度并加1 + + try: + res[i].append(node.val) # 尝试在对应层数的列表中添加当前节点值 + except IndexError: + res.append([node.val]) # 如果越界则创建新列表 + return i + dfs(root) - return res \ No newline at end of file + + return res diff --git a/solutions/python3/367.py b/solutions/python3/367.py index af033d7..9867dca 100644 --- a/solutions/python3/367.py +++ b/solutions/python3/367.py @@ -1,11 +1,17 @@ + class Solution: def isPerfectSquare(self, num): """ - :type num: int - :rtype: bool + :type num: int # 输入的整数 num + :rtype: bool # 返回是否是完全平方数 """ - i=1 - while i**2<=num: - if i**2= len(dp[j]): - dp[j] = dp[i] + dp[j][-1:] - return dp and sorted(dp, key = len)[-1] \ No newline at end of file + # 更新dp[j] + dp[j] = dp[i] + [dp[j][-1]] + + # 返回最长的可被整除子集,注意可能为空的情况 + return sorted(dp, key=len)[-1] if dp else [] diff --git a/solutions/python3/369.py b/solutions/python3/369.py index 7949098..bd5212f 100644 --- a/solutions/python3/369.py +++ b/solutions/python3/369.py @@ -1,15 +1,19 @@ + # Definition for singly-linked list. -# class ListNode: -# def __init__(self, x): -# self.val = x -# self.next = None +class ListNode: + def __init__(self, x): + self.val = x + self.next = None class Solution: - def plusOne(self, head): + # 处理链表加1操作 + def plusOne(self, head: 'ListNode') -> 'ListNode': """ :type head: ListNode :rtype: ListNode """ + + # 深度优先遍历,从尾节点开始处理进位 def dfs(node): if not node.next or dfs(node.next): if node.val + 1 > 9: @@ -18,8 +22,12 @@ def dfs(node): else: node.val += 1 return False + + # 如果需要在头结点前加一个节点,则返回新链表 if dfs(head): dummy = ListNode(1) dummy.next = head return dummy - return head \ No newline at end of file + + # 否则直接返回原链表 + return head diff --git a/solutions/python3/37.py b/solutions/python3/37.py index f2a168c..3fa1f4b 100644 --- a/solutions/python3/37.py +++ b/solutions/python3/37.py @@ -1,33 +1,47 @@ + class Solution: def solveSudoku(self, board): + # 初始化行、列和宫集合,用于存储已填数字;使用双端队列记录待填充位置 rows, cols, triples, visit = collections.defaultdict(set), collections.defaultdict(set), collections.defaultdict(set), collections.deque([]) + for r in range(9): for c in range(9): + # 遍历棋盘,填充已有的数字到相应集合中,并记录待填充位置 if board[r][c] != ".": rows[r].add(board[r][c]) cols[c].add(board[r][c]) triples[(r // 3, c // 3)].add(board[r][c]) else: visit.append((r, c)) + def dfs(): + # 当没有待填充位置时,表示已经成功填满整个棋盘 if not visit: return True + r, c = visit[0] t = (r // 3, c // 3) + for dig in {"1", "2", "3", "4", "5", "6", "7", "8", "9"}: + # 检查当前数字是否可以填入 if dig not in rows[r] and dig not in cols[c] and dig not in triples[t]: - board[r][c] = dig + board[r][c] = dig # 填充数字并记录状态 rows[r].add(dig) cols[c].add(dig) triples[t].add(dig) - visit.popleft() + + visit.popleft() # 移除当前待填充位置 + if dfs(): - return True - else: - board[r][c] = "." - rows[r].discard(dig) - cols[c].discard(dig) - triples[t].discard(dig) - visit.appendleft((r, c)) + return True # 如果递归填满成功,直接返回 + + board[r][c] = "." # 回溯 + rows[r].discard(dig) # 取消状态修改 + cols[c].discard(dig) + triples[t].discard(dig) + + visit.appendleft((r, c)) # 将当前位置重新加入待填充队列 + return False - dfs() \ No newline at end of file + + dfs() diff --git a/solutions/python3/370.py b/solutions/python3/370.py index 5cdabb0..825ba78 100644 --- a/solutions/python3/370.py +++ b/solutions/python3/370.py @@ -1,13 +1,41 @@ + class Solution: - def getModifiedArray(self, length, updates): + # 定义一个类来解决修改数组的问题 + + def getModifiedArray(self, length: int, updates: list[tuple[int, int, int]]) -> list[int]: + # 初始化起始位置、结束位置的增量字典和结果数组 start, end, res, cur = collections.defaultdict(int), collections.defaultdict(int), [0] * length, 0 + + # 遍历所有更新操作,记录每个位置的增量变化 for s, e, inc in updates: start[s] += inc end[e] += -inc + + # 计算实际数组值的变化 for i in range(length): if start[i]: cur += start[i] res[i] += cur if end[i]: cur += end[i] - return res \ No newline at end of file + + return res # 返回修改后的数组 + + + +class Solution: + def getModifiedArray(self, length: int, updates: list[tuple[int, int, int]]) -> list[int]: + start, end, res, cur = collections.defaultdict(int), collections.defaultdict(int), [0] * length, 0 + + for s, e, inc in updates: + start[s] += inc + end[e] += -inc + + for i in range(length): + if start[i]: + cur += start[i] + res[i] += cur + if end[i]: + cur += end[i] + + return res diff --git a/solutions/python3/371.py b/solutions/python3/371.py index 4de2603..bf3e936 100644 --- a/solutions/python3/371.py +++ b/solutions/python3/371.py @@ -1,11 +1,20 @@ + class Solution: - def getSum(self, a, b): + def getSum(self, a: int, b: int) -> int: """ :type a: int :type b: int :rtype: int """ + # mx 为正数的最大值,mask 用于防止溢出 + # Python 中没有整型溢出的概念,但为了模拟类似行为使用 mask mx, mask = 0x7FFFFFFF, 0xFFFFFFFF + + # 使用异或和与运算来模拟加法 while b: + # a 记录当前的未进位部分,b 记录当前的进位部分 a, b = (a ^ b) & mask, ((a & b) << 1) & mask - return a if a <= mx else ~(a ^ mask) \ No newline at end of file + + # 返回结果,注意 Python 中没有溢出,这里只是模拟 + return a if a <= mx else ~(a ^ mask) + \ No newline at end of file diff --git a/solutions/python3/372.py b/solutions/python3/372.py index 787f754..575762e 100644 --- a/solutions/python3/372.py +++ b/solutions/python3/372.py @@ -1,3 +1,5 @@ + class Solution: - def superPow(self, a, b): - return pow(a, int(''.join(map(str, b))), 1337) \ No newline at end of file + # 计算超幂,即计算 a 的 b 次方对 1337 取模的结果 + def superPow(self, a: int, b: list[int]) -> int: + return pow(a, int(''.join(map(str, b))), 1337) # 中文注释:将列表 b 转换为整数,计算 a 的 b 次方后对 1337 取模 diff --git a/solutions/python3/373.py b/solutions/python3/373.py index a06e1fb..f645ce2 100644 --- a/solutions/python3/373.py +++ b/solutions/python3/373.py @@ -1,10 +1,31 @@ + class Solution: - def kSmallestPairs(self, nums1, nums2, k): - if not nums1 or not nums2: return [] + # 定义一个类,用于解决求两个数组中和最小的k对值的问题 + + def kSmallestPairs(self, nums1: list[int], nums2: list[int], k: int) -> list[list[int]]: + """ + :param nums1: 第一个整数列表 + :param nums2: 第二个整数列表 + :param k: 最小的k对值 + :return: 返回最小和的前k对值组成的列表,每一对为两个整数组成的小列表 + + 1. 检查输入是否有空数组 + 2. 初始化变量n表示nums2长度,res用于存储结果,cnt计数器,heap用作优先队列 + 3. 将nums1中的每个元素与nums2的第一个元素组合放入堆中 + 4. 循环直到找到k对最小值或堆为空: + - 弹出堆顶元素,增加计数器 + - 如果当前索引未超出边界,则将新的组合加入堆中 + - 将当前最小和的两个整数加入结果列表 + """ + if not nums1 or not nums2: + return [] + n, res, cnt, heap = len(nums2), [], 0, [(nums1[i] + nums2[0], i, 0) for i in range(len(nums1))] + while heap and cnt < k: cnt += 1 sm, i, j = heapq.heappop(heap) res.append([nums1[i], nums2[j]]) if j + 1 < n: heapq.heappush(heap, (nums1[i] + nums2[j + 1], i, j + 1)) - return res \ No newline at end of file + + return res diff --git a/solutions/python3/375.py b/solutions/python3/375.py index 9fb1547..23991c4 100644 --- a/solutions/python3/375.py +++ b/solutions/python3/375.py @@ -1,8 +1,23 @@ + class Solution: + # 定义一个解题类,用于解决获取金额问题 + def getMoneyAmount(self, n): + # 初始化一个字典来存储子问题的解以避免重复计算 dic = {} + + # 定义一个深度优先搜索函数,用于查找最小花费 def dfs(l, r): - if l >=r: return 0 - if (l, r) not in dic: dic[(l, r)] = min(num + max(dfs(l, num - 1), dfs(num + 1, r)) for num in range(l, r)) + # 如果左索引大于等于右索引,则无需支付任何费用 + if l >= r: + return 0 + + # 如果当前子问题尚未计算过结果,则进行计算并存储在字典中 + if (l, r) not in dic: + dic[(l, r)] = min(num + max(dfs(l, num - 1), dfs(num + 1, r)) for num in range(l, r)) + + # 返回已经计算好的结果 return dic[(l, r)] - return dfs(1, n) \ No newline at end of file + + # 调用dfs函数从1到n进行搜索,返回最小花费 + return dfs(1, n) diff --git a/solutions/python3/376.py b/solutions/python3/376.py index 37892b7..907998b 100644 --- a/solutions/python3/376.py +++ b/solutions/python3/376.py @@ -1,10 +1,29 @@ + class Solution: def wiggleMaxLength(self, nums): - if len(nums) <= 2: return 0 if not nums else 1 if nums[0] == nums[-1] else 2 - inc = nums[0] < nums[1] if nums[0] != nums[1] else None - cnt = 2 if inc != None else 1 + """ + :param nums: List[int] 输入的整数列表 + :return: int 返回最长摆动子序列长度 + + 中文注释: + - 检查输入长度小于等于2时的情况 + - 初始化上升标志和计数值 + - 遍历数组,根据条件更新上升标志并增加计数值 + """ + # 如果输入列表长度小于或等于2直接返回结果 + if len(nums) <= 2: + return 0 if not nums else 1 if nums[0] == nums[-1] else 2 + + # 初始化比较上一个元素和当前元素是否上升的标志,和初始计数值 + inc = None if nums[0] != nums[1] else None + cnt = 2 if inc is not None else 1 + + # 遍历数组从第三个元素开始 for i in range(2, len(nums)): - if nums[i - 1] != nums[i] and (inc == None or inc != (nums[i - 1] < nums[i])): - inc = nums[i - 1] < nums[i] + # 如果当前元素与前一个元素不同且上升标志未定义或状态改变 + if nums[i - 1] != nums[i] and (inc is None or inc != (nums[i - 1] < nums[i])): + # 更新上升标志并增加计数值 + inc = nums[i - 1] < nums[i] cnt += 1 - return cnt \ No newline at end of file + + return cnt diff --git a/solutions/python3/377.py b/solutions/python3/377.py index 0ba33bb..8334cec 100644 --- a/solutions/python3/377.py +++ b/solutions/python3/377.py @@ -1,16 +1,26 @@ + class Solution: - def combinationSum4(self, nums, target): + # 定义组合总和问题的解决方案类 + + def combinationSum4(self, nums: List[int], target: int) -> int: + # 用于存储子问题的结果以避免重复计算 memo = {} + + # 深度优先搜索函数,用于递归求解目标值为目标的组合个数 def dfs(sm): + # 如果当前状态已计算过,则直接返回结果 if sm in memo: return memo[sm] else: + # 当剩余和大于等于目标时,判断是否完全匹配 if sm >= target: - memo[sm] = sm == target + memo[sm] = 1 if sm == target else 0 return memo[sm] cnt = 0 + # 遍历每个数字,递归计算子问题的结果并累加到当前计数中 for num in nums: memo[sm + num] = dfs(sm + num) cnt += memo[sm + num] - return cnt - return dfs(0) \ No newline at end of file + return cnt + # 从和为0开始进行搜索 + return dfs(0) diff --git a/solutions/python3/378.py b/solutions/python3/378.py index 0f86934..4149092 100644 --- a/solutions/python3/378.py +++ b/solutions/python3/378.py @@ -1,3 +1,8 @@ + class Solution: - def kthSmallest(self, matrix, k): - return sorted(itertools.chain(*matrix))[k - 1] \ No newline at end of file + # 定义一个类用于解决查找矩阵中第K小元素的问题 + + def kthSmallest(self, matrix: List[List[int]], k: int) -> int: + # 使用itertools.chain将二维列表展平为一维,然后进行排序 + # 通过sorted函数对所有元素进行升序排列 + return sorted(itertools.chain(*matrix))[k - 1] # 返回第K小的元素(注意索引从0开始) diff --git a/solutions/python3/379.py b/solutions/python3/379.py index bc1fc5d..7894fb3 100644 --- a/solutions/python3/379.py +++ b/solutions/python3/379.py @@ -1,13 +1,18 @@ + class PhoneDirectory: - def __init__(self, maxNumbers): - self.nums = set(range(maxNumbers)) + # 初始化电话目录,设置最大号码数量 + def __init__(self, maxNumbers: int): + self.nums = set(range(maxNumbers)) # 使用集合存储可用号码 - def get(self): - return self.nums.pop() if self.nums else -1 + # 获取一个未使用的号码并将其从集合中移除 + def get(self) -> int: + return self.nums.pop() if self.nums else -1 # 返回一个号码,如果无号码则返回-1 - def check(self, number): - return number in self.nums + # 检查给定的号码是否可用 + def check(self, number: int) -> bool: + return number in self.nums # 如果号码在集合中,则表示可用 - def release(self, number): - self.nums.add(number) \ No newline at end of file + # 释放指定的号码使其再次可用 + def release(self, number: int): + self.nums.add(number) # 将号码添加回集合 diff --git a/solutions/python3/38.py b/solutions/python3/38.py index 4243a57..25cc717 100644 --- a/solutions/python3/38.py +++ b/solutions/python3/38.py @@ -1,15 +1,30 @@ + class Solution: + # 定义一个方法countAndSay,接收一个整数n作为参数 def countAndSay(self, n): + # 初始字符串设为"1" curr = "1" + + # 循环n-1次以生成第n个序列 for i in range(n - 1): tmp, cnt = "", 1 + + # 遍历当前字符串curr中的每一个字符 for j, c in enumerate(curr): if j > 0 and curr[j - 1] == c: + # 如果当前字符与前一个字符相同,计数加一 cnt += 1 elif j > 0: + # 否则将上一段的数字和字符添加到临时字符串tmp中,并重置计数器 tmp += str(cnt) + curr[j - 1] cnt = 1 + if j == len(curr) - 1: + # 遍历完当前字符串后,将最后一段的数字和字符也添加到临时字符串tmp中 tmp += str(cnt) + curr[j] + + # 更新当前字符串为生成的新字符串 curr = tmp - return curr \ No newline at end of file + + # 返回最终结果 + return curr diff --git a/solutions/python3/380.py b/solutions/python3/380.py index 9aaf65b..99dafcb 100644 --- a/solutions/python3/380.py +++ b/solutions/python3/380.py @@ -1,38 +1,47 @@ + +import random + class RandomizedSet: def __init__(self): """ - Initialize your data structure here. + 初始化数据结构。 + Initialize the data structure. """ self.nums, self.ind = [], {} + def insert(self, val): """ + 向集合中插入一个值。如果集合未包含该元素,则返回 true;否则,返回 false。 Inserts a value to the set. Returns true if the set did not already contain the specified element. :type val: int :rtype: bool """ - if val not in self.ind: - self.nums += val, + if val not in self.ind: + self.nums.append(val) # 使用 append 更简洁 self.ind[val] = len(self.nums) - 1 return True return False def remove(self, val): """ + 从集合中移除一个值。如果集合包含该元素,则返回 true;否则,返回 false。 Removes a value from the set. Returns true if the set contained the specified element. :type val: int :rtype: bool """ if val in self.ind: ind, last = self.ind[val], self.nums[-1] - self.nums[ind], self.ind[last] = last, ind - self.nums.pop() + self.nums[ind] = last # 用最后一个元素替换目标元素 + self.ind[last] = ind # 更新索引字典 + self.nums.pop() # 移除最后一个元素(现在变成了被移除的元素) self.ind.pop(val) return True return False def getRandom(self): """ + 从集合中随机获取一个元素。 Get a random element from the set. :rtype: int """ @@ -42,4 +51,4 @@ def getRandom(self): # obj = RandomizedSet() # param_1 = obj.insert(val) # param_2 = obj.remove(val) -# param_3 = obj.getRandom() \ No newline at end of file +# param_3 = obj.getRandom() diff --git a/solutions/python3/381.py b/solutions/python3/381.py index 0591e83..1f4faa4 100644 --- a/solutions/python3/381.py +++ b/solutions/python3/381.py @@ -1,14 +1,21 @@ + +import random + class RandomizedCollection: + # 初始化,使用列表存储元素和一个字典存储每个元素的位置集合 def __init__(self): self.arr, self.pos = [], collections.defaultdict(set) - def insert(self, val): - out = val not in self.pos + + # 插入元素,返回插入后该值在集合中的唯一性状态 + def insert(self, val: int) -> bool: + out = val not in self.pos # 判断插入前该值是否已存在 self.arr.append(val) - self.pos[val].add(len(self.arr) - 1) + self.pos[val].add(len(self.arr) - 1) # 更新位置字典 return out - def remove(self, val): + # 移除元素,返回移除操作是否成功 + def remove(self, val: int) -> bool: if val in self.pos: if self.arr[-1] != val: x, y = self.pos[val].pop(), self.arr[-1] @@ -17,11 +24,12 @@ def remove(self, val): self.arr[x] = y else: self.pos[val].discard(len(self.arr) - 1) - self.arr.pop() + self.arr.pop() # 移除最后一个元素 if not self.pos[val]: self.pos.pop(val) return True return False + # 随机获取一个元素 def getRandom(self): - return random.choice(self.arr) \ No newline at end of file + return random.choice(self.arr) diff --git a/solutions/python3/382.py b/solutions/python3/382.py index b2568ac..8dbc88c 100644 --- a/solutions/python3/382.py +++ b/solutions/python3/382.py @@ -1,3 +1,4 @@ + # Definition for singly-linked list. # class ListNode: # def __init__(self, x): @@ -6,11 +7,14 @@ class Solution: - def __init__(self, head): + # 初始化时将链表转换为列表形式存储在arr中 + def __init__(self, head: ListNode): self.arr = [] - while head: - self.arr.append(head.val) - head = head.next + current = head # 使用current指针遍历链表 + while current: + self.arr.append(current.val) + current = current.next - def getRandom(self): - return random.choice(self.arr) \ No newline at end of file + # 随机返回arr中的一个元素,使用random.choice方法实现 + def getRandom(self) -> int: + return random.choice(self.arr) diff --git a/solutions/python3/383.py b/solutions/python3/383.py index 24da446..26c730e 100644 --- a/solutions/python3/383.py +++ b/solutions/python3/383.py @@ -1,9 +1,15 @@ + class Solution: + # 判断ransomNote是否可以通过magazine中的字符按顺序拼接而成 def canConstruct(self, ransomNote: str, magazine: str) -> bool: - cnt = collections.Counter(magazine) + from collections import Counter # 导入计数器类 + + cnt = Counter(magazine) # 统计magazine中每个字符的出现次数 + for c in ransomNote: - if cnt[c]: - cnt[c] -= 1 - else: - return False - return True \ No newline at end of file + if cnt[c]: # 如果字符c在magazine中有剩余 + cnt[c] -= 1 # 使用一个字符,计数减一 + else: # 没有剩余 + return False # 返回False + + return True # 所需字符都可用,返回True diff --git a/solutions/python3/384.py b/solutions/python3/384.py index 3f9669a..03b4a08 100644 --- a/solutions/python3/384.py +++ b/solutions/python3/384.py @@ -1,19 +1,29 @@ + class Solution: def __init__(self, nums: List[int]): + """ + 初始化时复制输入数组作为原始配置,并存储在self.org中。 + 同时,将输入数组复制一份保存在self.arr中用于后续操作。 + :param nums: 输入整数列表 + """ self.arr = nums self.org = nums[:] def reset(self) -> List[int]: """ - Resets the array to its original configuration and return it. + 将数组恢复到原始配置并返回。 + 这相当于撤销所有已执行的洗牌操作,使其回到初始状态。 + :return: 返回重置后的数组 """ self.arr = self.org[:] return self.arr def shuffle(self) -> List[int]: """ - Returns a random shuffling of the array. + 随机打乱数组中的元素顺序并返回打乱后的数组。 + 使用random.shuffle方法实现随机化操作。 + :return: 返回打乱后的数组 """ random.shuffle(self.arr) return self.arr @@ -22,4 +32,4 @@ def shuffle(self) -> List[int]: # Your Solution object will be instantiated and called as such: # obj = Solution(nums) # param_1 = obj.reset() -# param_2 = obj.shuffle() \ No newline at end of file +# param_2 = obj.shuffle() diff --git a/solutions/python3/385.py b/solutions/python3/385.py index 710d4be..8a64251 100644 --- a/solutions/python3/385.py +++ b/solutions/python3/385.py @@ -1,18 +1,34 @@ + class Solution: - def deserialize(self, s): + def deserialize(self, s: str) -> 'NestedInteger': + """ + Deserialize a nested list from a string representation. + + 中文注释:将字符串表示的嵌套列表反序列化。 + """ + stack, num, last = [], "", None + for c in s: - if c.isdigit() or c == "-": num += c + if c.isdigit() or c == "-": + # 数字或负号,累加形成数字 + num += c elif c == "," and num: + # 逗号且之前有数字,将数字添加到栈顶元素的子列表中 stack[-1].add(NestedInteger(int(num))) num = "" elif c == "[": + # 左括号,创建新元素并压入栈 elem = NestedInteger() - if stack: stack[-1].add(elem) + if stack: + stack[-1].add(elem) stack.append(elem) elif c == "]": + # 右括号且之前有数字,将数字添加到当前元素中 if num: stack[-1].add(NestedInteger(int(num))) num = "" + # 弹出栈顶元素作为结果的最终部分 last = stack.pop() - return last if last else NestedInteger(int(num)) \ No newline at end of file + + return last if last else NestedInteger(int(num)) diff --git a/solutions/python3/386.py b/solutions/python3/386.py index 1617a1e..3786465 100644 --- a/solutions/python3/386.py +++ b/solutions/python3/386.py @@ -1,2 +1,8 @@ + class Solution: - def lexicalOrder(self, n): return sorted(range(1, n + 1), key = str) \ No newline at end of file + # 定义一个Solution类 + + def lexicalOrder(self, n): + # 方法: lexicalOrder,输入参数n,返回1到n之间的数字按照字典序排序的结果 + + return sorted(range(1, n + 1), key=str) # 使用sorted函数和key=str将范围内的数字按字符串形式排序 diff --git a/solutions/python3/387.py b/solutions/python3/387.py index 6e181d2..2015653 100644 --- a/solutions/python3/387.py +++ b/solutions/python3/387.py @@ -1,12 +1,23 @@ + class Solution: + # 定义一个类,用于解决第一个唯一字符的问题 + def firstUniqChar(self, s): """ - :type s: str - :rtype: int + :param s: 输入字符串 + :return: 返回第一个唯一字符的索引,如果没有则返回-1 """ - dic = collections.defaultdict(int) + from collections import defaultdict # 引入defaultdict方便统计字符出现次数 + + dic = defaultdict(int) # 使用defaultdict来存储每个字符及其出现次数 + for c in s: + # 遍历字符串中的每一个字符,并更新其在字典中的计数 dic[c] += 1 + for i, c in enumerate(s): - if dic[c] == 1: return i - return -1 \ No newline at end of file + # 第二次遍历,查找第一个唯一字符的索引 + if dic[c] == 1: + return i # 如果找到唯一字符,返回其索引 + + return -1 # 如果没有找到唯一字符,返回-1 diff --git a/solutions/python3/388.py b/solutions/python3/388.py index 850621d..7df56a2 100644 --- a/solutions/python3/388.py +++ b/solutions/python3/388.py @@ -1,12 +1,25 @@ + class Solution: def lengthLongestPath(self, input: str) -> int: - maxlen = 0 - pathlen = {0: 0} + """ + :param input: 输入的字符串,包含多级目录结构信息(用换行符分隔) + :return: 返回最长路径长度 + + 思路:通过分析每一行的缩进程度(depth)来确定文件或目录的位置 + 使用字典pathlen存储每个深度级别的路径长度 + """ + + maxlen = 0 # 最长路径长度 + pathlen = {0: 0} # key为深度,value为该深度下的路径长度 + for line in input.splitlines(): - name = line.lstrip('\u005Ct') - depth = len(line) - len(name) - if '.' in name: - maxlen = max(maxlen, pathlen[depth] + len(name)) - else: - pathlen[depth + 1] = pathlen[depth] + len(name) + 1 - return maxlen \ No newline at end of file + name = line.lstrip('\t') # 去掉首部的制表符,得到文件或目录名称 + depth = len(line) - len(name) # 计算缩进程度(depth) + + if '.' in name: # 如果是文件 + maxlen = max(maxlen, pathlen[depth] + len(name)) # 更新最大路径长度 + + else: # 如果是目录 + pathlen[depth + 1] = pathlen[depth] + len(name) + 1 # 更新下一层目录的路径长度 + + return maxlen diff --git a/solutions/python3/389.py b/solutions/python3/389.py index ad55b1f..bc7fbef 100644 --- a/solutions/python3/389.py +++ b/solutions/python3/389.py @@ -1,3 +1,21 @@ + class Solution: - def findTheDifference(self, s, t): - return next(iter(collections.Counter(t) - collections.Counter(s))) \ No newline at end of file + """ + 解决方案类 + + Attributes: + None + """ + + def findTheDifference(self, s: str, t: str) -> str: + """ + 找出字符串t中比字符串s多一个字符的那一个。 + + 参数: + s (str): 字符串1 + t (str): 字符串2 + + 返回: + str: 多出来的那个字符 + """ + return next(iter(collections.Counter(t) - collections.Counter(s))) diff --git a/solutions/python3/39.py b/solutions/python3/39.py index a48133f..329a371 100644 --- a/solutions/python3/39.py +++ b/solutions/python3/39.py @@ -1,11 +1,21 @@ + class Solution: - def combinationSum(self, c, t): - res, stack, n = [], [(0, [], 0)], len(c) - while stack: - sm, tmp, r = stack.pop() - for i in range(r, n): - if sm + c[i] < t: - stack.append((sm + c[i], tmp + [c[i]], i)) - elif sm + c[i] == t: - res.append(tmp + [c[i]]) - return res \ No newline at end of file + # 定义一个求解组合和问题的类 + + def combinationSum(self, candidates, target): + # 初始化结果列表、栈以及候选数个数 + result, stack, n = [], [(0, [], 0)], len(candidates) + + while stack: # 当栈不为空时,继续循环 + sum_val, tmp_list, right_index = stack.pop() # 弹出栈顶元素 + + for i in range(right_index, n): # 从当前右边界开始遍历候选数列表 + if sum_val + candidates[i] < target: + # 如果当前和加上下一个数小于目标值,则压入新状态到栈中 + stack.append((sum_val + candidates[i], tmp_list + [candidates[i]], i)) + + elif sum_val + candidates[i] == target: + # 如果当前和等于目标值,找到一组解,将其加入结果列表 + result.append(tmp_list + [candidates[i]]) + + return result # 返回所有满足条件的组合和列表 diff --git a/solutions/python3/390.py b/solutions/python3/390.py index 22f4242..36dbd3c 100644 --- a/solutions/python3/390.py +++ b/solutions/python3/390.py @@ -1,9 +1,24 @@ + class Solution: def lastRemaining(self, n): + """ + :param n: 整数,表示初始数量 (n) + :return: 返回第 n 次操作后剩下的最后一个元素的位置 + + 使用数学方法模拟筛选过程,优化空间和时间复杂度。 + """ head, left, step, remaining = 1, 1, 1, n + # 当剩余元素大于1时继续循环 while remaining > 1: - if left or remaining % 2: head += step + if left or remaining % 2: + # 如果left为True或剩余元素个数为奇数,则前进step步 + head += step + + # 每次操作后更新left状态,即下一次筛选方向 left = 1 - left + # 更新步长,每次循环步长翻倍 step *= 2 + # 剩余元素数量减半 remaining //= 2 - return head \ No newline at end of file + + return head diff --git a/solutions/python3/391.py b/solutions/python3/391.py index b5cbbf7..11378ef 100644 --- a/solutions/python3/391.py +++ b/solutions/python3/391.py @@ -1,13 +1,28 @@ + class Solution: + # 判断给定的矩形集合是否能完全覆盖一个大矩形 + def isRectangleCover(self, rectangles): - cnt = collections.Counter() + from collections import Counter + + # 使用计数器统计每个顶点出现次数 + cnt = Counter() for x1, y1, x2, y2 in rectangles: cnt[(x1, y1)] += 1 cnt[(x1, y2)] += 1 cnt[(x2, y2)] += 1 cnt[(x2, y1)] += 1 - x1, y1, x2, y2 = min([r[:2] for r in rectangles]) + max(r[-2:] for r in rectangles) - for x, y in ((x1, y1), (x1, y2), (x2, y2), (x2, y1)): - if cnt[(x, y)] != 1: return False + + # 计算大矩形的左下角和右上角坐标 + x1, y1 = min([r[:2] for r in rectangles]) + x2, y2 = max(r[-2:] for r in rectangles) + + # 检查四个顶点是否各出现一次 + for (x, y) in ((x1, y1), (x1, y2), (x2, y2), (x2, y1)): + if cnt[(x, y)] != 1: + return False cnt.pop((x, y)) - return all(cnt[k] in (2, 4) for k in cnt) and sum((x2 - x1) * (y2 - y1) for x1, y1, x2, y2 in rectangles) == (x2 - x1) * (y2 - y1) \ No newline at end of file + + # 检查其他顶点是否符合预期 + return all(cnt[k] in (2, 4) for k in cnt) and \ + sum((x2 - x1) * (y2 - y1) for x1, y1, x2, y2 in rectangles) == (x2 - x1) * (y2 - y1) diff --git a/solutions/python3/392.py b/solutions/python3/392.py index 3ff6082..0869e25 100644 --- a/solutions/python3/392.py +++ b/solutions/python3/392.py @@ -1,7 +1,34 @@ + class Solution: - def isSubsequence(self, s, t): - ind = -1 - for i in s: - try: ind = t.index(i, ind + 1) - except: return False - return True \ No newline at end of file + # 判断字符串s是否是字符串t的子序列 + def isSubsequence(self, s: str, t: str) -> bool: + index = -1 # 记录当前字符在t中的索引位置 + + for char in s: + try: + # 在t中从index+1的位置开始寻找char,若找到则更新index + index = t.index(char, index + 1) + except ValueError: + # 若未找到,则返回False + return False + + # 如果s的所有字符都在t中按顺序出现过,则返回True + return True + + + +class Solution: + # 判断字符串s是否是字符串t的子序列 + def isSubsequence(self, s: str, t: str) -> bool: + index = -1 # 记录当前字符在t中的索引位置 + + for char in s: + try: + # 在t中从index+1的位置开始寻找char,若找到则更新index + index = t.index(char, index + 1) + except ValueError: + # 若未找到,则返回False + return False + + # 如果s的所有字符都在t中按顺序出现过,则返回True + return True diff --git a/solutions/python3/393.py b/solutions/python3/393.py index 247e2c7..4230676 100644 --- a/solutions/python3/393.py +++ b/solutions/python3/393.py @@ -1,6 +1,9 @@ + class Solution: def validUtf8(self, data: List[int]) -> bool: + # 检查剩余数据是否足够 def rest(i): + """Check if there are enough remaining bytes.""" if len(data) < i: return False for _ in range(i): @@ -8,20 +11,32 @@ def rest(i): return False return True + # 将整数转换为8位二进制字符串并反转列表方便从高位开始处理 data, byte = [str(bin(seq)[2:].zfill(8)) for seq in data[::-1]], None + while data: seq = data.pop() + + # 单字节情况:以'0'开头的二进制串直接跳过 if seq.startswith("0"): continue + + # 两字节序列:前缀为"110" elif seq.startswith("110"): if not rest(1): return False + + # 三字节序列:前缀为"1110" elif seq.startswith("1110"): if not rest(2): return False + + # 四字节序列:前缀为"11110" elif seq.startswith("11110"): if not rest(3): return False + else: return False + return True diff --git a/solutions/python3/394.py b/solutions/python3/394.py index 7bc9ab6..4dd91f8 100644 --- a/solutions/python3/394.py +++ b/solutions/python3/394.py @@ -1,14 +1,30 @@ + class Solution: def decodeString(self, s): + """ + 解码字符串的实现。使用栈来帮助处理嵌套的括号结构。 + + 参数: + s (str): 输入的编码字符串 + + 返回值: + str: 解码后的字符串 + """ stack, num, string = [], 0, "" for c in s: + # 遇到左括号时,将当前累积的数和字符串压入栈中,并重置它们 if c == "[": - stack += string, - stack += num, + stack += (string, ), + stack += (num, ) num, string = 0, "" + # 遇到右括号时,从栈中弹出上一个数和字符串,并更新当前的解码结果 elif c == "]": pre_num, pre_string = stack.pop(), stack.pop() string = pre_string + pre_num * string - elif c.isdigit(): num = num * 10 + int(c) - else: string += c - return string \ No newline at end of file + # 当前字符是数字时,构建数字 + elif c.isdigit(): + num = num * 10 + int(c) + # 其他情况下直接拼接当前字符 + else: + string += c + return string diff --git a/solutions/python3/395.py b/solutions/python3/395.py index a6b4640..568a918 100644 --- a/solutions/python3/395.py +++ b/solutions/python3/395.py @@ -1,4 +1,8 @@ + class Solution: - def longestSubstring(self, s, k): + def longestSubstring(self, s: str, k: int) -> int: + # 中文注释:获取所有出现次数小于k的字符的位置索引,包括首尾位置 br = [-1] + [i for i, c in enumerate(s) if s.count(c) < k] + [len(s)] - return len(s) if len(br) == 2 else max(self.longestSubstring(s[br[i - 1] + 1:br[i]], k) for i in range(1, len(br))) \ No newline at end of file + + # 中文注释:如果分割后的子串只有一个,则返回原字符串长度;否则递归计算每个子串的最大满足条件的长度并取最大值 + return len(s) if len(br) == 2 else max(self.longestSubstring(s[br[i - 1] + 1:br[i]], k) for i in range(1, len(br))) diff --git a/solutions/python3/396.py b/solutions/python3/396.py index 91c28ce..1feeccc 100644 --- a/solutions/python3/396.py +++ b/solutions/python3/396.py @@ -1,8 +1,27 @@ + class Solution: def maxRotateFunction(self, A): """ :type A: List[int] :rtype: int + + 英文注释:定义一个类,包含一个方法用于计算数组A的最大旋转函数值。 + + 1. 初始化最大值mx和数组元素总和sm + 2. 遍历数组A的每个元素,累加当前下标*i*A[i]到mx中 + - 中文注释:初始化最大值mx及数组元素和sm。遍历计算初始的最大旋转函数值。 + + 3. 初始化当前值curr为mx,并从1开始遍历数组A + - 中文注释:初始化当前的累积值curr,从第二个元素开始迭代更新 + - 英文注释:Initialize curr with the initial max value and start iterating from the second element. + + 4. 在每次循环中计算新的curr,并与最大值mx比较更新 + - 英文注释:Update curr by subtracting total sum and adding A[i-1] * length of array, then compare with mx to update it if necessary. + - 中文注释:在每一次迭代中根据公式更新当前的累积值,同时更新最大值。 + + 5. 返回最终的最大旋转函数值mx + - 英文注释:Return the maximum rotation function value. + - 中文注释:返回计算得到的最大旋转函数值。 """ mx, sm = 0, sum(A) for i in range(len(A)): @@ -11,4 +30,4 @@ def maxRotateFunction(self, A): for i in range(1, len(A)): curr = curr - sm + A[i - 1] * len(A) mx = max(mx, curr) - return mx \ No newline at end of file + return mx diff --git a/solutions/python3/397.py b/solutions/python3/397.py index 8171723..43ddefe 100644 --- a/solutions/python3/397.py +++ b/solutions/python3/397.py @@ -1,12 +1,18 @@ + class Solution: def integerReplacement(self, n): """ :type n: int :rtype: int + + 输入一个整数n,返回将其变为1所需的最少操作次数。每次操作可以是将当前数字除以2(如果为偶数)或加减1使其变为偶数。 + - 若n等于1,则无需任何操作,直接返回0。 + - 如果n为偶数,则递归调用自身处理n/2,并将结果加1作为当前操作次数。 + - 如果n为奇数,则分别尝试n+1和n-1两种情况,取最小的操作次数并加1。 """ if n == 1: return 0 elif n % 2 == 0: - return self.integerReplacement(n/2)+1 + return self.integerReplacement(n // 2) + 1 else: - return min(self.integerReplacement(n+1),self.integerReplacement(n-1))+1 \ No newline at end of file + return min(self.integerReplacement(n+1), self.integerReplacement(n-1)) + 1 diff --git a/solutions/python3/398.py b/solutions/python3/398.py index ca790a4..fce5226 100644 --- a/solutions/python3/398.py +++ b/solutions/python3/398.py @@ -1,9 +1,17 @@ + class Solution: - def __init__(self, nums): - self.indexes = collections.defaultdict(set) + def __init__(self, nums): # 初始化类,传入一个整数列表 + """ + :param nums: 初始的整数列表 + """ + self.indexes = collections.defaultdict(set) # 使用字典存储每个数字及其索引集合 for i, num in enumerate(nums): - self.indexes[num].add(i) + self.indexes[num].add(i) # 将当前索引添加到对应数字的集合中 - def pick(self, target): - return random.sample(self.indexes[target], 1)[0] \ No newline at end of file + def pick(self, target): # 根据目标值返回一个随机索引 + """ + :param target: 目标整数 + :return: 返回一个随机选择的目标值对应的索引,保证该索引存在于字典中的目标值集合中 + """ + return random.sample(self.indexes[target], 1)[0] # 使用random.sample从目标值的索引集合中随机选取一个 diff --git a/solutions/python3/399.py b/solutions/python3/399.py index dd17a98..41bc0f9 100644 --- a/solutions/python3/399.py +++ b/solutions/python3/399.py @@ -1,22 +1,62 @@ + class Solution: def calcEquation(self, equations, values, queries): + """ + 计算给定方程组的比值。 + + 参数: + equations (List[Tuple[str, str]]): 方程对列表,每个元素为一个元组表示两个变量之间的关系。 + values (List[float]): 每个方程对应的比值。 + queries (List[Tuple[str, str]]): 需要查询的变量对。 + + 返回: + List[float]: 各个查询结果,如果不存在则返回-1.0。 + """ + def explore(x, y, r, q): + """ + 递归查找两个节点之间的比值关系。 + + 参数: + x (str): 起始节点。 + y (str): 目标节点。 + r (float): 当前路径的乘积结果。 + q (set[str]): 已访问过的节点集合,避免重复计算。 + """ results[(x, y)] = r for z in edges[y]: if z not in q: results[(x, z)], results[(z, x)] = r * vals[(y, z)], 1 / (r * vals[(y, z)]) explore(x, z, r * vals[(y, z)], q | {z}) - edges, vals, visited, results, res = collections.defaultdict(set), {}, set(), {}, [] + + # 边集合 + edges = collections.defaultdict(set) + # 比值字典 + vals = {} + # 已访问的节点集合 + visited = set() + # 查询结果存储 + results = {} + res = [] + + # 构建图结构 for i, eq in enumerate(equations): edges[eq[0]].add(eq[1]) edges[eq[1]].add(eq[0]) vals[(eq[0], eq[1])], vals[(eq[1], eq[0])] = values[i], 1 / values[i] + + # 遍历每个方程中的变量 for i, eq in enumerate(equations): for p in eq: if p not in visited: visited.add(p) explore(p, p, 1.0, {p}) + + # 查询处理 for q in queries: - if (q[0], q[1]) in results: res += results[(q[0], q[1])], - else: res += -1.0, - return res \ No newline at end of file + if (q[0], q[1]) in results: + res += [results[(q[0], q[1])]] + else: + res += [-1.0] + + return res diff --git a/solutions/python3/4.py b/solutions/python3/4.py index ee99f9e..2bdcc77 100644 --- a/solutions/python3/4.py +++ b/solutions/python3/4.py @@ -1,5 +1,16 @@ + class Solution: def findMedianSortedArrays(self, nums1, nums2): + # 合并两个有序数组,并排序 + # Merge and sort two sorted arrays arr = sorted(nums1 + nums2) - if len(arr) % 2 == 0: return (arr[len(arr) // 2] + arr[len(arr) // 2 - 1]) / 2 - else: return arr[len(arr) // 2] \ No newline at end of file + + # 如果合并后的数组长度为偶数,则中位数是中间两个数的平均值 + # If the length of merged array is even, median is the average of the two middle numbers + if len(arr) % 2 == 0: + return (arr[len(arr) // 2] + arr[len(arr) // 2 - 1]) / 2 + + # 如果合并后的数组长度为奇数,则中位数是中间的那个数 + # If the length of merged array is odd, median is the middle number + else: + return arr[len(arr) // 2] diff --git a/solutions/python3/40.py b/solutions/python3/40.py index 6e2f167..960d048 100644 --- a/solutions/python3/40.py +++ b/solutions/python3/40.py @@ -1,15 +1,42 @@ -class Solution: - def combinationSum2(self, candidates, target): + +class Solution: + """ + Combination Sum II + + 组合总和II + + Given a collection of candidate numbers (candidates) and a target number (target), + find all unique combinations in candidates where the candidate numbers sum to target. + Each number in candidates may only be used once in the combination. + + 假设给定一个候选数列表(candidates)和目标值(target),找到所有满足条件的唯一组合, + 使候选数之和等于目标值。每个数字只能在组合中使用一次。 + """ + + def combinationSum2(self, candidates, target): + """ + :param candidates: List[int] - 候选数列表 + :param target: int - 目标值 + :return: List[List[int]] - 所有满足条件的唯一组合 + """ res = [] self.dfs(sorted(candidates), target, 0, [], res) return res - def dfs(self, nums, target, index, path, res): + + def dfs(self, nums, target, index, path, res): + """ + :param nums: List[int] - 排序后的候选数列表 + :param target: int - 当前目标值 + :param index: int - 起始索引 + :param path: List[int] - 当前路径(组合) + :param res: List[List[int]] - 结果集 + """ if target < 0: - return + return if target == 0 and path not in res: res.append(path) - return + return for i in range(index, len(nums)): - if i>1 and nums[i] == nums[i-1]: + if i > 1 and nums[i] == nums[i - 1]: continue - self.dfs(nums[:i] + nums[i+1:], target-nums[i], i, path+[nums[i]], res) \ No newline at end of file + self.dfs(nums[:i] + nums[i + 1:], target - nums[i], i, path + [nums[i]], res) diff --git a/solutions/python3/401.py b/solutions/python3/401.py index f6bbd17..dd4e196 100644 --- a/solutions/python3/401.py +++ b/solutions/python3/401.py @@ -1,9 +1,13 @@ + class Solution: def readBinaryWatch(self, num): """ - :type num: int - :rtype: List[str] + :type num: int # 输入的二进制数位数 + :rtype: List[str] # 返回满足条件的时间列表 + + 构建一个从0到11的小时范围和0到59分钟范围,通过遍历组合小时和分钟,并检查其二进制表示中'1'的数量是否等于num。 """ return ['%d:%02d' % (h, m) - for h in range(12) for m in range(60) - if (bin(h) + bin(m)).count('1') == num] \ No newline at end of file + for h in range(12) # 遍历可能的小时值 + for m in range(60) # 遍历可能的分钟值 + if (bin(h) + bin(m)).count('1') == num] # 检查二进制表示中'1'的数量是否等于num diff --git a/solutions/python3/402.py b/solutions/python3/402.py index f3c9668..c42955a 100644 --- a/solutions/python3/402.py +++ b/solutions/python3/402.py @@ -1,9 +1,20 @@ + class Solution: - def removeKdigits(self, num, k): - out = [] + # 定义一个移除指定数量数字的方法 + def removeKdigits(self, num: str, k: int) -> str: + out = [] # 初始化结果列表 + for digit in num: + # 当k大于0且当前数字小于栈顶元素时,弹出栈顶元素 while k and out and out[-1] > digit: out.pop() k -= 1 + + # 将当前数字压入栈中 out.append(digit) - return ''.join(out[:-k or None]).lstrip('0') or "0" \ No newline at end of file + + # 去除最后k个字符或直至结果为空 + res = ''.join(out[:-k or None]) + + # 移除结果前导零并返回,若结果为空则返回"0" + return res.lstrip('0') or "0" diff --git a/solutions/python3/403.py b/solutions/python3/403.py index 042349c..041b740 100644 --- a/solutions/python3/403.py +++ b/solutions/python3/403.py @@ -1,9 +1,27 @@ + class Solution: + # 判断是否可以跳跃到所有石头上 + def canCross(self, stones): + # 使用字典进行记忆化搜索,存储已经计算过的结果以提高效率 memo, stones, target = {}, set(stones), stones[-1] + def dfs(unit, last): - if unit == target: return True - if (unit, last) not in memo: - memo[(unit, last)] = any(dfs(unit + move, move) for move in (last - 1, last, last + 1) if move and unit + move in stones) + """ + unit: 当前所在位置 + last: 上一次跳跃的步数 + """ + # 如果当前位置等于目标位置,则成功返回 True + if unit == target: + return True + + # 如果该状态未被计算过,进行深度优先搜索 + if (unit, last) not in memo: + # 尝试不同的跳跃步数 + memo[(unit, last)] = any(dfs(unit + move, move) for move in (last - 1, last, last + 1) + if move and unit + move in stones) + return memo[(unit, last)] - return dfs(1, 1) if 1 in stones else False \ No newline at end of file + + # 如果起始位置不是 1,则无法开始跳跃 + return dfs(1, 1) if 1 in stones else False diff --git a/solutions/python3/404.py b/solutions/python3/404.py index 2778f53..0808d4a 100644 --- a/solutions/python3/404.py +++ b/solutions/python3/404.py @@ -1,22 +1,37 @@ + # Definition for a binary tree node. -# class TreeNode: -# def __init__(self, x): -# self.val = x -# self.left = None -# self.right = None +class TreeNode: + def __init__(self, x): + self.val = x + self.left = None + self.right = None class Solution: - def sumOfLeftLeaves(self, root): + # 计算二叉树中所有左叶子节点的和 + def sumOfLeftLeaves(self, root: TreeNode) -> int: """ :type root: TreeNode :rtype: int """ + + # 递归函数,用于遍历节点并收集左叶子节点值 def left(node, sm): - if not node: return - left(node.left,sm) - if node.left: - if not node.left.left and not node.left.right: sm.append(node.left.val) - left(node.right,sm) - otp=list() - left(root,otp) - return sum(otp) \ No newline at end of file + if not node: + return + + # 递归处理左子树 + left(node.left, sm) + + # 检查当前节点的左子节点是否为叶节点 + if node.left and not node.left.left and not node.left.right: + sm.append(node.left.val) + + # 递归处理右子树 + left(node.right, sm) + + # 初始化结果列表 + otp = list() + # 调用递归函数开始遍历 + left(root, otp) + # 返回所有左叶子节点值的和 + return sum(otp) diff --git a/solutions/python3/405.py b/solutions/python3/405.py index 66e2027..34f1adc 100644 --- a/solutions/python3/405.py +++ b/solutions/python3/405.py @@ -1,10 +1,27 @@ + class Solution: - def toHex(self, num): - if not num: return "0" - mp, ans = "0123456789abcdef", "" + def toHex(self, num: int) -> str: + """ + 将给定的整数转换为16进制字符串。 + + 参数: + num (int): 需要转换的整数值 + + 返回: + str: 转换后的16进制字符串 + """ + if not num: + return "0" + + # 用于映射16进制字符 + mp = "0123456789abcdef" + ans = "" + + # 处理最多8次循环,因为int型整数至少可以表示为8个16进制位 for i in range(8): - n = num & 15 - c = mp[n] - ans = c + ans - num = num >> 4 - return ans.lstrip('0') \ No newline at end of file + n = num & 15 # 取最低四位进行转换 + c = mp[n] # 获取对应的十六进制字符 + ans = c + ans # 将当前字符加入结果字符串的开头 + num >>= 4 # 向右移动4位,处理下一位 + + return ans.lstrip('0') # 移除前导零 diff --git a/solutions/python3/406.py b/solutions/python3/406.py index a55fb5d..c002cb9 100644 --- a/solutions/python3/406.py +++ b/solutions/python3/406.py @@ -1,12 +1,24 @@ + class Solution: + # 定义一个类,用于解决重建队列问题 + def reconstructQueue(self, people): + """ + :param people: List[List[int]], 每个元素是一个人高和需要在前面看到的人数的列表 + :return: List[List[int]], 重构后的队列,满足所有人的条件 + """ arr = [0] * len(people) - people.sort() + + # 首先按高度降序排序,如果高度相同则按k升序排序 + people.sort(key=lambda x: (-x[0], x[1])) + for h, k in people: cnt = 0 + # 找到合适的位置插入当前人 for i in range(len(arr)): if not arr[i] or arr[i][0] == h: cnt += 1 if cnt == k + 1: arr[i] = [h, k] - return arr \ No newline at end of file + + return arr diff --git a/solutions/python3/407.py b/solutions/python3/407.py index 36912b1..d4683f2 100644 --- a/solutions/python3/407.py +++ b/solutions/python3/407.py @@ -1,16 +1,30 @@ + class Solution: def trapRainWater(self, heightMap): + """ + 计算给定高度地图中的雨水量 + + :param heightMap: List[List[int]] 高度地图,二维数组表示地形的高度 + :return: int 返回可以存储的水量 + """ + m, n, heap, trapped = len(heightMap), len(heightMap and heightMap[0]), [], 0 + + # 将外圈的格子加入堆中,并标记为已访问(-1) for i in range(m): for j in range(n): if i in {0, m - 1} or j in {0, n - 1}: heapq.heappush(heap, (heightMap[i][j], i, j)) - heightMap[i][j] = -1 + heightMap[i][j] = -1 + + # 处理堆中的每一个格子 while heap: h, i, j = heapq.heappop(heap) for x, y in ((i + 1, j), (i - 1, j), (i, j + 1), (i, j - 1)): + # 检查是否为内部格子且未访问 if 0 < x < m - 1 and 0 < y < n - 1 and heightMap[x][y] != -1: - trapped += max(h - heightMap[x][y], 0) - heapq.heappush(heap, (max(heightMap[x][y], h), x, y)) - heightMap[x][y] = -1 - return trapped \ No newline at end of file + trapped += max(h - heightMap[x][y], 0) # 计算并累加能存储的水量 + heapq.heappush(heap, (max(heightMap[x][y], h), x, y)) # 将当前格子加入堆中 + heightMap[x][y] = -1 # 标记为已访问 + + return trapped diff --git a/solutions/python3/408.py b/solutions/python3/408.py index f9e941e..e4e8637 100644 --- a/solutions/python3/408.py +++ b/solutions/python3/408.py @@ -1,18 +1,30 @@ + class Solution: def validWordAbbreviation(self, word: str, abbr: str) -> bool: + """ + 判断给定的缩写abbr是否可以合法地表示单词word。 + + 参数: + word (str): 原始单词,每个字符都是小写字母。 + abbr (str): 缩写形式,可能包含字母和数字。 + + 返回值: + bool: 如果abbr是合法的word缩写,则返回True;否则返回False。 + """ i = num = 0 for c in abbr: if c.isdigit(): + # 数字字符处理:确保首字符不是'0',且累加数字 if num == 0 and c == '0': return False num = num * 10 + int(c) else: + # 非数字字符处理:跳过数字部分,检查实际单词的对应位置 if num: - #print(i, num) - i += num + i += num num = 0 if i >= len(word) or word[i] != c: - #print(i, c) return False i += 1 - return i == len(word) if num == 0 else i + num == len(word) \ No newline at end of file + # 最后判断是否完整匹配 + return i == len(word) if num == 0 else i + num == len(word) diff --git a/solutions/python3/409.py b/solutions/python3/409.py index b215f40..f9bad2b 100644 --- a/solutions/python3/409.py +++ b/solutions/python3/409.py @@ -1,15 +1,31 @@ + class Solution: def longestPalindrome(self, s): """ :type s: str :rtype: int """ - from collections import Counter - out=even=sum(v for k,v in Counter(s).items() if v%2==0) - odd_big=[v for k,v in Counter(s).items() if v%2!=0 and v>1] - odd_small=[v for k,v in Counter(s).items() if v==1] - if len(odd_big)==1: out+=odd_big[0] + + from collections import Counter # 导入计数器模块 + + # 统计字符出现次数,计算偶数次的字符总数 + out = even = sum(v for k, v in Counter(s).items() if v % 2 == 0) + + # 找出所有奇数次出现且大于1次的字符数量 + odd_big = [v for k, v in Counter(s).items() if v % 2 != 0 and v > 1] + + # 找出只出现一次的字符数量 + odd_small = [v for k, v in Counter(s).items() if v == 1] + + # 如果只有一个奇数次出现且大于1次的字符,则结果加该值 + if len(odd_big) == 1: + out += odd_big[0] else: - out+=sum(odd_big)-len(odd_big)+1 - if len(odd_small)==0 and len(odd_big)==0: out-=1 - return out \ No newline at end of file + # 计算所有奇数次出现且大于1次的字符数量之和减去个数再加一 + out += sum(odd_big) - len(odd_big) + 1 + + # 如果没有只出现一次的字符且没有奇数次出现且大于1次的字符,则结果减一 + if len(odd_small) == 0 and len(odd_big) == 0: + out -= 1 + + return out diff --git a/solutions/python3/41.py b/solutions/python3/41.py index f170aac..4431284 100644 --- a/solutions/python3/41.py +++ b/solutions/python3/41.py @@ -1,6 +1,12 @@ + class Solution: + # 定义一个类来解决寻找数组中第一个缺失的正整数的问题 + def firstMissingPositive(self, nums: List[int], res: int = 1) -> int: + # 初始化结果变量,用于记录最小缺失正整数,默认值为1 for num in sorted(nums): + # 遍历排序后的数组,检查当前数字是否等于结果变量 res += num == res + # 如果相等,则结果变量不变;否则增加结果变量的值 return res - \ No newline at end of file + # 返回最终的结果变量,即最小缺失正整数 diff --git a/solutions/python3/410.py b/solutions/python3/410.py index ed71dd1..1c04e83 100644 --- a/solutions/python3/410.py +++ b/solutions/python3/410.py @@ -1,19 +1,24 @@ + class Solution: + # 定义一个辅助函数来验证分割方式是否满足条件 + def valid(self, mid: int) -> bool: + cnt, sm = 0, 0 + for num in nums: + sm += num + if sm > mid: + cnt += 1 + if cnt >= m: + return False + sm = num + return True + + # 主函数,使用二分查找来找到满足条件的最小分割值 def splitArray(self, nums, m): - def valid(mid): - cnt = sm = 0 - for num in nums: - sm += num - if sm > mid: - cnt += 1 - if cnt>= m: return False - sm = num - return True - l, h = max(nums), sum(nums) + l, h = max(nums), sum(nums) # 初始化搜索范围为数组中的最大值和所有元素之和 while l < h: - mid = (l + h) // 2 - if valid(mid): - h = mid - else: - l = mid + 1 - return l \ No newline at end of file + mid = (l + h) // 2 # 计算中间值 + if self.valid(mid): + h = mid # 如果验证通过,缩小上限 + else: + l = mid + 1 # 否则增加下限 + return l # 返回最终的分割值 diff --git a/solutions/python3/411.py b/solutions/python3/411.py index 2c5cd04..82405e6 100644 --- a/solutions/python3/411.py +++ b/solutions/python3/411.py @@ -1,45 +1,78 @@ + class Solution(object): - def extract_number(self, j, abbr, M): + + # 提取数字,支持多位数 + def extract_number(self, j: int, abbr: str, M: int) -> (int, int): + """ + :param j: 当前索引 + :param abbr: 简写字符串 + :param M: abbr 的长度 + :return: 数字和更新后的索引 + """ num = 0 while j < M and abbr[j].isdigit(): - num, j = num*10 + int(abbr[j]), j+1 + num, j = num * 10 + int(abbr[j]), j + 1 return num, j - def valid(self, word, abbr): - i,j,N, M = 0,0,len(word), len(abbr) + # 验证简写是否有效 + def valid(self, word: str, abbr: str) -> bool: + """ + :param word: 目标单词 + :param abbr: 简写字符串 + :return: 是否为有效的简写 + """ + i, j, N, M = 0, 0, len(word), len(abbr) while i < N and j < M: if abbr[j].isalpha() and abbr[j] != word[i]: return False elif abbr[j].isalpha() and abbr[j] == word[i]: - i,j = i+1,j+1 + i, j = i + 1, j + 1 elif abbr[j].isdigit(): if abbr[j] == '0': return False num, j = self.extract_number(j, abbr, M) - i = i+num - return (i==N and j == M) - - def process_solution(self, so_far): + i += num + return (i == N and j == M) + + # 处理生成的简写 + def process_solution(self, so_far: list) -> (str, int): + """ + :param so_far: 当前构建的简写列表 + :return: 构建的字符串和长度 + """ csofar, i, cnt = [], 0, 0 while i < len(so_far): if so_far[i].isalpha(): csofar.append(so_far[i]) - i, cnt = i+1, cnt+1 + i, cnt = i + 1, cnt + 1 else: num = 0 while i < len(so_far) and so_far[i].isdigit(): - num, i = num+1, i+1 - cnt = cnt + 1 + num, i = num + 1, i + 1 + cnt += 1 csofar.append(str(num)) return "".join(csofar), cnt - - def test(self, abbr, dictionary): + + # 检查简写是否在字典中有效 + def test(self, abbr: str, dictionary: list) -> bool: + """ + :param abbr: 简写字符串 + :param dictionary: 字典列表 + :return: 是否为有效简写 + """ for wrd in dictionary: if self.valid(wrd, abbr): return False return True - - def helper(self, word, so_far, i, dictionary): + + # 辅助函数,递归构建简写 + def helper(self, word: str, so_far: list, i: int, dictionary: list) -> None: + """ + :param word: 目标单词 + :param so_far: 当前构建的简写列表 + :param i: 当前索引 + :param dictionary: 字典列表 + """ if i == len(word): abbr, cnt = self.process_solution(so_far) if cnt < self.result_len and self.test(abbr, dictionary): @@ -47,21 +80,21 @@ def helper(self, word, so_far, i, dictionary): return else: so_far.append("1") - self.helper(word, so_far, i+1, dictionary) + self.helper(word, so_far, i + 1, dictionary) so_far.pop() so_far.append(word[i]) - self.helper(word, so_far, i+1, dictionary) + self.helper(word, so_far, i + 1, dictionary) so_far.pop() - def minAbbreviation(self, target, dictionary): + # 主函数,找到最简缩写 + def minAbbreviation(self, target: str, dictionary: list) -> str: """ :type target: str :type dictionary: List[str] :rtype: str """ - - # Remove those words which can never be an abbreviation for target. - # This preprocessing will help us save time. + + # 预处理:过滤掉那些不可能的单词 filtered_dictionary = [] for wrd in dictionary: if len(wrd) != len(target): @@ -70,8 +103,8 @@ def minAbbreviation(self, target, dictionary): dictionary = filtered_dictionary if len(dictionary) == 0: return str(len(target)) - - self.result_len = len(target)+1 + + self.result_len = len(target) + 1 self.result, so_far, i = target, [], 0 - self.helper(target, so_far, i, dictionary) - return self.result \ No newline at end of file + self.helper(target, so_far, i, dictionary) + return self.result diff --git a/solutions/python3/412.py b/solutions/python3/412.py index 780d3c0..8bf8603 100644 --- a/solutions/python3/412.py +++ b/solutions/python3/412.py @@ -1,17 +1,18 @@ + class Solution: - def fizzBuzz(self, n): + def fizzBuzz(self, n: int) -> list[str]: """ - :type n: int - :rtype: List[str] + :param n: 输入的整数n,表示需要生成FizzBuzz序列的长度。 + :return: 返回一个包含字符串元素的列表,按照规则生成FizzBuzz序列。 """ - num = [] + result = [] # 使用更通用的名字result代替num for i in range(1, n + 1): if i % 3 == 0 and i % 5 == 0: - num.append("FizzBuzz") + result.append("FizzBuzz") elif i % 3 == 0: - num.append("Fizz") + result.append("Fizz") elif i % 5 == 0: - num.append("Buzz") + result.append("Buzz") else: - num.append(str(i)) - return num \ No newline at end of file + result.append(str(i)) + return result diff --git a/solutions/python3/413.py b/solutions/python3/413.py index 50ab7e6..411f22d 100644 --- a/solutions/python3/413.py +++ b/solutions/python3/413.py @@ -1,13 +1,25 @@ + class Solution: + # 定义一个类来解决问题 + def numberOfArithmeticSlices(self, A): + # 检查数组A长度是否小于3,如果是返回0 if len(A) < 3: return 0 + + # 在数组末尾添加一个无穷大的数以处理边界情况 A.append(float("inf")) + + # 初始化变量:d为当前差值, l为差值起始位置, n为A的长度,res为结果计数器 d, l, n, res = A[1] - A[0], 0, len(A), 0 + for i in range(2, n): + # 如果当前元素与前一个元素的差值不等于d,则更新结果并重置d和l if d != A[i] - A[i - 1]: diff = i - l - 2 if diff > 0: res += diff * (diff + 1) // 2 d, l = A[i] - A[i - 1], i - 1 - return res \ No newline at end of file + + # 返回结果计数器res的值 + return res diff --git a/solutions/python3/414.py b/solutions/python3/414.py index 2b749a2..1275d8d 100644 --- a/solutions/python3/414.py +++ b/solutions/python3/414.py @@ -1,10 +1,24 @@ + class Solution: def thirdMax(self, nums): """ :type nums: List[int] :rtype: int + + 输入:一个整数列表nums。 + 输出:如果三个不同的最大值存在,则返回第三个最大的值;否则,返回列表中的最大值。 + 中文注释: + - 首先去重并存储在一个新的列表s中 + - 如果列表s的最后一个元素小于第一个元素,说明全是负数或特殊情况,此时过滤掉所有非正数 + - 判断列表长度是否大于等于3,如果是返回倒数第三个元素(即第三大值) + - 否则返回列表中的最大值(即最后一个元素) """ - s=list(set(nums)) - if s[-1]=0] - if len(s)>=3: return s[-3] - else: return s[-1] \ No newline at end of file + s = list(set(nums)) # 去重并存储在s中 + + if s[-1] < s[0]: # 如果最后一个元素小于第一个元素,说明全是负数或特殊情况 + s = [item for item in s if item >= 0] # 过滤掉所有非正数 + + if len(s) >= 3: # 判断列表长度是否大于等于3 + return s[-3] # 返回倒数第三个元素(即第三大值) + else: + return s[-1] # 返回列表中的最大值(即最后一个元素) diff --git a/solutions/python3/415.py b/solutions/python3/415.py index 06eb10b..14e47a4 100644 --- a/solutions/python3/415.py +++ b/solutions/python3/415.py @@ -1,8 +1,16 @@ + class Solution: - def addStrings(self, num1, num2): + def addStrings(self, num1: str, num2: str) -> str: """ - :type num1: str - :type num2: str - :rtype: str + :type num1: str # 字符串num1 + :type num2: str # 字符串num2 + :rtype: str # 返回相加后的字符串结果 """ - return "".join(str(sum([(ord(num1[i])-ord("0"))*(10**(len(num1)-1-i)) for i in range(len(num1))]+[(ord(num2[i])-ord("0"))*(10**(len(num2)-1-i)) for i in range(len(num2))]))) \ No newline at end of file + # 计算num1的数值并累加到result中 + result = sum((ord(num1[i]) - ord('0')) * (10 ** (len(num1) - 1 - i)) for i in range(len(num1))) + + # 计算num2的数值并累加到result中 + result += sum((ord(num2[i]) - ord('0')) * (10 ** (len(num2) - 1 - i)) for i in range(len(num2))) + + # 将最终结果转换为字符串并返回 + return str(result) diff --git a/solutions/python3/416.py b/solutions/python3/416.py index 1ed23ea..cd4c07f 100644 --- a/solutions/python3/416.py +++ b/solutions/python3/416.py @@ -1,12 +1,22 @@ + class Solution: def canPartition(self, nums): - sm, n = sum(nums), len(nums) - if sm % 2: + """ + 判断给定的整数列表是否可以被分割成两个子集,使得两个子集的元素和相等。 + + 中文注释: 判断给定的整数列表是否可以被分割成两个子集,使得两个子集的元素和相等。 + """ + sm, n = sum(nums), len(nums) # 计算总和并获取长度 + if sm % 2: # 如果总和为奇数,则无法分割为两个等和子集 return False - sm //= 2 - dp = [False] * (sm + 1) - dp[0] = True + + sm //= 2 # 目标和为总和的一半 + + dp = [False] * (sm + 1) # 初始化动态规划数组 + dp[0] = True # 空集合的和可以认为是0,所以初始化第一个值为True + for num in nums: - for j in range(num, sm + 1)[::-1]: + for j in range(num, sm + 1)[::-1]: # 从大到小遍历dp数组 dp[j] = dp[j] or dp[j - num] - return dp[-1] \ No newline at end of file + return dp[-1] # 最后一个元素是否可以达到目标和 + \ No newline at end of file diff --git a/solutions/python3/417.py b/solutions/python3/417.py index cc7a5a2..34e05fc 100644 --- a/solutions/python3/417.py +++ b/solutions/python3/417.py @@ -1,15 +1,52 @@ + class Solution: def pacificAtlantic(self, matrix): - pac, atl, m, n = set(), set(), len(matrix), len(matrix and matrix[0]) - def explore(i, j, ocean): + """ + Pacific Atlantic Water Flow Problem + + :param matrix: List[List[int]], a matrix representing elevation heights + :return: List[List[int]], positions that can flow to both the Pacific and Atlantic oceans + """ + + if not matrix or not matrix[0]: + return [] + + pac, atl, m, n = set(), set(), len(matrix), len(matrix[0]) + + """ + Explore function for dfs. + It adds current position to visited set if it can flow from current cell. + :param i: row index + :param j: column index + :param ocean: the set of cells that can flow into this ocean + """ + def explore(i, j, ocean): ocean.add((i, j)) - if i > 0 and (i - 1, j) not in ocean and matrix[i - 1][j] >= matrix[i][j]: explore(i - 1, j, ocean) - if j > 0 and (i, j - 1) not in ocean and matrix[i][j - 1] >= matrix[i][j]: explore(i, j - 1, ocean) - if i + 1 < m and (i + 1, j) not in ocean and matrix[i + 1][j] >= matrix[i][j]: explore(i + 1, j, ocean) - if j + 1 < n and (i, j +1) not in ocean and matrix[i][j + 1] >= matrix[i][j]: explore(i, j + 1, ocean) - for i in range(max(m, n)): - if i < m and (i, 0) not in pac: explore(i, 0, pac) - if i < n and (0, i) not in pac: explore(0, i, pac) - if i < n and (m - 1, i) not in atl: explore(m - 1, i, atl) - if i < m and (i, n - 1) not in atl: explore(i, n - 1, atl) - return [[x, y] for x, y in pac & atl] \ No newline at end of file + # Check top and left neighbors for Pacific Ocean exploration + if i > 0 and (i - 1, j) not in ocean and matrix[i - 1][j] >= matrix[i][j]: + explore(i - 1, j, ocean) + # Check bottom neighbor for Atlantic Ocean exploration + if i + 1 < m and (i + 1, j) not in ocean and matrix[i + 1][j] >= matrix[i][j]: + explore(i + 1, j, ocean) + # Check left neighbor for Pacific Ocean exploration + if j > 0 and (i, j - 1) not in ocean and matrix[i][j - 1] >= matrix[i][j]: + explore(i, j - 1, ocean) + # Check right neighbor for Atlantic Ocean exploration + if j + 1 < n and (i, j + 1) not in ocean and matrix[i][j + 1] >= matrix[i][j]: + explore(i, j + 1, ocean) + + # Explore boundaries to identify cells that can flow into Pacific or Atlantic + for i in range(m): + if (i, 0) not in pac: + explore(i, 0, pac) + if (m - 1, i) not in atl: + explore(m - 1, i, atl) + + for j in range(n): + if (0, j) not in pac: + explore(0, j, pac) + if (i, n - 1) not in atl: + explore(i, n - 1, atl) + + # Return cells that can flow into both oceans + return [[x, y] for x, y in pac & atl] diff --git a/solutions/python3/418.py b/solutions/python3/418.py index 9575b66..3833de3 100644 --- a/solutions/python3/418.py +++ b/solutions/python3/418.py @@ -1,13 +1,23 @@ + class Solution: + # 定义一个类来解决单词排版问题 + def wordsTyping(self, sentence, rows, cols): + # 初始化一些变量,用于记录每个单词的起始位置、当前行的剩余空格数、当前指针位置和单个单词长度 left, count, sm, ptr, wordLen = [0] * len(sentence), 0, 0, 0, len(sentence[0]) + + # 遍历每个单词,计算每个单词在一行中占据的空间 for i, w in enumerate(sentence): while sm + wordLen <= cols: - sm += wordLen - ptr += 1 - wordLen = len(sentence[ptr % len(sentence)]) + 1 - left[i] = ptr - i - sm -= len(w) + 1 + sm += wordLen # 当前指针指向的单词长度加到剩余空格数上 + ptr += 1 # 指针右移一个位置 + wordLen = len(sentence[ptr % len(sentence)]) + 1 # 更新下一个单词的长度 + + left[i] = ptr - i # 记录当前单词开始的位置 + sm -= len(w) + 1 # 减去当前单词和空格,为下次计算做准备 + + # 遍历行数,累加每个单词的起始位置信息 for r in range(rows): count += left[count % len(sentence)] - return count // len(sentence) \ No newline at end of file + + return count // len(sentence) # 返回最终结果 diff --git a/solutions/python3/419.py b/solutions/python3/419.py index 8561f04..b576e1e 100644 --- a/solutions/python3/419.py +++ b/solutions/python3/419.py @@ -1,3 +1,19 @@ + class Solution: def countBattleships(self, board): - return sum(board[i][j] == "X" and (i == 0 or board[i - 1][j] == ".") and (j == 0 or board[i][j - 1] == ".") for i in range(len(board)) for j in range(len(board[0]))) \ No newline at end of file + """ + 计算海图上战舰的数量。 + + 通过遍历二维数组,判断每个 "X" 是否代表一艘完整的战舰。 + + :param board: List[List[str]] - 海图的表示形式,'.' 表示水,'X' 表示战舰的一部分 + :return: int - 战舰的数量 + """ + # 使用生成器表达式来计算战舰数量,优化性能并减少内存使用 + return sum( + board[i][j] == "X" # 当前位置是 "X" + and (i == 0 or board[i-1][j] == ".") # 上方不是 "X" + and (j == 0 or board[i][j-1] == ".") # 左侧不是 "X" + for i in range(len(board)) # 遍历行 + for j in range(len(board[0])) # 遍历列 + ) diff --git a/solutions/python3/42.py b/solutions/python3/42.py index 7410ae5..8ff1c63 100644 --- a/solutions/python3/42.py +++ b/solutions/python3/42.py @@ -1,14 +1,24 @@ + class Solution: + # 定义一个解决方案类 + def trap(self, height): + # 初始化结果变量res,左右边界字典left,以及左右最高点l和r res, left, l, r = 0, {}, 0, 0 + + # 遍历height数组计算左侧最高墙的高度 for i, h in enumerate(height): left[i] = l - if h > l: + if h > l: l = h + + # 反向遍历height数组,计算储水量 for i in range(len(height) - 1, -1, -1): - roof = min(left[i] , r) + roof = min(left[i], r) if roof > height[i]: res += roof - height[i] if height[i] > r: r = height[i] - return res \ No newline at end of file + + # 返回总的储水量 + return res diff --git a/solutions/python3/420.py b/solutions/python3/420.py index a3ac09c..e49ad87 100644 --- a/solutions/python3/420.py +++ b/solutions/python3/420.py @@ -1,39 +1,49 @@ + class Solution(object): def strongPasswordChecker(self, s): """ :type s: str :rtype: int """ + + # 计算缺失的类型数量 missing_type = 3 - if any('a' <= c <= 'z' for c in s): missing_type -= 1 - if any('A' <= c <= 'Z' for c in s): missing_type -= 1 - if any(c.isdigit() for c in s): missing_type -= 1 + if any('a' <= c <= 'z' for c in s): + missing_type -= 1 # 检查小写字母 + if any('A' <= c <= 'Z' for c in s): + missing_type -= 1 # 检查大写字母 + if any(c.isdigit() for c in s): + missing_type -= 1 # 检查数字 - change = 0 - one = two = 0 - p = 2 + change = 0 # 需要改变的操作数 + one = two = 0 # len=3, len=2的重复字符数量 + p = 2 # 开始检查从索引2开始 + while p < len(s): - if s[p] == s[p-1] == s[p-2]: - length = 2 + if s[p] == s[p-1] == s[p-2]: # 检查三个连续相同字符 + length = 2 # 初始化重复长度为2 while p < len(s) and s[p] == s[p-1]: - length += 1 + length += 1 # 增加重复长度 p += 1 - change += length // 3 - if length % 3 == 0: one += 1 - elif length % 3 == 1: two += 1 + change += length // 3 # 计算需要的操作数 + if length % 3 == 0: + one += 1 # 长度为3的重复序列数量+1 + elif length % 3 == 1: + two += 1 # 长度为2的余1的重复序列数量+1 else: - p += 1 + p += 1 # 移动指针 - if len(s) < 6: - return max(missing_type, 6 - len(s)) - elif len(s) <= 20: - return max(missing_type, change) + # 根据字符串长度计算需要的操作数 + if len(s) < 6: + return max(missing_type, 6 - len(s)) # 字符串太短,返回缺失类型或补足长度的最大值 + elif len(s) <= 20: + return max(missing_type, change) # 长度在合理范围内,返回缺失类型或改变操作数的最大值 else: - delete = len(s) - 20 + delete = len(s) - 20 # 计算删除的字符数量 + + change -= min(delete, one) # 尽量删除重复序列中的一个3长度 + change -= min(max(delete - one, 0), two * 2) // 2 # 删除两个长度为2的重复序列,但优先处理余1的情况 + change -= max(delete - one - 2 * two, 0) // 3 # 删除单个字符来优化剩余的操作数 - change -= min(delete, one) - change -= min(max(delete - one, 0), two * 2) // 2 - change -= max(delete - one - 2 * two, 0) // 3 - - return delete + max(missing_type, change) \ No newline at end of file + return delete + max(missing_type, change) # 返回删除操作和最终改变操作的最大值 diff --git a/solutions/python3/421.py b/solutions/python3/421.py index 09f609e..ebe8913 100644 --- a/solutions/python3/421.py +++ b/solutions/python3/421.py @@ -1,14 +1,37 @@ + class Solution: - def findMaximumXOR(self, nums, ans = 0): + def findMaximumXOR(self, nums, ans=0): + """ + 寻找给定数组中的最大异或值。 + + Args: + nums (List[int]): 输入整数列表。 + ans (int): 累计结果,默认为0。 + + Returns: + int: 给定数组中任意两个数的最大异或值。 + """ ans = 0 for bit in range(30, -1, -1): + # 将当前的ans左移一位,相当于在二进制表示中增加一个0 ans <<= 1 + + # 尝试将当前位设置为1,并记录是否可以形成最大异或值 attempt = ans | 1 + + # 使用集合存储前缀值 prefix = set() + for x in nums: + # 计算当前x在第bit位的前缀值 p = x >> bit + + # 如果存在一个之前出现过的前缀,与尝试的值异或后等于ans,则更新最大结果 if attempt ^ p in prefix: ans = attempt break + + # 将当前前缀添加到集合中 prefix.add(p) - return ans \ No newline at end of file + + return ans diff --git a/solutions/python3/422.py b/solutions/python3/422.py index 46d50eb..865d868 100644 --- a/solutions/python3/422.py +++ b/solutions/python3/422.py @@ -1,9 +1,21 @@ + class Solution: + # 判断给定的单词列表是否构成一个有效的词方阵 + def validWordSquare(self, words): + # 遍历每一行(即每个单词) for j, row in enumerate(words): - col = "" + col = "" # 初始化列字符串 + + # 构建当前行对应的列 for s in words: - try: col += s[j] - except: break - if row != col: return False - return True \ No newline at end of file + try: + col += s[j] # 拼接字符到列字符串中 + except: + break # 如果超出范围,终止构建 + + # 判断当前行是否与构建的列相等 + if row != col: + return False + + return True # 所有行都满足条件,则返回True diff --git a/solutions/python3/424.py b/solutions/python3/424.py index efaf3c5..c6c82f6 100644 --- a/solutions/python3/424.py +++ b/solutions/python3/424.py @@ -1,15 +1,27 @@ + class Solution: - def characterReplacement(self, s, k): + def characterReplacement(self, s: str, k: int) -> int: """ :type s: str :type k: int :rtype: int """ + + # 初始化字典、起始位置和结束位置 dic, start, end = {}, 0, 0 - for end in range(1, len(s)+1): - if not s[end-1] in dic: dic[s[end-1]] = 1 - else: dic[s[end-1]] += 1 - if end-start-max(dic.values()) > k: + + # 遍历字符串,从1到len(s) + for end in range(1, len(s) + 1): + if s[end-1] not in dic: + dic[s[end-1]] = 1 + else: + dic[s[end-1]] += 1 + + # 如果当前窗口中最多字符出现次数小于k,则继续扩大窗口 + if end - start - max(dic.values()) > k: + # 否则,减少起始位置字符的计数,并移动起始位置指针 dic[s[start]] -= 1 start += 1 - return end-start \ No newline at end of file + + # 返回最终结果:结束位置减去起始位置即为最大长度 + return end - start diff --git a/solutions/python3/425.py b/solutions/python3/425.py index db0f9d6..56cda09 100644 --- a/solutions/python3/425.py +++ b/solutions/python3/425.py @@ -1,15 +1,42 @@ + class Solution: - def wordSquares(self, words): - pref, res = collections.defaultdict(set), [] + def wordSquares(self, words: List[str]) -> List[List[str]]: + """ + :param words: 一个单词列表 + :return: 返回所有可能的正方形单词组合 + """ + + from collections import defaultdict + + # 使用defaultdict存储前缀及其对应的所有单词集合,以加快查找速度 + pref = defaultdict(set) + for w in words: + # 构建每个单词的所有长度的前缀,并添加到相应的前缀集合中 for i in range(len(w)): pref[w[:i + 1]].add(w) - def dfs(i, arr): + + def dfs(i: int, arr: List[str]) -> None: + """ + 深度优先搜索函数,用于构建正方形单词组合 + + :param i: 当前处理的行索引 + :param arr: 当前行已填入的单词列表 + """ if i == len(arr[0]): + # 所有单词均按规则填充完成,则添加结果集 res.append(arr) else: - for w in pref["".join(row[i] for row in arr)]: - dfs(i + 1, arr + [w]) + # 获取当前列的候选单词集合 + next_words = pref["".join(row[i] for row in arr)] + + for w in next_words: + # 递归尝试添加下一个单词,并进入下一层搜索 + dfs(i + 1, arr + [w]) + + # 从每个单词开始,尝试构建正方形单词组合 + res = [] for w in words: dfs(1, [w]) - return res \ No newline at end of file + + return res diff --git a/solutions/python3/426.py b/solutions/python3/426.py index 0bb0694..4bf3c8f 100644 --- a/solutions/python3/426.py +++ b/solutions/python3/426.py @@ -1,23 +1,40 @@ + class Solution: def treeToDoublyList(self, root): + # 初始化头节点和尾节点指针 head, tail = [None], [None] + + # 深度优先搜索函数,参数为当前节点和前驱节点 def dfs(node, pre): if not node: return + + # 递归处理左子树 l = dfs(node.left, pre) - new = Node(node.val, l or pre, None) + + # 创建新节点,并连接前驱节点 + new_node = Node(node.val, l or pre, None) if pre and not l: - pre.right = new + pre.right = new_node elif l: - l.right = new + l.right = new_node + + # 更新头尾节点指针 if not pre and not l: - head[0] = new + head[0] = new_node if not tail[0] or node.val > tail[0].val: - tail[0] = new - r = dfs(node.right, new) - return r if r else new + tail[0] = new_node + + # 递归处理右子树 + r = dfs(node.right, new_node) + return r if r else new_node + + # 开始深度优先搜索,从根节点开始 dfs(root, None) + + # 连接头尾节点形成循环链表 if head[0]: head[0].left = tail[0] tail[0].right = head[0] - return head[0] \ No newline at end of file + + return head[0] diff --git a/solutions/python3/427.py b/solutions/python3/427.py index 7f14e08..3ede7e0 100644 --- a/solutions/python3/427.py +++ b/solutions/python3/427.py @@ -1,17 +1,47 @@ + class Solution: def construct(self, grid): + """ + 构建四叉树。给定一个二维的01矩阵,构建一个四叉树。 + + :param grid: 二维列表,包含0和1,表示矩阵 + :return: 四叉树根节点 + """ + def dfs(x, y, l): + """ + 深度优先搜索递归构建四叉树。 + + :param x: 当前子区域左上角的x坐标 + :param y: 当前子区域左上角的y坐标 + :param l: 当前子区域的边长 + :return: 当前子区域对应的节点 + """ if l == 1: - node = Node(grid[x][y] == 1, True, None, None, None, None) + # 如果当前子区域只有一个元素,返回一个叶子结点 + return Node(grid[x][y] == 1, True, None, None, None, None) else: - tLeft = dfs(x, y, l // 2) - tRight = dfs(x, y + l // 2, l // 2) - bLeft = dfs(x + l // 2, y, l// 2) - bRight = dfs(x + l // 2, y + l // 2, l // 2) - value = tLeft.val or tRight.val or bLeft.val or bRight.val - if tLeft.isLeaf and tRight.isLeaf and bLeft.isLeaf and bRight.isLeaf and tLeft.val == tRight.val == bLeft.val == bRight.val: - node = Node(value, True, None, None, None, None) + tLeft = dfs(x, y, l // 2) # 左上子区域 + tRight = dfs(x, y + l // 2, l // 2) # 右上子区域 + bLeft = dfs(x + l // 2, y, l // 2) # 左下子区域 + bRight = dfs(x + l // 2, y + l // 2, l // 2) # 右下子区域 + + value = tLeft.val or tRight.val or bLeft.val or bRight.val # 当前子树的值 + + if (tLeft.isLeaf and + tRight.isLeaf and + bLeft.isLeaf and + bRight.isLeaf and + tLeft.val == tRight.val == bLeft.val == bRight.val): + # 如果所有子节点都是叶子且值相同,则合并为一个叶子结点 + return Node(value, True, None, None, None, None) else: - node = Node(value, False, tLeft, tRight, bLeft, bRight) - return node - return grid and dfs(0, 0, len(grid)) or None \ No newline at end of file + # 否则,返回当前非叶子结点 + return Node(value, False, tLeft, tRight, bLeft, bRight) + + if grid: + # 如果grid不为空,则从(0, 0)开始构建四叉树 + return dfs(0, 0, len(grid)) + else: + # 否则返回None + return None diff --git a/solutions/python3/43.py b/solutions/python3/43.py index 2560973..f431219 100644 --- a/solutions/python3/43.py +++ b/solutions/python3/43.py @@ -1,4 +1,19 @@ + class Solution: - def multiply(self, num1, num2): - dic, l1, l2 = {str(i): i for i in range(10)}, len(num1) - 1, len(num2) - 1 - return str(sum([dic[n1] * (10**(l1-i)) for i, n1 in enumerate(num1)]) * sum([dic[n2] * (10**(l2-j)) for j, n2 in enumerate(num2)])) \ No newline at end of file + # 初始化数字字典和字符串长度 + def __init__(self): + self.dic = {str(i): i for i in range(10)} + + def multiply(self, num1: str, num2: str) -> str: + """ + :param num1: 第一个乘数,字符串形式 + :param num2: 第二个乘数,字符串形式 + :return: 两个乘数的积,字符串形式 + """ + + # 计算每个数字在各自位置上的值,并求和转换成整数 + n1 = sum(self.dic[n] * (10 ** (len(num1) - i - 1)) for i, n in enumerate(num1)) + n2 = sum(self.dic[n] * (10 ** (len(num2) - j - 1)) for j, n in enumerate(num2)) + + # 计算乘积并返回结果 + return str(n1 * n2) diff --git a/solutions/python3/432.py b/solutions/python3/432.py index 092d498..0a9ad72 100644 --- a/solutions/python3/432.py +++ b/solutions/python3/432.py @@ -1,81 +1,91 @@ + class Node: + # 节点类,包含键值对、前后节点指针 def __init__(self, key, value): - self.val = value - self.key = key - self.next = None - self.pre = None -class AllOne: + self.val = value # 值 + self.key = key # 键 + self.next = None # 后一个节点 + self.pre = None # 前一个节点 +class AllOne: + # 包含键值对操作的数据结构 + def __init__(self): - self.first = {} - self.last = {} - self.keys = {} - self.head = Node(-1, -1) - self.tail = Node(-1, -1) - self.head.next = self.tail + # 初始化双向链表的头尾哨兵节点以及键值映射字典 + self.first = {} # 小于等于当前值的第一个节点 + self.last = {} # 大于等于当前值的最后一个节点 + self.keys = {} # 键到节点的映射 + self.head = Node(-1, -1) # 双向链表头哨兵 + self.tail = Node(-1, -1) # 双向链表尾哨兵 + self.head.next = self.tail # 头尾相连形成循环链表 self.tail.pre = self.head - + def add(self, prev, node): + # 将节点添加到双向链表中 node.pre = prev node.next = prev.next node.pre.next = node.next.pre = node - + def remove(self, node): + # 从双向链表中移除节点 node.pre.next = node.next node.next.pre = node.pre - + def process(self, node): if self.last[node.val] == node and node.pre.val != node.val: self.first.pop(node.val) - self.last.pop(node.val) + self.last.pop(node.val) # 处理当前节点为链表尾部且前后键值不相等的情况 elif self.first[node.val] == node: - self.first[node.val] = node.next + self.first[node.val] = node.next # 更新第一个节点的映射 elif self.last[node.val] == node: - self.last[node.val] = node.pre - + self.last[node.val] = node.pre # 更新最后一个节点的映射 + def process2(self, node, prev, key, d): if key in self.keys: if node.val + d in self.last: - self.add(self.last[node.val + d], node) + self.add(self.last[node.val + d], node) # 增加操作:将节点添加到下一个链表位置 elif node.val in self.last: self.add(self.last[node.val], node) else: - self.add(prev, node) - elif 1 in self.last: + self.add(prev, node) # 处理边界情况 + elif 1 in self.last: # 初始化操作(最小值) node = Node(key, 0) self.add(self.last[1], node) else: node = Node(key, 0) self.add(self.head, node) - node.val += d - self.last[node.val] = node + node.val += d # 更新节点的值 + self.last[node.val] = node # 更新当前最大值的映射 if node.val not in self.first: - self.first[node.val] = node - if key not in self.keys: + self.first[node.val] = node # 初始化当前最小值的映射 + if key not in self.keys: # 键到节点初始化映射 self.keys[key] = node - + def inc(self, key): if key in self.keys: node = self.keys[key] prev = node.pre self.process(node) - self.remove(node) + self.remove(node) # 当键值存在于字典中时,增加操作的处理流程 self.process2(node, prev, key, 1) else: self.process2(None, None, key, 1) - + def dec(self, key): if key in self.keys: node = self.keys[key] prev = node.pre self.process(node) - self.remove(node) - if node.val != 1: + self.remove(node) # 当键值存在于字典中时,减少操作的处理流程 + if node.val != 1: # 判断当前节点是否为最小值(val=1) self.process2(node, prev, key, -1) else: self.keys.pop(key) - + else: + pass + def getMaxKey(self): - return self.tail.pre.key if self.tail.pre != self.head else "" + return self.tail.pre.key if self.tail.pre != self.head else "" # 获取最大键 + def getMinKey(self): - return self.head.next.key if self.head.next != self.tail else "" \ No newline at end of file + return self.head.next.key if self.head.next != self.tail else "" # 获取最小键 diff --git a/solutions/python3/433.py b/solutions/python3/433.py index 95628d0..9b2ae65 100644 --- a/solutions/python3/433.py +++ b/solutions/python3/433.py @@ -1,20 +1,31 @@ + class Solution: def minMutation(self, start: str, end: str, bank: List[str]) -> int: - bfs = [start] - genes = set(bank) - cnt = 0 + """ + :param start: 起始基因序列 (Initial gene sequence) + :param end: 目标基因序列 (Target gene sequence) + :param bank: 可用的基因变异序列集合 (Set of available gene sequences for mutation) + :return: 从起始基因到目标基因所需的最小变异次数,如果无法达到则返回-1 (Minimum number of mutations required to reach the target gene, or -1 if impossible) + """ + + bfs = [start] # 使用广度优先搜索进行层级遍历 + genes = set(bank) # 将可用的基因序列集合化以提高查找效率 + cnt = 0 # 记录变异次数 + while bfs: - arr = [] + arr = [] # 用于存储当前层级可到达的新基因序列 for g in bfs: - if g == end: + if g == end: # 如果当前基因序列为目标序列,返回当前的变异次数 return cnt - for i, c in enumerate(g): - for new in 'AGTC': - if new != c: - s = g[:i] + new + g[i + 1:] - if s in genes: - arr.append(s) - genes.discard(s) - bfs = arr - cnt += 1 - return -1 \ No newline at end of file + for i, c in enumerate(g): # 遍历当前基因序列中的每一个字符 + for new in 'AGTC': # 对于每个可能的新字符进行尝试 + if new != c: # 如果新字符与原字符不同 + s = g[:i] + new + g[i + 1:] # 构造新的基因序列 + if s in genes: # 如果该序列存在于可用的基因序列集合中 + arr.append(s) # 将其加入当前层级可到达的新序列列表 + genes.discard(s) # 并从集合中移除以避免重复访问 + + bfs = arr # 更新下一层级可访问的基因序列 + cnt += 1 # 变异次数加一 + + return -1 # 如果没有找到目标序列,返回-1 diff --git a/solutions/python3/434.py b/solutions/python3/434.py index a9915ec..c67c68e 100644 --- a/solutions/python3/434.py +++ b/solutions/python3/434.py @@ -1,8 +1,9 @@ + class Solution: + # 计算字符串s中的单词个数 def countSegments(self, s): """ - :type s: str - :rtype: int + :param s: 字符串(str) + :return: 返回字符串中单词的数量 (int) """ return len(s.split()) - \ No newline at end of file diff --git a/solutions/python3/435.py b/solutions/python3/435.py index 0f4366f..8c91482 100644 --- a/solutions/python3/435.py +++ b/solutions/python3/435.py @@ -1,3 +1,4 @@ + # Definition for an interval. # class Interval: # def __init__(self, s=0, e=0): @@ -5,9 +6,21 @@ # self.end = e class Solution: + # 优化:通过按结束时间排序来减少重叠区间 def eraseOverlapIntervals(self, intervals): - intervals.sort(key = lambda x: x.end); res, curr = 0, -float("inf") + """ + :type intervals: List[Interval] + :rtype: int + """ + intervals.sort(key=lambda x: x.end) # 按照区间结束时间进行升序排序 + + res = 0 # 记录需要移除的重叠区间数量 + curr = -float("inf") # 初始化当前选择区间的终点为负无穷,确保第一个区间能被选中 + for i in intervals: - if curr > i.start: res += 1 - else: curr = i.end - return res \ No newline at end of file + if curr > i.start: # 当前选择的区间和下一个区间有重叠 + res += 1 # 增加需要移除的数量 + else: # 如果没有重叠 + curr = i.end # 更新当前选择区间的终点为下一个区间的结束时间 + + return res # 返回需要移除的重叠区间数量 diff --git a/solutions/python3/436.py b/solutions/python3/436.py index dcef026..dc26554 100644 --- a/solutions/python3/436.py +++ b/solutions/python3/436.py @@ -1,7 +1,12 @@ + class Solution: + # 寻找每个区间的右区间,返回结果数组 + def findRightInterval(self, intervals): + # 辅助函数:二分查找 def binarySearch(l, r): - x, found = intervals[l - 1].end, None + x = intervals[l - 1].end + found = None while l <= r: mid = (l + r) // 2 if intervals[mid].start >= x: @@ -9,10 +14,17 @@ def binarySearch(l, r): found = mid else: l = mid + 1 - return ind[intervals[found]] if found != None else -1 + return ind[intervals[found]] if found is not None else -1 + + # 复制原数组并构建索引字典 root = intervals[:] - ind = {intr:i for i, intr in enumerate(root)} - intervals.sort(key = lambda x: x.start) + ind = {intr: i for i, intr in enumerate(root)} + + # 按区间起始位置排序 + intervals.sort(key=lambda x: x.start) + + # 遍历每个区间,使用二分查找确定其右区间,并在结果数组中存储索引 for i in range(len(intervals)): root[ind[intervals[i]]] = binarySearch(i + 1, len(intervals) - 1) - return root \ No newline at end of file + + return root diff --git a/solutions/python3/437.py b/solutions/python3/437.py index 70372eb..b663c0c 100644 --- a/solutions/python3/437.py +++ b/solutions/python3/437.py @@ -1,28 +1,39 @@ + # Definition for a binary tree node. -# class TreeNode: -# def __init__(self, x): -# self.val = x -# self.left = None -# self.right = None +class TreeNode: + def __init__(self, x): + self.val = x + self.left = None + self.right = None class Solution: + # 寻找二叉树中和为sum的路径数量 + # :type root: TreeNode 根节点 + # :type sum: int 目标和 + # :rtype: int 路径数 def pathSum(self, root, sum): - """ - :type root: TreeNode - :type sum: int - :rtype: int - """ - dic = {} + dic = {} # 存储以每个节点为结尾的路径和 + + # 深度优先遍历,计算所有路径和并统计目标和出现次数 def traverse(node, parent): if not node: return - dic[node] = [node.val] - if node.val == sum: res[0] += 1 + + dic[node] = [node.val] # 初始化当前节点路径和列表 + + # 如果当前节点值等于目标和,则路径数+1 + if node.val == sum: + res[0] += 1 + + # 更新父节点的路径和到当前节点,并检查是否形成目标和 if parent: for num in dic[parent]: dic[node].append(num + node.val) - if num + node.val == sum: res[0] += 1 - traverse(node.left, node) - traverse(node.right, node) + if num + node.val == sum: + res[0] += 1 + + traverse(node.left, node) # 遍历左子树 + traverse(node.right, node) # 遍历右子树 + res = [0] - traverse(root, None) - return res[0] \ No newline at end of file + traverse(root, None) # 开始遍历 + return res[0] diff --git a/solutions/python3/438.py b/solutions/python3/438.py index a49a477..f8e87b1 100644 --- a/solutions/python3/438.py +++ b/solutions/python3/438.py @@ -1,16 +1,29 @@ + class Solution: - def findAnagrams(self, s, p): + def findAnagrams(self, s: str, p: str) -> list[int]: """ :type s: str :type p: str :rtype: List[int] """ - out=list() + + # 初始化结果列表和计数器 + out = list() from collections import Counter - s_counter, p_counter=Counter(s[:len(p)-1]), Counter(p) - for i in range(len(p)-1,len(s)): - s_counter[s[i]]+=1 - if s_counter==p_counter: out.append(i-len(p)+1) - s_counter[s[i-len(p)+1]]-=1 - if s_counter[s[i-len(p)+1]]==0: del s_counter[s[i-len(p)+1]] - return out \ No newline at end of file + + # 初始窗口为 s[:len(p)-1] 和 p 的字符计数 + s_counter, p_counter = Counter(s[:len(p) - 1]), Counter(p) + + # 滑动窗口遍历字符串 s + for i in range(len(p) - 1, len(s)): + # 更新当前字符的计数值,并检查是否与目标计数器匹配 + s_counter[s[i]] += 1 + if s_counter == p_counter: + out.append(i - len(p) + 1) + + # 移除窗口最左边的字符,保持窗口大小不变 + s_counter[s[i - len(p) + 1]] -= 1 + if s_counter[s[i - len(p) + 1]] == 0: + del s_counter[s[i - len(p) + 1]] + + return out diff --git a/solutions/python3/439.py b/solutions/python3/439.py index ad2b9b7..e0dbf25 100644 --- a/solutions/python3/439.py +++ b/solutions/python3/439.py @@ -1,9 +1,19 @@ + class Solution: - def parseTernary(self, expression, stack = []): + def parseTernary(self, expression: str, stack: list = []) -> bool: + """ + 解析三元表达式 + + :param expression: 三元表达式的字符串形式,例如 "T?1:0" + :param stack: 用于存储中间结果的栈 + :return: 解析后的布尔值结果 + """ for c in expression[::-1]: + # 中文注释:检查当前元素是否为问号,并且栈顶是否为"?",如果是则解析三元表达式 if stack and stack[-1] == "?": _, first, q, second = stack.pop(), stack.pop(), stack.pop(), stack.pop() stack.append(c == "T" and first or second) else: + # 中文注释:将当前元素压入栈中 stack.append(c) - return stack.pop() \ No newline at end of file + return stack.pop() # 返回最终结果,中文注释:从栈顶弹出并返回解析后的布尔值结果 diff --git a/solutions/python3/44.py b/solutions/python3/44.py index 9d3e3a8..06263e1 100644 --- a/solutions/python3/44.py +++ b/solutions/python3/44.py @@ -1,21 +1,40 @@ + class Solution: - def isMatch(self, s, p): + def isMatch(self, s: str, p: str) -> bool: + """ + 判断字符串s是否匹配模式p。 + + Parameters: + s (str): 输入的字符串 + p (str): 匹配模式,其中 '?' 可以匹配任意单个字符, '*' 可以匹配零个或多个任意字符 + + Returns: + bool: 如果s匹配p则返回True,否则返回False + """ + sp = pp = match = 0 - star = -1 + star = -1 # 记录'*'的位置 + while sp < len(s): if (pp < len(p) and (s[sp] == p[pp] or p[pp] == '?')): - sp +=1 - pp +=1 + # 当前字符匹配或者当前模式为'?' + sp += 1 + pp += 1 elif pp < len(p) and p[pp] == '*': + # 当前模式为'*',记录位置并跳过 star = pp match = sp - pp +=1 + pp += 1 elif star != -1: + # 之前的模式中包含'*' pp = star + 1 - match +=1 + match += 1 sp = match else: return False - while(pp < len(p) and p[pp] == '*'): + + while pp < len(p) and p[pp] == '*': + # 尾部处理,跳过剩余的'*' pp += 1 - return pp == len(p) \ No newline at end of file + + return pp == len(p) diff --git a/solutions/python3/441.py b/solutions/python3/441.py index c322c7e..9609959 100644 --- a/solutions/python3/441.py +++ b/solutions/python3/441.py @@ -1,9 +1,18 @@ + class Solution: def arrangeCoins(self, n: int) -> int: - sm = res = 0 + """ + 使用贪心算法计算最多可以放置多少层 + + Greedy algorithm to calculate the maximum number of layers that can be placed. + """ + sm = 0 # 当前累加和 + res = 0 # 结果,表示最多的层数 + for i in range(1, n + 1): - sm += i - if sm > n: + sm += i # 累加当前层的硬币数 + if sm > n: # 如果当前累加和超过n,则跳出循环 break - res += 1 - return res \ No newline at end of file + res += 1 # 层数加一 + + return res # 返回结果 diff --git a/solutions/python3/442.py b/solutions/python3/442.py index 592582f..456e6b3 100644 --- a/solutions/python3/442.py +++ b/solutions/python3/442.py @@ -1,11 +1,18 @@ + class Solution: + # 寻找数组中重复的元素 - Find duplicates in the array + def findDuplicates(self, nums): """ - :type nums: List[int] - :rtype: List[int] + :type nums: List[int] # 输入参数:整数列表 + :rtype: List[int] # 返回类型:整数列表,包含所有重复的数字 """ - out=list() + out = list() # 存储结果 - Store the result + for i in range(len(nums)): - if nums[abs(nums[i])-1]<0: out.append(abs(nums[i])) - else: nums[abs(nums[i])-1]*=-1 - return out \ No newline at end of file + if nums[abs(nums[i]) - 1] < 0: + out.append(abs(nums[i])) # 如果该位置数值小于0,则表示之前已经访问过,加入结果列表 + else: + nums[abs(nums[i]) - 1] *= -1 # 将对应位置的数取反,标记为已访问 + + return out # 返回最终的结果列表 - Return the final result list diff --git a/solutions/python3/443.py b/solutions/python3/443.py index 7e1f52f..3da4c97 100644 --- a/solutions/python3/443.py +++ b/solutions/python3/443.py @@ -1,16 +1,31 @@ + class Solution: def compress(self, chars): """ :type chars: List[str] :rtype: int """ - curr, count, i = chars[0], 1, 1 - while i1: chars[:i]+= (i for i in "".join(str(count))); i+=len([i for i in "".join(str(count))]) - i, count =i+1, 1 + curr, count, i = chars[0], 1, 1 # 当前字符,计数器,索引 + + while i < len(chars): + if chars[i] != curr: + # 当遇到不同字符时,处理当前字符和计数 + curr = chars[i] + if count > 1: + # 如果有多个相同的字符,则插入计数字符到列表中 + chars[:i] += ''.join(str(count)) + i += len(str(count)) # 跳过已添加的计数字符 + else: - if i==len(chars)-1: chars.pop(i); chars+=[i for i in "".join(str(count+1))]; break - chars.pop(i); count+=1 - return len(chars) \ No newline at end of file + # 继续增加相同字符的计数,直到遇到不同字符 + if i == len(chars) - 1: + # 如果是最后一个相同的字符,则更新并退出循环 + chars.pop(i) + chars += ''.join(str(count + 1)) + break + chars.pop(i) # 移除当前字符 + count += 1 + + i += 1 # 增加索引值 + + return len(chars) # 返回压缩后的字符串长度 diff --git a/solutions/python3/444.py b/solutions/python3/444.py index 764c16b..18faf6b 100644 --- a/solutions/python3/444.py +++ b/solutions/python3/444.py @@ -1,18 +1,34 @@ + class Solution: + # 初始化图和相关数据结构 def sequenceReconstruction(self, org, seqs): - order, orders, graph, seen = collections.defaultdict(int), set(), collections.defaultdict(set), set() + from collections import defaultdict, set + + order, orders, graph, seen = defaultdict(int), set(), defaultdict(set), set() + + # 构建图和seen集合 for seq in seqs: for i in range(len(seq)): if i > 0: - if seq[i] == seq[i - 1]: return False - graph[seq[i - 1]].add(seq[i]) - seen.add(seq[i]) - if not seen: return False + if seq[i] == seq[i - 1]: return False # 检查序列中是否有重复元素 + graph[seq[i - 1]].add(seq[i]) # 构建图,记录前一个节点到后一个节点的关系 + + seen.add(seq[i]) + + if not seen: + return False # 如果seen为空,返回False + + # 根据org逆序遍历并计算order for i in range(len(org) - 1, -1, -1): - if org[i] in seen: seen.discard(org[i]) + if org[i] in seen: + seen.discard(org[i]) + order[org[i]] = max([order[v] for v in graph[org[i]]] or [0]) + 1 - before = set(v for v in graph[org[i]] if v in seen) + + before = set(v for v in graph[org[i]] if v in seen) + # 检查当前节点的order是否合理以及before集合是否为空 if order[org[i]] in orders or before: return False - orders.add(order[org[i]]) - return not seen \ No newline at end of file + + # 如果seen为空,表示重建成功 + return not seen diff --git a/solutions/python3/445.py b/solutions/python3/445.py index 6a32568..92b40ed 100644 --- a/solutions/python3/445.py +++ b/solutions/python3/445.py @@ -1,26 +1,41 @@ + class Solution: + # 定义一个方法,用于将两个链表表示的数字相加 def addTwoNumbers(self, l1: ListNode, l2: ListNode) -> ListNode: - s1, s2, s3 = [], [], [] - p1, p2 = l1, l2 + + s1, s2, s3 = [], [], [] # 初始化三个列表来存储节点值 + p1, p2 = l1, l2 # 指针初始化,指向链表的头结点 + + # 将l1链表中的数字压入s1列表中 while p1: s1.append(p1.val) p1 = p1.next - while p2: - s2.append(p2.val) + + # 将l2链表中的数字压入s2列表中 + while p2: + s2.append(p2.val) p2 = p2.next + + # 确保s1的长度不小于s2,以便后续处理进位时更加方便 if len(s1) < len(s2): - s1, s2 = s2, s1 + s1, s2 = s2, s1 # 列表和链表互换 l1, l2 = l2, l1 - residual = 0 + + residual = 0 # 初始化进位值为0 + + # 当s1还有元素时,依次弹出并相加 while len(s1) > 0: temp = s1.pop() + residual - if len(s2) > 0: + if len(s2) > 0: temp += s2.pop() - s3.append(temp % 10) - residual = temp // 10 - head, p = ListNode(1), l1 - head.next = p - while len(s3) > 0: - p.val = s3.pop() - p = p.next - return head if residual == 1 else head.next \ No newline at end of file + s3.append(temp % 10) # 将结果的个位数存入s3中 + residual = temp // 10 # 更新进位值 + + head, p = ListNode(1), l1 # 创建一个头节点并指向l1链表的第一个节点作为起始点 + + head.next = p # 将新创建的头节点连接到原链表上 + while len(s3) > 0: + p.val = s3.pop() # 更新当前指针所指向节点的值为s3中的值 + p = p.next # 移动指针至下一个节点 + + return head if residual == 1 else head.next # 返回头结点,如果存在进位则返回下一个节点 diff --git a/solutions/python3/446.py b/solutions/python3/446.py index c8a8799..06587ff 100644 --- a/solutions/python3/446.py +++ b/solutions/python3/446.py @@ -1,8 +1,23 @@ + class Solution: def numberOfArithmeticSlices(self, A): - dp, res = collections.defaultdict(dict), 0 + # 使用字典嵌套结构存储差值及对应的子序列数量 + # defaultdict(dict) 是为了方便处理不存在的键值对,默认初始化为0或1 + dp = collections.defaultdict(dict) + res = 0 + + # 遍历数组A中的每一个元素 for j in range(len(A)): + # 再次遍历j之前的所有元素 for i in range(j): - dp[j][A[j] - A[i]] = dp[j].get(A[j] - A[i], 0) + dp[i].get(A[j] - A[i], 1) - if A[j] - A[i] in dp[i]: res, dp[j][A[j] - A[i]] = res + dp[i][A[j] - A[i]], dp[j][A[j] - A[i]] + 1 - return res \ No newline at end of file + diff = A[j] - A[i] + + # 更新差值对应的子序列数量 + dp[j][diff] = dp[j].get(diff, 0) + dp[i].get(diff, 1) + + # 检查是否存在满足条件的子数组,更新结果和dp表 + if diff in dp[i]: + res += dp[i][diff] + dp[j][diff] += 1 + + return res diff --git a/solutions/python3/448.py b/solutions/python3/448.py index 049ee43..a8f3efc 100644 --- a/solutions/python3/448.py +++ b/solutions/python3/448.py @@ -1,7 +1,8 @@ + class Solution: def findDisappearedNumbers(self, nums): """ - :type nums: List[int] - :rtype: List[int] + :type nums: List[int] # 输入的整数列表 + :rtype: List[int] # 返回缺失的数字列表 """ - return [x for x in set([i for i in range(1,len(nums)+1)])-set(nums)] \ No newline at end of file + return [x for x in set(range(1, len(nums) + 1)) - set(nums)] # 使用集合操作找出缺失的数字 diff --git a/solutions/python3/45.py b/solutions/python3/45.py index 04c24f3..1caf746 100644 --- a/solutions/python3/45.py +++ b/solutions/python3/45.py @@ -1,10 +1,29 @@ + class Solution: def jump(self, nums): + """ + :param nums: List[int] - 需要跳跃的数组,每个元素表示从当前位置可以跳的最大步数 + :return: int - 实现从起点到终点所需的最少跳跃次数 + """ + last = cur = jump = i = 0 + # 中文:使用last记录当前能到达的最远距离;cur用于更新最远距离;jump记录跳跃次数;i用于遍历数组 + # English: Use `last` to record the farthest distance that can be reached; use `cur` to update the farthest distance; + # use `jump` to count the number of jumps; and use `i` to traverse the array. + while cur < len(nums) - 1: + # 中文:当当前最远距离小于数组长度减一,进入循环 + # English: If the current farthest distance is less than the length of the array minus one, enter the loop + while i <= last: - if i + nums[i] > cur: cur = i + nums[i] + # 中文:内部循环用于遍历last范围内的所有点,并更新当前能到达的最远距离cur + # English: The inner loop traverses all points within the range of `last` and updates the current farthest distance `cur`. + + if i + nums[i] > cur: + cur = i + nums[i] i += 1 + last = cur jump += 1 - return jump \ No newline at end of file + + return jump diff --git a/solutions/python3/450.py b/solutions/python3/450.py index 3f25eb6..a926ee0 100644 --- a/solutions/python3/450.py +++ b/solutions/python3/450.py @@ -1,25 +1,34 @@ + # Definition for a binary tree node. -# class TreeNode: -# def __init__(self, x): -# self.val = x -# self.left = None -# self.right = None +class TreeNode: + def __init__(self, x): + self.val = x + self.left = None + self.right = None class Solution: - def deleteNode(self, root, key): - """ - :type root: TreeNode - :type key: int - :rtype: TreeNode - """ + # 二叉树节点删除操作 + def deleteNode(self, root: 'TreeNode', key: int) -> 'TreeNode': if not root: return - if root.val > key: root.left = self.deleteNode(root.left, key) - elif root.val < key: root.right = self.deleteNode(root.right, key) + + # 当前结点值大于key,递归到左子树并更新当前结点的左子树引用 + if root.val > key: + root.left = self.deleteNode(root.left, key) + + # 当前结点值小于key,递归到右子树并更新当前结点的右子树引用 + elif root.val < key: + root.right = self.deleteNode(root.right, key) + + # 找到要删除的节点 else: + # 无右子树或左子树情况处理 if not root.right: return root.left elif not root.left: return root.right + + # 寻找右子树最小结点并替换当前结点值,递归更新右子树 tmp, mini = root.right, root.right.val while tmp.left: tmp, mini = tmp.left, tmp.left.val root.val, root.right = mini, self.deleteNode(root.right, mini) - return root \ No newline at end of file + + return root diff --git a/solutions/python3/451.py b/solutions/python3/451.py index 0a8ee31..6447e78 100644 --- a/solutions/python3/451.py +++ b/solutions/python3/451.py @@ -1,7 +1,25 @@ + class Solution: + # Python 代码优化和注释 + def frequencySort(self, s: str) -> str: - cnt = collections.Counter(s) + """ + 中文注释:使用计数器统计字符串中每个字符的频率,并按降序排序。 + 英文注释:Use a counter to count the frequency of each character in the string and sort it in descending order. + + :param s: 输入的字符串 + :return: 按照字符出现次数从多到少重新排列后的字符串 + """ + from collections import Counter + + # 中文注释:使用collections.Counter统计字符频率 + # 英文注释:Use collections.Counter to count the frequency of characters. + cnt = Counter(s) + res = '' - for k, v in sorted(cnt.items(), key = lambda x: -cnt[x[0]]): + # 中文注释:遍历排序后的频率项,并构建结果字符串 + # 英文注释:Iterate over the sorted frequency items and build the result string. + for k, v in sorted(cnt.items(), key=lambda x: -cnt[x[0]]): res += k * v - return res \ No newline at end of file + + return res diff --git a/solutions/python3/452.py b/solutions/python3/452.py index da05f57..0ee3b1c 100644 --- a/solutions/python3/452.py +++ b/solutions/python3/452.py @@ -1,7 +1,24 @@ + class Solution: - def findMinArrowShots(self, p): - p.sort(key = lambda x: x[1]) - (res, curr) = (1, p[0][1]) if p else (0, None) - for n in p: - if n[0] > curr: res, curr = res + 1, n[1] - return res \ No newline at end of file + def findMinArrowShots(self, points): + """ + 输入:points - 覆盖目标的气球位置列表,每个元素表示一个区间 [x_start, x_end]。 + + 输出:最少需要多少支箭才能射破所有气球。 + """ + # 按照每个区间的结束位置排序 + points.sort(key=lambda x: x[1]) + + if not points: + return 0 + + # 初始化结果和当前箭的位置 + res = 1 # 至少需要一支箭 + curr = points[0][1] + + for point in points: + # 如果当前气球的起始位置大于当前箭的位置,则需要额外一支箭,并更新箭的位置为当前区间的结束位置 + if point[0] > curr: + res, curr = res + 1, point[1] + + return res diff --git a/solutions/python3/453.py b/solutions/python3/453.py index a1455e0..747c990 100644 --- a/solutions/python3/453.py +++ b/solutions/python3/453.py @@ -1,7 +1,10 @@ + class Solution: + # 计算将所有数组元素变为相同值所需的最小移动次数 def minMoves(self, nums): """ :type nums: List[int] :rtype: int """ - return sum(nums) - min(nums) * len(nums) \ No newline at end of file + # 总和减去最小值的n倍,即为解 + return sum(nums) - min(nums) * len(nums) diff --git a/solutions/python3/454.py b/solutions/python3/454.py index 97839f0..34cfef6 100644 --- a/solutions/python3/454.py +++ b/solutions/python3/454.py @@ -1,4 +1,14 @@ + +from typing import List +import collections + class Solution: + # 定义一个类来解决四数之和为零的问题 + def fourSumCount(self, A: List[int], B: List[int], C: List[int], D: List[int]) -> int: + # 生成A和B的所有可能两数之和,并使用collections.Counter进行计数 ab = collections.Counter([a + b for a in A for b in B]) - return sum(-c - d in ab and ab[-c-d] for c in C for d in D) \ No newline at end of file + + # 计算C和D所有可能两数之和的相反数在ab中出现的次数 + # 这里通过sum函数遍历C和D,检查其负值是否存在于ab中,并统计结果 + return sum(-c - d in ab and ab[-c-d] for c in C for d in D) diff --git a/solutions/python3/455.py b/solutions/python3/455.py index eb0dac4..fe3a996 100644 --- a/solutions/python3/455.py +++ b/solutions/python3/455.py @@ -1,7 +1,17 @@ + class Solution: + # 定义一个类来解决分配问题 + def findContentChildren(self, g, s): - g.sort(reverse = True); s.sort(reverse = True); res = 0 + # 对满足条件的儿童和饼干大小进行降序排序 + g.sort(reverse=True); s.sort(reverse=True) + res = 0 # 记录能够满足需求的儿童数量 + + # 当有剩余的饼干和需要分配的儿童时,继续循环 while s and g: - if g[-1] <= s[-1]: res += 1; g.pop(); s.pop() - else: s.pop() - return res \ No newline at end of file + if g[-1] <= s[-1]: # 检查当前最大需求是否能被当前最大饼干满足 + res += 1 # 如果可以满足,则计数器加一,并移除一个饼干和需求 + g.pop(); s.pop() + else: # 否则,说明当前最大饼干不能满足当前最大需求,移除一个饼干尝试下一个小一点的饼干 + s.pop() + return res # 返回能够被满足的需求数量 diff --git a/solutions/python3/456.py b/solutions/python3/456.py index cd882c6..50f7320 100644 --- a/solutions/python3/456.py +++ b/solutions/python3/456.py @@ -1,8 +1,21 @@ + class Solution: + # 检查数组中是否存在132模式 + def find132pattern(self, nums): stack, s3 = [], -float("inf") - for n in nums[::-1]: - if n < s3: return True - while stack and stack[-1] < n: s3 = stack.pop() + + for n in nums[::-1]: # 遍历逆序的nums列表 + # 如果当前元素小于s3,则找到了132模式,返回True + if n < s3: + return True + + # 尝试更新s3并移除栈中比n小的元素 + while stack and stack[-1] < n: + s3 = stack.pop() + + # 将当前元素压入栈中 stack.append(n) - return False \ No newline at end of file + + # 遍历结束,未找到132模式,返回False + return False diff --git a/solutions/python3/459.py b/solutions/python3/459.py index 2e1a6de..5a077c4 100644 --- a/solutions/python3/459.py +++ b/solutions/python3/459.py @@ -1,7 +1,26 @@ + class Solution: - def repeatedSubstringPattern(self, s): + def repeatedSubstringPattern(self, s: str) -> bool: """ :type s: str :rtype: bool + + 中文注释: + 判断给定字符串是否可以通过重复某个子串构成。 + + 英文注释: + Determine whether the given string can be constructed by repeating a substring. """ - return True if len(s)>1 and (s in [s[:i]*(len(s)//i) for i in range(2,len(s)) if len(s)%i==0] or s==s[0]*len(s)) else False \ No newline at end of file + + # 检查字符串长度是否大于1,确保有足够字符进行分割 + if len(s) > 1: + # 遍历可能的分隔因子i(从2到s长度-1) + for i in range(2, len(s)): + # 如果s的长度能被i整除,则进一步检查 + if len(s) % i == 0: + # 检查是否可以通过重复s[:i]构成整个字符串s + if s == (s[:i] * (len(s) // i)): + return True + + # 如果没有找到合适的子串,返回False + return False diff --git a/solutions/python3/46.py b/solutions/python3/46.py index e65e9da..6dda917 100644 --- a/solutions/python3/46.py +++ b/solutions/python3/46.py @@ -1,2 +1,26 @@ + class Solution: - def permute(self, nums): return list(itertools.permutations(nums)) \ No newline at end of file + """ + 中文: + 实现一个方法来生成给定数字列表的所有排列组合。 + + English: + Implement a method to generate all permutations of the given number list. + """ + + def permute(self, nums): + """ + 中文: + 生成给定数字列表的所有排列组合。 + + English: + Generate all permutations of the given number list. + + Args: + nums (List[int]): 输入的数字列表。 + + Returns: + List[tuple]: 返回所有可能的排列组合列表,每个元素是一个元组形式的排列。 + """ + from itertools import permutations + return list(permutations(nums)) diff --git a/solutions/python3/460.py b/solutions/python3/460.py index 12a56f4..83ab8f3 100644 --- a/solutions/python3/460.py +++ b/solutions/python3/460.py @@ -1,28 +1,39 @@ + class Node: + # 节点类,用于构建双向链表中的节点 def __init__(self, k, v, f): - self.key = k - self.val = v - self.freq = f - self.next = self.pre = None -class LFUCache: + self.key = k # 键 + self.val = v # 值 + self.freq = f # 频次 + self.next = None # 下一个节点 + self.pre = None # 上一个节点 +class LFUCache: def __init__(self, capacity): - self.max = capacity - self.cache = 0 - self.freqLast = {} - self.Nodes = {} - self.head = self.tail = Node("#", "#", "#") - self.head.next = self.tail - self.tail.pre = self.head + """ + 初始化LFU缓存类 + :param capacity: 缓存的最大容量 + """ + self.max = capacity # 最大容量 + self.cache = 0 # 当前缓存数量 + self.freqLast = {} # 按照频次组织的节点尾部指针字典,用于快速找到每个频次下的最后一个节点 + self.Nodes = {} # 存储key到Node对象的映射 + self.head = self.tail = Node("#", "#", "#") # 头尾哨兵节点 + self.head.next = self.tail # 尾节点指向头节点 + self.tail.pre = self.head # 头节点指向尾节点 def changeFreq(self, key): - node, f = self.Nodes[key], self.Nodes[key].freq + """ + 更新节点的频次,并调整双向链表结构 + :param key: 节点键值 + """ + node, f = self.Nodes[key], self.Nodes[key].freq # 获取节点及其当前频次 if self.freqLast[f] == node: if node.pre.freq == f: self.freqLast[f] = node.pre else: self.freqLast.pop(f) - if f + 1 in self.freqLast: + if (f + 1) in self.freqLast: node.pre.next = node.next node.next.pre = node.pre node.pre = self.freqLast[f + 1] @@ -35,34 +46,48 @@ def changeFreq(self, key): node.pre.next = node.next.pre = node self.freqLast[f + 1] = node node.freq += 1 - + def removeFirst(self): - node, f = self.head.next, self.head.next.freq - node.pre.next = node.next + """ + 移除并返回最不常用的节点 + """ + node, f = self.head.next, self.head.next.freq # 获取头节点的下一个节点及其频次 + node.pre.next = node.next # 调整前一个节点和后一个节点的关系,跳过当前要移除的节点 node.next.pre = node.pre - self.Nodes.pop(node.key) + self.Nodes.pop(node.key) # 移除缓存中的键值对 if self.freqLast[f] == node: self.freqLast.pop(f) self.cache -= 1 - + def get(self, key): + """ + 获取指定key对应的value,如果存在则更新节点的频次 + :param key: 键值 + :return: 对应值或-1(未找到) + """ if key in self.Nodes: self.changeFreq(key) - return self.Nodes[key].val + return self.Nodes[key].val # 返回节点的值,并更新其频次 return -1 + def put(self, key, value): + """ + 插入新的键值对或更新现有键值对 + :param key: 键值 + :param value: 值 + """ if key in self.Nodes: self.changeFreq(key) - self.Nodes[key].val = value + self.Nodes[key].val = value # 更新节点的值并增加其频次 elif self.max: if self.cache == self.max: - self.removeFirst() + self.removeFirst() # 如果缓存已满,移除最不常用的节点 self.cache += 1 - new = Node(key, value, 1) + new = Node(key, value, 1) # 创建新的节点 if 1 in self.freqLast: new.pre = self.freqLast[1] else: new.pre = self.head new.next = new.pre.next new.pre.next = new.next.pre = new - self.freqLast[1] = self.Nodes[key] = new \ No newline at end of file + self.freqLast[1] = self.Nodes[key] = new # 将新节点添加到链表中,并更新缓存字典 diff --git a/solutions/python3/461.py b/solutions/python3/461.py index 7bea7d2..297d098 100644 --- a/solutions/python3/461.py +++ b/solutions/python3/461.py @@ -1,3 +1,11 @@ + class Solution: + # 计算两个整数之间的汉明距离,即二进制表示下对应位不同的位数 + def hammingDistance(self, x: int, y: int) -> int: - return sum(a != b for a, b in zip(bin(x)[2:].zfill(32), bin(y)[2:].zfill(32))) \ No newline at end of file + # 将两个整数转换为32位的二进制字符串,并确保长度相同 + bin_x = bin(x)[2:].zfill(32) + bin_y = bin(y)[2:].zfill(32) + + # 计算对应位不同的位数,返回汉明距离 + return sum(a != b for a, b in zip(bin_x, bin_y)) diff --git a/solutions/python3/462.py b/solutions/python3/462.py index 5f9d928..aa5e43e 100644 --- a/solutions/python3/462.py +++ b/solutions/python3/462.py @@ -1,5 +1,14 @@ + class Solution: + # 计算将数组中的所有元素移动到中间值所需的最小移动次数 + def minMoves2(self, nums): + # 首先对数组进行排序 nums.sort() - m = nums[(len(nums) - 1) // 2] - return sum(abs(num - m) for num in nums) \ No newline at end of file + + # 找到中位数,对于奇数长度的数组,中位数是中间的那个数; + # 对于偶数长度的数组,中位数可以是中间两个数中的任何一个 + m = nums[(len(nums) - 1) // 2] + + # 计算所有元素移动到中位数所需的操作次数总和 + return sum(abs(num - m) for num in nums) diff --git a/solutions/python3/463.py b/solutions/python3/463.py index 3d82ed7..54c3b1f 100644 --- a/solutions/python3/463.py +++ b/solutions/python3/463.py @@ -1,18 +1,40 @@ + class Solution: def islandPerimeter(self, grid: List[List[int]]) -> int: - self.res = 0 - used = set() + """ + 计算岛屿的周长 + + Parameters: + grid (List[List[int]]): 二维网格,1表示陆地,0表示水域 + + Returns: + int: 岛屿的周长 + """ + + self.res = 0 # 初始化结果变量 + used = set() # 记录已访问的位置 + def dfs(i, j): - used.add((i, j)) - self.res += 4 - for x, y in (i - 1, j), (i + 1, j), (i, j - 1), (i, j + 1): + """ + 深度优先搜索计算单个岛屿的周长 + + Parameters: + i (int): 当前行索引 + j (int): 当前列索引 + """ + used.add((i, j)) # 标记当前位置为已访问 + self.res += 4 # 每遇到一个陆地,初始周长加4 + + for x, y in ((i - 1, j), (i + 1, j), (i, j - 1), (i, j + 1)): if 0 <= x < m and 0 <= y < n and grid[x][y]: - self.res -= 1 + self.res -= 1 # 邻近陆地减少一条边 if (x, y) not in used: - dfs(x, y) - m, n = len(grid), len(grid[0]) + dfs(x, y) # 继续递归搜索 + + m, n = len(grid), len(grid[0]) # 获取网格的行数和列数 for i in range(m): for j in range(n): if grid[i][j] == 1 and (i, j) not in used: - dfs(i, j) - return self.res \ No newline at end of file + dfs(i, j) # 从未访问的陆地开始搜索 + + return self.res # 返回计算得到的周长 diff --git a/solutions/python3/464.py b/solutions/python3/464.py index 553b5e0..b8899be 100644 --- a/solutions/python3/464.py +++ b/solutions/python3/464.py @@ -1,18 +1,49 @@ + class Solution: - def canIWin(self, maxChoosableInteger, desiredTotal): - memo = {} + # 定义一个解决方案类 + + def canIWin(self, maxChoosableInteger: int, desiredTotal: int) -> bool: + """ + 判断是否能在游戏中获胜 + + :param maxChoosableInteger: 可选择的最大整数 (maxChoosableInteger) + :param desiredTotal: 游戏目标分数 (desiredTotal) + :return: 是否能赢得游戏 (bool) + """ + + # 如果所有可选数字之和小于目标分数,直接返回False + if (1 + maxChoosableInteger) * maxChoosableInteger / 2 < desiredTotal: + return False + + memo = {} # 使用字典存储已经计算过的状态以避免重复计算 + def dfs(arr, total): - s = str(arr) + """ + 深度优先搜索函数 + + :param arr: 当前可选择的数字列表 (list of int) + :param total: 剩余需要达到的目标分数 (int) + :return: 是否能在当前状态下获胜 (bool) + """ + + s = str(arr) # 数组转字符串以便于字典键值 if s in memo: - return memo[s] - elif arr[-1] >= total: + return memo[s] # 如果已经计算过此状态,直接返回结果 + + if arr[-1] >= total: + # 如果最后一个数字大于或等于剩余分数,则当前玩家获胜 return True + for i in range(len(arr)): - if not dfs(arr[:i] + arr[i + 1:], total - arr[i]): + # 尝试移除一个数字并检查对手是否能赢 + if not dfs(arr[:i] + arr[i+1:], total - arr[i]): + # 如果对手不能赢,记录当前状态为True(即自己可以赢) memo[s] = True return True + + # 如果所有尝试都无法让自己获胜,则记录当前状态为False memo[s] = False return False - if (1 + maxChoosableInteger) * maxChoosableInteger/2 < desiredTotal: - return False - return dfs(list(range(1, maxChoosableInteger + 1)), desiredTotal) \ No newline at end of file + + # 调用dfs函数并传入初始化的可选数字和目标分数 + return dfs(list(range(1, maxChoosableInteger + 1)), desiredTotal) diff --git a/solutions/python3/465.py b/solutions/python3/465.py index bb4acaf..7e3269f 100644 --- a/solutions/python3/465.py +++ b/solutions/python3/465.py @@ -1,9 +1,11 @@ + class Solution: def minTransfers(self, transactions: List[List[int]]) -> int: + # 定义移除一个零闭集的函数 def remove_one_zero_clique(non_zero): n = len(non_zero) q = collections.deque() - # q store ([index set], sum of set) + # 使用队列存储(index集合, 集合和值) 的元组 q.append(([0], non_zero[0])) min_zero_set = None @@ -15,18 +17,21 @@ def remove_one_zero_clique(non_zero): for j in range(cur_set[-1] + 1, n): q.append((cur_set + [j], cur_sum + non_zero[j])) + # 将找到的零闭集转换为集合 min_zero_set = set(min_zero_set) return [non_zero[i] for i in range(n) if i not in min_zero_set] - bal = collections.defaultdict(int) + # 统计每个用户的余额变化情况,正数表示净收入,负数表示净支出 for t in transactions: bal[t[0]] -= t[2] bal[t[1]] += t[2] non_zero = [bal[k] for k in bal if bal[k] != 0] + # 初始非零余额的数量 bal_cnt = len(non_zero) while len(non_zero) > 0: + # 移除一个零闭集,减少非零余额数量 non_zero = remove_one_zero_clique(non_zero) bal_cnt -= 1 - return bal_cnt \ No newline at end of file + return bal_cnt diff --git a/solutions/python3/466.py b/solutions/python3/466.py index 57160c7..af0e317 100644 --- a/solutions/python3/466.py +++ b/solutions/python3/466.py @@ -1,25 +1,43 @@ + class Solution(object): - def getMaxRepetitions(self, s1, n1, s2, n2): - start = {} # s2_idx : s1_round, s2_round + """ + 解决方案类,用于求解最大重复次数问题。 + """ + + def getMaxRepetitions(self, s1: str, n1: int, s2: str, n2: int) -> int: + # 记录s2_idx在s1_round中出现的位置及对应的s2_round + start = {} s1_round, s2_round, s2_idx = 0, 0, 0 + while s1_round < n1: s1_round += 1 for ch in s1: + # 如果当前字符匹配,则移动s2_idx if ch == s2[s2_idx]: s2_idx += 1 + # 检查是否已完整匹配一个s2字符串 if s2_idx == len(s2): s2_round += 1 s2_idx = 0 + + # 如果之前已经遇到过相同s2_idx,则找到了循环节 if s2_idx in start: prev_s1_round, prev_s2_round = start[s2_idx] circle_s1_round, circle_s2_round = s1_round - prev_s1_round, s2_round - prev_s2_round + + # 计算完整周期数量并加上剩余部分 res = (n1 - prev_s1_round) // circle_s1_round * circle_s2_round left_s1_round = (n1 - prev_s1_round) % circle_s1_round + prev_s1_round for key, val in start.items(): if val[0] == left_s1_round: res += val[1] break + return res // n2 + + # 记录当前状态,供后续循环检查使用 else: start[s2_idx] = (s1_round, s2_round) - return s2_round // n2 \ No newline at end of file + + # 如果没有找到完整周期,则直接计算结果 + return s2_round // n2 diff --git a/solutions/python3/467.py b/solutions/python3/467.py index f0cabac..0365eba 100644 --- a/solutions/python3/467.py +++ b/solutions/python3/467.py @@ -1,7 +1,25 @@ + class Solution: + # 定义一个类用于解决寻找缠绕字符串中子串的问题 + def findSubstringInWraproundString(self, p): + """ + :param p: str - 输入的字符串 + :return: int - 返回可以找到的最大缠绕子串数量 + + 解析输入字符串,统计每个字符作为结尾的最长缠绕子串长度。 + """ + res, l = {i: 1 for i in p}, 1 + # 初始化结果字典和当前子串长度 + for i, j in zip(p, p[1:]): + # 遍历输入字符串,两两比较字符 l = l + 1 if (ord(j) - ord(i)) % 26 == 1 else 1 + # 判断是否构成缠绕序列,并更新当前子串长度 + res[j] = max(res[j], l) - return sum(res.values()) \ No newline at end of file + # 更新结果字典中每个字符的最大子串长度 + + return sum(res.values()) + # 返回所有字符最大子串长度的总和 diff --git a/solutions/python3/468.py b/solutions/python3/468.py index 09f7812..8228586 100644 --- a/solutions/python3/468.py +++ b/solutions/python3/468.py @@ -1,20 +1,39 @@ + class Solution: def validIPAddress(self, IP): """ :type IP: str :rtype: str + + 判断给定的字符串IP是否为有效的IPv4或IPv6地址。 + 1. 首先检查是否符合IPv4格式,即由四个部分组成,每个部分由点分隔。 + 2. 检查每个部分是否满足IPv4规则:长度在0到3之间,数字0-9开头且不超过255。同时,以'0'开头但不等于"0"的情况视为无效。 + 3. 如果符合IPv4格式,则返回 "IPv4"。 + + 4. 检查是否符合IPv6格式,即由八个部分组成,每个部分由冒号分隔。 + 5. 每个部分应为1-4位的十六进制数字。 + 6. 如果符合IPv6格式,则返回 "IPv6"。 + + 如果不符合上述任何规则,则返回 "Neither"。 """ ip4, ip6 = IP.split("."), IP.split(":") + + # IPv4 validation if len(ip4) == 4: for num in ip4: try: if not (num[0] in string.digits and int(num) < 256 and (num[0] != "0" or num == "0")): return "Neither" - except: return "Neither" + except: + return "Neither" return "IPv4" + + # IPv6 validation elif len(ip6) == 8: for num in ip6: try: - if not (num[0] in string.hexdigits and 0 <= int(num, 16) and len(num) <= 4): return "Neither" - except: return "Neither" + if not (num[0] in string.hexdigits and 0 <= int(num, 16) < 65536 and len(num) <= 4): return "Neither" + except: + return "Neither" return "IPv6" - return "Neither" \ No newline at end of file + + return "Neither" diff --git a/solutions/python3/469.py b/solutions/python3/469.py index de813d8..70d0c57 100644 --- a/solutions/python3/469.py +++ b/solutions/python3/469.py @@ -1,9 +1,18 @@ + class Solution: + # 判断一个点集是否为凸多边形 def isConvex(self, points): - def direction(a, b, c): return (b[0] - a[0]) * (c[1] - a[1]) - (b[1] - a[1]) * (c[0] - a[0]) + # 计算向量方向,用于判断点的方向性 + def direction(a, b, c): + return (b[0] - a[0]) * (c[1] - a[1]) - (b[1] - a[1]) * (c[0] - a[0]) + d, n = 0, len(points) + # 遍历点集,检查相邻三点的方向性是否一致 for i in range(n): a = direction(points[i], points[(i + 1) % n], points[(i + 2) % n]) - if not d: d = a - elif a * d < 0: return False - return True \ No newline at end of file + if not d: + d = a + elif a * d < 0: + return False + + return True diff --git a/solutions/python3/47.py b/solutions/python3/47.py index e63ba64..f860ae4 100644 --- a/solutions/python3/47.py +++ b/solutions/python3/47.py @@ -1,7 +1,19 @@ + class Solution: + """解决方案类""" + def permuteUnique(self, nums): - dic = set() - for p in itertools.permutations(nums): + """ + :param nums: 列表,需要进行唯一排列的数字列表 + :return: 列表,包含所有唯一排列组合的结果 + """ + from itertools import permutations # 导入itertools.permutations用于生成排列 + + dic = set() # 使用集合存储结果以去重 + + # 遍历生成的所有排列 + for p in permutations(nums): if p not in dic: - dic.add(p) - return list(dic) \ No newline at end of file + dic.add(p) # 如果排列未在集合中,则添加进去 + + return list(dic) # 将集合转换为列表并返回 diff --git a/solutions/python3/470.py b/solutions/python3/470.py index 00bea1d..b1aae65 100644 --- a/solutions/python3/470.py +++ b/solutions/python3/470.py @@ -1,3 +1,14 @@ + class Solution: + # 返回一个1到10之间的随机整数(包含1和10) + # 中文注释:返回一个1到10之间的随机整数(包含1和10) + def rand10(self): - return sum(rand7() for _ in range(10)) % 10 + 1 \ No newline at end of file + # 通过多次调用rand7()生成一个范围在[0,63]之间的随机数 + # 使用生成的随机数映射到[1,10]范围内 + # 中文注释:通过多次调用rand7()生成一个范围在[0,63]之间的随机数,使用生成的随机数映射到[1,10]范围内 + + while True: + num = sum(rand7() for _ in range(10)) % 64 + if num < 60: # 60是大于等于10的最大整数,确保结果在[1,10] + return (num % 10) + 1 diff --git a/solutions/python3/471.py b/solutions/python3/471.py index 3bd2c84..389ec6f 100644 --- a/solutions/python3/471.py +++ b/solutions/python3/471.py @@ -1,18 +1,55 @@ + class Solution: def encode(self, s: str) -> str: + """ + 编码字符串,将其压缩为更短的形式。 + + 参数: + s (str): 输入的原始字符串 + + 返回: + str: 压缩后的字符串 + """ + def dfs(i, j): - if i == j: return s[i] + """ + 深度优先搜索实现字符串编码。 + + 参数: + i (int): 当前子串起始索引 + j (int): 当前子串结束索引 + + 返回: + str: 编码后的子串 + """ + + if i == j: + return s[i] # 如果是单个字符,直接返回 + if (i, j) not in memo: - c1 = min((dfs(i, k) + dfs(k + 1, j) if s[i:k + 1] != s[k + 1:j + 1] else '2[' + dfs(i, k) + ']' for k in range(i, j)), key = len) + # 遍历所有分割点,寻找最短编码方式 + c1 = min((dfs(i, k) + dfs(k + 1, j) + if s[i:k + 1] != s[k + 1:j + 1] + else '2[' + dfs(i, k) + ']' + for k in range(i, j)), + key=len) + c2 = s[i:j + 1] - memo[(i, j)] = min(c1, c2, key = len) + + memo[(i, j)] = min(c1, c2, key=len) + + # 寻找重复子串并压缩 for k in range(i, i + (j - i) // 2 + 1): tar, ind, cnt = s[i:k + 1], i, 0 while ind + k - i <= j and s[ind:ind + k - i + 1] == tar: cnt += 1 ind += k - i + 1 - c3 = str(cnt) + '[' + tar + ']' + dfs(ind, j) if ind <= j else str(cnt) + '[' + tar + ']' - memo[(i, j)] = min(memo[(i, j)], c3, key = len) + + c3 = str(cnt) + '[' + tar + ']' + dfs(ind, j) + if ind <= j: + memo[(i, j)] = min(memo.get((i, j), ''), c3, key=len) + return memo[(i, j)] + memo = {} - return dfs(0, len(s) - 1) \ No newline at end of file + return dfs(0, len(s) - 1) diff --git a/solutions/python3/472.py b/solutions/python3/472.py index 9572739..4888ff6 100644 --- a/solutions/python3/472.py +++ b/solutions/python3/472.py @@ -1,13 +1,25 @@ + class Solution: + # 定义一个方法用于检查单词是否可以由字典中的其他单词拼接而成 def findAllConcatenatedWordsInADict(self, words): + # 辅助函数,递归检查子字符串是否存在字典中 def check(w, st): - if w in st: return True - for i in range(1, len(w)): - if w[:i] in st and check(w[i:], st): return True + if w in st: # 如果当前单词存在于集合中,则直接返回True + return True + for i in range(1, len(w)): # 遍历所有可能的分割点 + if w[:i] in st and check(w[i:], st): # 检查前缀和后缀是否都在字典中 + return True return False + + # 将输入单词转换为集合,方便查找 w_set, res = set(words), [] + for w in words: - w_set.remove(w) - if check(w, w_set): res += w, - w_set.add(w) - return res \ No newline at end of file + w_set.remove(w) # 从集合中移除当前检查的单词 + + if check(w, w_set): # 如果当前单词可以通过字典中的其他单词拼接而成,则加入结果列表 + res += w, + + w_set.add(w) # 将当前单词重新添加回集合,为下次循环做准备 + + return res # 返回所有可以由字典中单词拼接而成的单词 diff --git a/solutions/python3/473.py b/solutions/python3/473.py index 4ca0d32..cd59421 100644 --- a/solutions/python3/473.py +++ b/solutions/python3/473.py @@ -1,14 +1,51 @@ + class Solution: def makesquare(self, nums): + """ + 判断给定的数字列表是否可以构成一个正方形,每个边上的和相同。 + + 参数: + nums (List[int]): 数字列表 + + 返回值: + bool: 如果可以构成正方形则返回 True,否则返回 False + """ + def dfs(index, edge, count, used): + """ + 深度优先搜索辅助函数。 + + 参数: + index (int): 当前考虑的数字索引 + edge (int): 边长剩余值 + count (int): 已完成的边数 + used (Set[int]): 已使用的数字索引集合 + """ for i in range(index, len(nums)): - if i in used or edge - nums[i] < 0: continue - elif edge - nums[i] > 0 and dfs(i + 1, edge - nums[i], count, used | {i}): return True - elif edge - nums[i] == 0 and (count and dfs(1, l, count - 1, used | {i})) or not count: return True + if i in used or edge - nums[i] < 0: + continue + elif edge - nums[i] > 0 and dfs(i + 1, edge - nums[i], count, used | {i}): + return True + elif edge - nums[i] == 0 and (count and dfs(1, l, count - 1, used | {i})) or not count: + return True return False + + # 计算数字列表总和 sm = sum(nums) - if len(nums) < 4 or sm % 4 != 0: return False + + # 判断边界条件 + if len(nums) < 4 or sm % 4 != 0: + return False + + # 每条边的目标长度 l = sm // 4 - nums.sort(reverse = True) - if nums[0] > l: return False - return nums[0] == l and dfs(1, l, 1, {0}) or dfs(1, l - nums[0], 2, {0}) \ No newline at end of file + + # 对数字按降序排序,便于后续剪枝操作 + nums.sort(reverse=True) + + # 如果最大值大于目标边长,则无法构成正方形 + if nums[0] > l: + return False + + # 尝试从第一个元素开始构建每条边 + return nums[0] == l and dfs(1, l, 1, {0}) or dfs(1, l - nums[0], 2, {0}) diff --git a/solutions/python3/474.py b/solutions/python3/474.py index 24a949f..37e6e47 100644 --- a/solutions/python3/474.py +++ b/solutions/python3/474.py @@ -1,19 +1,40 @@ + class Solution: - def findMaxForm(self, strs, m, n): + def findMaxForm(self, strs: list[str], m: int, n: int) -> int: + # 初始化结果为0,使用列表形式便于后续更新最大值 res = [0] + + # 使用集合存储已经计算过的情况以避免重复计算 memo = set() - def dfs(st, zeros, ones, cnt): + + def dfs(st: dict[int, int], zeros: int, ones: int, cnt: int) -> None: + """ + 深度优先搜索,尝试从当前字符串集合中选择最优组合 + + :param st: 当前剩余的可用字符串计数 + :param zeros: 剩余可用0的数量 + :param ones: 剩余可用1的数量 + :param cnt: 当前已选字符串数量 + """ if (zeros, ones, cnt) not in memo: + # 更新最大选择数量 if cnt > res[0]: res[0] = cnt + if zeros or ones: for s in st: if st[s] and cntr[s]["0"] <= zeros and cntr[s]["1"] <= ones: + # 选择当前字符串并递归处理剩余情况 st[s] -= 1 dfs(st, zeros - cntr[s]["0"], ones - cntr[s]["1"], cnt + 1) st[s] += 1 - memo.add((zeros, ones, cnt)) - cntr = {s:collections.Counter(s) for s in strs} + memo.add((zeros, ones, cnt)) + + # 计算每个字符串中0和1的个数 + cntr = {s: collections.Counter(s) for s in strs} + + # 调用深度优先搜索函数开始计算最大组合数量 dfs(collections.Counter(strs), m, n, 0) - return res[0] \ No newline at end of file + + return res[0] diff --git a/solutions/python3/475.py b/solutions/python3/475.py index c464bee..16e9450 100644 --- a/solutions/python3/475.py +++ b/solutions/python3/475.py @@ -1,13 +1,29 @@ + class Solution: - def findRadius(self, houses, heaters): + # 定义一个解决类,用于找到供暖器的最大半径 + + def findRadius(self, houses: list[int], heaters: list[int]) -> int: + # 对供暖器的位置进行排序 heaters.sort() + + # 初始化最大半径为0 r = 0 + + # 遍历每个房屋位置 for h in houses: + # 使用二分查找确定当前房屋最近的供暖器位置 ind = bisect.bisect_left(heaters, h) + + # 如果房屋在所有供暖器之后 if ind == len(heaters): - r = max(r, h - heaters[-1]) + r = max(r, h - heaters[-1]) # 更新最大半径 + + # 如果房屋在第一个供暖器之前 elif ind == 0: - r = max(r, heaters[0] - h) + r = max(r, heaters[0] - h) # 更新最大半径 + else: + # 计算当前房屋到前后两个供暖器的距离,取较小者更新最大半径 r = max(r, min(heaters[ind] - h, h - heaters[ind - 1])) - return r \ No newline at end of file + + return r diff --git a/solutions/python3/476.py b/solutions/python3/476.py index 29c274a..b4d4836 100644 --- a/solutions/python3/476.py +++ b/solutions/python3/476.py @@ -1,7 +1,8 @@ + class Solution: def findComplement(self, num): """ - :type num: int - :rtype: int + :type num: int # 输入整数num + :rtype: int # 返回补码 """ - return int("".join([str((int(i)+1)%2) for i in bin(num)[2:]]),2) \ No newline at end of file + return int("".join([str((int(i)+1)%2) for i in bin(num)[2:]]), 2) # 计算补码并转换为十进制返回 diff --git a/solutions/python3/477.py b/solutions/python3/477.py index 1e951e4..94a25a1 100644 --- a/solutions/python3/477.py +++ b/solutions/python3/477.py @@ -1,8 +1,18 @@ + class Solution: def totalHammingDistance(self, nums): + # 初始化一个长度为32的列表ones来存储每个位上1的数量,初始化nums长度变量n和结果变量res ones, n, res = [0] * 32, len(nums), 0 + + # 遍历输入的nums列表中的每一个数字num for num in nums: + # 将数字转换为二进制字符串,并反转该字符串,从最低位开始计算 for i, c in enumerate(bin(num)[2:][::-1]): - if c == "1": ones[i] += 1 - for one in ones: res += one * (n - one) - return res \ No newline at end of file + if c == "1": # 如果当前位是1,则ones对应索引位置加一 + ones[i] += 1 + + # 遍历ones列表中的每个值,累加结果res为每个位上1的数量与0的数量之积 + for one in ones: + res += one * (n - one) + + return res # 返回最终的汉明距离总和 diff --git a/solutions/python3/478.py b/solutions/python3/478.py index 1a956cf..bf50cae 100644 --- a/solutions/python3/478.py +++ b/solutions/python3/478.py @@ -1,8 +1,21 @@ + class Solution: - def __init__(self, radius, x_center, y_center): - self.x, self.y, self.r = x_center, y_center, radius + def __init__(self, radius: float, x_center: float, y_center: float): + """ + 初始化圆的中心坐标和半径。 + :param radius: 圆的半径,float 类型 + :param x_center: 圆心在 x 轴上的坐标,float 类型 + :param y_center: 圆心在 y 轴上的坐标,float 类型 + """ + self.x = x_center # 圆心横坐标 + self.y = y_center # 圆心纵坐标 + self.r = radius # 圆的半径 - def randPoint(self): + def randPoint(self) -> List[float]: + """ + 随机生成圆内的一点。 + :return: 返回一个包含两个 float 值的列表,表示随机点的坐标 (x, y) + """ r, angle, scale = random.uniform(0, self.r), random.uniform(0, 2 * math.pi), math.sqrt(random.uniform(0, 1)) - return [self.x + self.r * scale * math.cos(angle), self.y + self.r * scale * math.sin(angle)] \ No newline at end of file + return [self.x + self.r * scale * math.cos(angle), self.y + self.r * scale * math.sin(angle)] diff --git a/solutions/python3/479.py b/solutions/python3/479.py index 6c858be..794f65a 100644 --- a/solutions/python3/479.py +++ b/solutions/python3/479.py @@ -1,7 +1,28 @@ + class Solution: - def largestPalindrome(self, n): + def largestPalindrome(self, n: int) -> int: """ - :type n: int - :rtype: int + :type n: int # 输入的整数n,表示回文数的位数 + :rtype: int # 返回值为最大可能的n位回文数 """ - return list(num for i,num in enumerate([0,9,987,123,597,677,1218,877,475]) if i==n)[0] \ No newline at end of file + + # 回文数的最大可能取值列表(预先计算好的) + max_palindromes = [0, 9, 987, 123, 597, 677, 1218, 877, 475] + + # 返回对应位数的回文数 + return max_palindromes[n] + + + +class Solution: + def largestPalindrome(self, n: int) -> int: + """ + :type n: int # 输入的整数n,表示回文数的位数 + :rtype: int # 返回值为最大可能的n位回文数 + """ + + # 回文数的最大可能取值列表(预先计算好的) + max_palindromes = [0, 9, 987, 123, 597, 677, 1218, 877, 475] + + # 返回对应位数的回文数 + return max_palindromes[n] diff --git a/solutions/python3/48.py b/solutions/python3/48.py index a756db3..a1449e5 100644 --- a/solutions/python3/48.py +++ b/solutions/python3/48.py @@ -1,3 +1,9 @@ + class Solution: + # 定义一个类,用于处理矩阵旋转操作 + def rotate(self, matrix): - matrix[:] = [[row[i] for row in matrix[::-1]] for i in range(len(matrix))] \ No newline at end of file + # 旋转90度的矩阵 + # 中文注释:此方法实现将输入的矩阵顺时针旋转90度 + matrix[:] = [[row[i] for row in matrix[::-1]] for i in range(len(matrix))] + # 优化说明:使用切片操作`matrix[:]`来原地修改矩阵,避免额外的空间开销 diff --git a/solutions/python3/480.py b/solutions/python3/480.py index 4b5e6c8..6386982 100644 --- a/solutions/python3/480.py +++ b/solutions/python3/480.py @@ -1,9 +1,28 @@ + class Solution: def medianSlidingWindow(self, nums, k): - window = sorted(nums[:k]) + """ + :param nums: List[int] - 输入数组 + :param k: int - 窗口大小 + :return: List[float] - 滑动窗口的中位数序列 + + 该方法用于计算给定数组 nums 中长度为 k 的滑动窗口的中位数。 + + 方法步骤: + 1. 初始化第一个窗口,将其排序。 + 2. 遍历整个数组,每次移除最左边的元素并插入当前遍历到的新元素。 + 3. 计算并记录每个窗口的中位数。 + """ + window = sorted(nums[:k]) # 初始滑动窗口 medians = [] - for a, b in zip(nums, nums[k:] + [0]): + + for a, b in zip(nums[:-k+1], nums[k-1:]): + # 滑动窗口的中位数计算,取中间两个元素的平均值 medians.append((window[k//2] + window[~(k//2)]) / 2.) + + # 移除滑动窗口最左边的元素 window.remove(a) + # 插入新元素,并保持有序性 bisect.insort(window, b) - return medians \ No newline at end of file + + return medians diff --git a/solutions/python3/481.py b/solutions/python3/481.py index 610d5d7..017ed78 100644 --- a/solutions/python3/481.py +++ b/solutions/python3/481.py @@ -1,10 +1,32 @@ + class Solution(object): + # 定义一个类来解决魔数字符串问题 + def magicalString(self, n): + """ + :param n: int - 需要生成的魔数字符串长度 + :return: int - 魔数字符串中数字1的数量 + + 中文注释: + 1. 初始化计数器cnt,初始魔数字符串s为"1",布尔值two用于交替添加字符2或1。 + 2. 使用for循环生成魔数字符串直到长度达到n-1。 + 3. 根据s[i]的值决定cnt加1,并在末尾添加相应数量的2或1。 + 4. 更新boolean变量two以交替添加字符。 + 5. 如果n为1,直接返回1;否则返回计数器cnt的结果。 + + 英文注释: + 1. Initialize a counter cnt, and the initial magical string s as "1", and boolean variable two to alternate adding '2' or '1'. + 2. Use a for loop to generate the magical string until its length reaches n-1. + 3. Based on the value of s[i], increment cnt by 1 and append the corresponding number of '2' or '1' at the end. + 4. Update boolean variable two to alternate between adding characters. + 5. If n is 1, directly return 1; otherwise, return the result of counter cnt. + """ cnt, s, two = 0, "1", True for i in range(n - 1): if s[i] == "1": cnt += 1 s += "2" if two else "1" - else: s += "22" if two else "11" + else: + s += "22" if two else "11" two = not two - return cnt if n != 1 else 1 \ No newline at end of file + return cnt if n != 1 else 1 diff --git a/solutions/python3/482.py b/solutions/python3/482.py index 437b05e..b601273 100644 --- a/solutions/python3/482.py +++ b/solutions/python3/482.py @@ -1,4 +1,10 @@ + class Solution: - def licenseKeyFormatting(self, S, K): + # 定义一个类来处理许可证格式化 + + def licenseKeyFormatting(self, S: str, K: int) -> str: + # 移除字符串中的 '-',转换为大写,并反转字符串 S = S.replace("-", "").upper()[::-1] - return '-'.join([S[i:i+K] for i in range(0, len(S), K)])[::-1] \ No newline at end of file + + # 使用切片将字符串分割成长度为K的子串,并用 '-' 连接这些子串,最后再反转回来 + return '-'.join([S[i:i+K] for i in range(0, len(S), K)])[::-1] diff --git a/solutions/python3/483.py b/solutions/python3/483.py index cbfc5ad..25a95d0 100644 --- a/solutions/python3/483.py +++ b/solutions/python3/483.py @@ -1,8 +1,17 @@ + class Solution: - def smallestGoodBase(self, n): + def smallestGoodBase(self, n: str) -> str: + # 将输入的字符串n转换为整数 n = int(n) + + # 计算log(n, 2),作为循环上限,确保m范围合理 for m in range(int(math.log(n, 2)), 1, -1): - k = int(n ** m ** -1) - if (k ** (m + 1) -1) // (k - 1) == n: + # 计算k的值,即等比序列的第一个项 + k = int(n ** (1/m)) + + # 检查是否满足等比数列求和公式等于n,满足则返回k + if (k ** (m + 1) - 1) // (k - 1) == n: return str(k) - return str(n-1) \ No newline at end of file + + # 如果没有找到满足条件的m,则返回n-1作为特殊情况处理 + return str(n-1) diff --git a/solutions/python3/484.py b/solutions/python3/484.py index 91846a1..eb86a3e 100644 --- a/solutions/python3/484.py +++ b/solutions/python3/484.py @@ -1,10 +1,19 @@ + class Solution: + # 定义一个Solution类,包含findPermutation方法 + def findPermutation(self, s): + # 初始化数组arr为长度为s+1的范围列表(从1到len(s)+2),cnt用于记录连续D的数量,n表示字符串s的长度 arr, cnt, n = list(range(1, len(s) + 2)), 0, len(s) + for i in range(n + 1): + # 如果当前字符是"D"且还在范围内,增加计数器cnt if i < n and s[i] == "D": cnt += 1 + elif cnt: - arr[i - cnt:i + 1] = arr[i - cnt:i + 1][::-1] + # 当遇到非"D"或到达字符串末尾时,反转cnt长度的数组段,并重置cnt为0 + arr[i - cnt:i + 1] = arr[i - cnt:i + 1][::-1] cnt = 0 - return arr \ No newline at end of file + + return arr # 返回处理后的数组arr diff --git a/solutions/python3/485.py b/solutions/python3/485.py index 2a23988..a4925d2 100644 --- a/solutions/python3/485.py +++ b/solutions/python3/485.py @@ -1,13 +1,17 @@ + class Solution: def findMaxConsecutiveOnes(self, nums): """ - :type nums: List[int] - :rtype: int + :type nums: List[int] # 输入列表nums,元素为整数 + :rtype: int # 返回最大连续1的数量 """ - cons=[0,0] + cons = [0, 0] # 初始化计数器数组,[当前最大长度, 当前连续1的长度] + for num in nums: - if num==1:cons[1]+=1 - else:cons[1]=0 - cons[0]=max(cons[0],cons[1]) - return cons[0] - \ No newline at end of file + if num == 1: # 如果当前数字是1 + cons[1] += 1 # 更新当前连续1的数量 + else: # 否则,重置当前连续1的数量 + cons[1] = 0 + cons[0] = max(cons[0], cons[1]) # 更新最大连续1的长度 + + return cons[0] # 返回最大连续1的长度 diff --git a/solutions/python3/486.py b/solutions/python3/486.py index 7dad28e..c457a8c 100644 --- a/solutions/python3/486.py +++ b/solutions/python3/486.py @@ -1,10 +1,35 @@ + class Solution: def PredictTheWinner(self, nums): + """ + 判断当前玩家是否能赢得游戏。使用深度优先搜索(DFS)来模拟游戏过程。 + + :param nums: List[int] - 游戏中可选的数字列表 + :return: bool - 当前玩家是否有足够的策略确保胜利 + """ + def dfs(l, r, p1, p2, turn): + """ + 使用深度优先搜索递归模拟游戏。 + + :param l: int - 数组左边界索引 + :param r: int - 数组右边界索引 + :param p1: int - 玩家1当前得分 + :param p2: int - 玩家2当前得分 + :param turn: bool - 当前是否为玩家1的回合(True表示是) + :return: bool - 如果当前玩家能赢得游戏则返回True,否则False + """ if l > r: + # 边界条件:如果索引越界,则比赛结束,检查得分 return p1 >= p2 elif turn: + # 玩家1的回合 + # 选择左边或右边的数字,并递归调用以判断是否能获胜 return dfs(l + 1, r, p1 + nums[l], p2, 0) or dfs(l, r - 1, p1 + nums[r], p2, 0) else: + # 玩家2的回合 + # 必须选择左边或右边的数字,且确保玩家1不能获胜 return dfs(l + 1, r, p1, p2 + nums[l], 1) and dfs(l, r - 1, p1, p2 + nums[r], 1) - return dfs(0, len(nums) - 1, 0, 0, 1) \ No newline at end of file + + # 游戏开始时调用DFS函数,假设当前为玩家1的回合 + return dfs(0, len(nums) - 1, 0, 0, 1) diff --git a/solutions/python3/487.py b/solutions/python3/487.py index f9214d4..9bde26f 100644 --- a/solutions/python3/487.py +++ b/solutions/python3/487.py @@ -1,7 +1,15 @@ + class Solution: + # 定义一个解决方案类 + def findMaxConsecutiveOnes(self, nums): + # 初始化左指针、零的位置和最大连续1的长度 l, zero, mx = 0, -1, 0 + + # 遍历数组加上一个虚拟的0,避免在边界处理 for r, num in enumerate(nums + [0]): - if not num: + if not num: # 如果当前数为0 + # 更新左指针、零的位置以及最大连续1的长度 l, zero, mx = zero + 1, r, max(mx, r - l) - return mx \ No newline at end of file + + return mx # 返回最大连续1的长度 diff --git a/solutions/python3/488.py b/solutions/python3/488.py index 4e217e7..fd9ac6d 100644 --- a/solutions/python3/488.py +++ b/solutions/python3/488.py @@ -1,18 +1,46 @@ + class Solution: - def findMinStep(self, board, hand): - def dfs(s, c): - if not s: return 0 + def findMinStep(self, board: str, hand: str) -> int: + """ + 找出用最少步数匹配给定的字符串序列。 + + 参数: + board (str): 给定的初始字符串序列,需要填充以匹配目标状态。 + hand (str): 可提供的字符,用于填充board。 + + 返回: + int: 使用手头字符填充board所需最小步骤数量。如果无法完成任务返回-1。 + """ + + def dfs(s: str, c: collections.Counter) -> int: + """ + 深度优先搜索,寻找匹配的最少步数。 + + 参数: + s (str): 当前字符串状态。 + c (collections.Counter): 手头字符计数字典。 + + 返回: + int: 从当前状态到目标状态所需的最小步骤数量。如果无法完成任务返回-1。 + """ + if not s: + return 0 res, i = float("inf"), 0 while i < len(s): j = i + 1 - while j < len(s) and s[i] == s[j]: j += 1 + while j < len(s) and s[i] == s[j]: + j += 1 incr = 3 - (j - i) if c[s[i]] >= incr: incr = 0 if incr < 0 else incr c[s[i]] -= incr tep = dfs(s[:i] + s[j:], c) - if tep >= 0: res = min(res, tep + incr) + if tep >= 0: + res = min(res, tep + incr) c[s[i]] += incr i = j return res if res != float("inf") else -1 - return dfs(board, collections.Counter(hand)) \ No newline at end of file + + # 初始化手头字符计数字典 + hand_counter = collections.Counter(hand) + return dfs(board, hand_counter) diff --git a/solutions/python3/489.py b/solutions/python3/489.py index 269762c..eeadea7 100644 --- a/solutions/python3/489.py +++ b/solutions/python3/489.py @@ -1,17 +1,39 @@ + class Solution: - def cleanRoom(self, robot, move = [(-1, 0), (0, -1), (1, 0), (0, 1)]): + def cleanRoom(self, robot, move=[(-1, 0), (0, -1), (1, 0), (0, 1)]): + """ + 清洁机器人清洁房间的算法实现。 + + :param robot: 机器人对象,具有clean(), move(), turnLeft()方法 + :param move: 移动方向列表,默认为上下左右 + """ + def dfs(i, j, cleaned, ind): - robot.clean() - cleaned.add((i, j)) + """ + 深度优先搜索函数用于清洁房间。 + + :param i: 当前横坐标 + :param j: 当前纵坐标 + :param cleaned: 已清理单元集合 + :param ind: 移动方向索引 + """ + + robot.clean() # 清洁当前格子 + cleaned.add((i, j)) # 标记为已清理 + k = 0 - for x, y in move[ind:] + move[:ind]: - if (i + x, j + y) not in cleaned and robot.move(): - dfs(i + x, j + y, cleaned, (ind + k) % 4) + for x, y in move[ind:] + move[:ind]: # 遍历所有可能的方向 + if (i + x, j + y) not in cleaned and robot.move(): # 检查下一步是否可以移动且未被清理过 + dfs(i + x, j + y, cleaned, (ind + k) % 4) # 递归深度优先搜索 + + # 返回上一步,先右转两次,再左转一次 robot.turnLeft() robot.turnLeft() robot.move() robot.turnRight() robot.turnRight() - robot.turnLeft() + + robot.turnLeft() # 尝试下一个方向之前总是先左转,确保每次尝试移动前都在原地 k += 1 - dfs(0, 0, set(), 0) \ No newline at end of file + + dfs(0, 0, set(), 0) # 从 (0, 0) 开始搜索 diff --git a/solutions/python3/49.py b/solutions/python3/49.py index e391258..9a21de2 100644 --- a/solutions/python3/49.py +++ b/solutions/python3/49.py @@ -1,6 +1,15 @@ + class Solution: + # 中文注释:定义一个类来解决字符串分组问题 + # 英文注释: Define a class to solve the anagram grouping problem + def groupAnagrams(self, strs): - dic = collections.defaultdict(list) - for s in strs: - dic["".join(sorted(s))].append(s) - return list(dic.values()) \ No newline at end of file + from collections import defaultdict # 中文注释:导入defaultdict以简化字典的使用;英文注释: Import defaultdict for easier dictionary handling + + dic = defaultdict(list) # 中文注释:创建一个默认值为列表的字典来存储分组后的字符串;英文注释: Create a default dictionary with lists to store grouped strings + + for s in strs: + key = ''.join(sorted(s)) # 中文注释:对每个字符串排序并合并成键;英文注释: Sort each string and join it to form the key + dic[key].append(s) # 中文注释:使用生成的键将原始字符串添加到对应的分组中;英文注释: Use the generated key to append the original string to its corresponding group + + return list(dic.values()) # 中文注释:返回字典中的所有值,即分组后的列表;英文注释: Return all values from the dictionary, which are the grouped lists diff --git a/solutions/python3/490.py b/solutions/python3/490.py index e32d695..39e989f 100644 --- a/solutions/python3/490.py +++ b/solutions/python3/490.py @@ -1,18 +1,45 @@ + class Solution: def hasPath(self, maze, start, destination): - m, n, stopped = len(maze), len(maze[0]), set() + """ + 判断从起始位置能否到达目标位置。 + + 参数: + maze: List[List[int]] - 代表迷宫的地图,1表示墙,0表示可通行。 + start: List[int] - 起始位置坐标 [x, y]。 + destination: List[int] - 目标位置坐标 [x, y]。 + + 返回值: + bool - 如果能从起始位置到达目标位置则返回True,否则返回False。 + """ + m, n, stopped = len(maze), len(maze[0]), set() # 获取迷宫的行数、列数以及已访问的位置集合 + def dfs(x, y): - if (x, y) in stopped: + """ + 深度优先搜索辅助函数。 + + 参数: + x: int - 当前探索位置的x坐标。 + y: int - 当前探索位置的y坐标。 + + 返回值: + bool - 如果从当前位置能到达目标位置则返回True,否则返回False。 + """ + if (x, y) in stopped: # 检查当前位置是否已被访问过 return False - stopped.add((x, y)) - if [x, y] == destination: + stopped.add((x, y)) # 标记当前位置已访问 + + if [x, y] == destination: # 判断是否到达目标位置 return True - for i, j in (-1, 0) , (1, 0), (0, -1), (0, 1): - newX, newY = x, y + + for i, j in (-1, 0), (1, 0), (0, -1), (0, 1): + newX, newY = x, y # 初始化新的探索坐标 while 0 <= newX + i < m and 0 <= newY + j < n and maze[newX + i][newY + j] != 1: - newX += i + newX += i # 沿着当前方向继续移动 newY += j - if dfs(newX, newY): + + if dfs(newX, newY): # 如果从新位置能到达目标位置则返回True return True return False - return dfs(*start) \ No newline at end of file + + return dfs(*start) # 调用深度优先搜索函数,传入起始坐标 diff --git a/solutions/python3/491.py b/solutions/python3/491.py index a716c15..221be34 100644 --- a/solutions/python3/491.py +++ b/solutions/python3/491.py @@ -1,6 +1,15 @@ + class Solution: + # 定义一个类来解决寻找所有非递减子序列的问题 + def findSubsequences(self, nums): + # 初始化结果集,包含空元组作为起点 subs = {()} + + # 遍历输入的数字列表 for num in nums: + # 通过集合操作更新结果集,确保每个新元素仅添加到适当位置 subs |= {sub + (num,) for sub in subs if not sub or sub[-1] <= num} - return [sub for sub in subs if len(sub) >= 2] \ No newline at end of file + + # 过滤并返回长度大于等于2的非递减子序列列表 + return [sub for sub in subs if len(sub) >= 2] diff --git a/solutions/python3/492.py b/solutions/python3/492.py index 9efd24c..1df080c 100644 --- a/solutions/python3/492.py +++ b/solutions/python3/492.py @@ -1,12 +1,17 @@ + class Solution: def constructRectangle(self, area): """ - :type area: int - :rtype: List[int] + :type area: int # 输入参数area,表示矩形的面积 + :rtype: List[int] # 返回一个列表,包含构造矩形的长和宽 """ import math - l, w = int(math.sqrt(area)), int(math.sqrt(area)) - while l*w!=area: - if area%w==0: l=int(area/w) - else: w-=1 - return [l,w] \ No newline at end of file + l, w = int(math.sqrt(area)), int(math.sqrt(area)) # 初始化长和宽为平方根值 + + while l * w != area: # 当长乘以宽不等于面积时循环 + if area % w == 0: # 如果宽度w可以整除面积,则更新长度l + l = int(area / w) + else: + w -= 1 # 否则减小宽度直到找到合适的尺寸 + + return [l, w] # 返回构造的长和宽 diff --git a/solutions/python3/493.py b/solutions/python3/493.py index 8788dfd..adbd4c3 100644 --- a/solutions/python3/493.py +++ b/solutions/python3/493.py @@ -1,13 +1,53 @@ + class Solution: + # 初始化结果列表,用于存储最终的逆序对个数 def reversePairs(self, nums: List[int]) -> int: res = [0] + + # 合并排序,并统计逆序对数量 def merge(nums): - if len(nums) <= 1: return nums + if len(nums) <= 1: + return nums + + # 分治法,递归拆分数组 left, right = merge(nums[:len(nums)//2]), merge(nums[len(nums)//2:]) + for r in right: - add = len(left) - bisect.bisect(left, 2 * r) - if not add: break + # 计算逆序对数量 + add = len(left) - bisect.bisect_left(left, 2 * r) + if not add: + break + res[0] += add - return sorted(left+right) + + return sorted(left + right) + merge(nums) - return res[0] \ No newline at end of file + return res[0] + + +class Solution: + # 初始化结果列表,用于存储最终的逆序对个数 + def reversePairs(self, nums: List[int]) -> int: + res = [0] + + # 合并排序,并统计逆序对数量 + def merge(nums): + if len(nums) <= 1: + return nums + + # 分治法,递归拆分数组 + left, right = merge(nums[:len(nums)//2]), merge(nums[len(nums)//2:]) + + for r in right: + # 计算逆序对数量 + add = len(left) - bisect.bisect_left(left, 2 * r) + if not add: + break + + res[0] += add + + return sorted(left + right) + + merge(nums) + return res[0] diff --git a/solutions/python3/494.py b/solutions/python3/494.py index 9a35691..69946af 100644 --- a/solutions/python3/494.py +++ b/solutions/python3/494.py @@ -1,10 +1,23 @@ + class Solution: - def findTargetSumWays(self, nums, S): - d = {S:1} - for i in range(len(nums)): - new_d = collections.defaultdict(int) - for k, v in d.items(): - new_d[k+nums[i]] += v - new_d[k-nums[i]] += v - d = new_d - return d[0] \ No newline at end of file + def findTargetSumWays(self, nums: list[int], S: int) -> int: + """ + 计算使数组中的所有数字加减之后等于目标和S的方案数。 + + Args: + nums (list[int]): 数组,包含整数。 + S (int): 目标和。 + + Returns: + int: 达到目标和S的方法总数。 + """ + d = {S: 1} # 初始化字典,用于记录当前和为S的方案数量 + + for i in range(len(nums)): # 遍历数组 + new_d = collections.defaultdict(int) # 创建一个新的默认值为0的字典来存储新的组合 + for k, v in d.items(): # 遍历字典d中的每个键值对 + new_d[k + nums[i]] += v # 将当前和与nums[i]相加,计数累加到新字典中 + new_d[k - nums[i]] += v # 将当前和与nums[i]相减,计数累加到新字典中 + d = new_d # 更新d为新的组合字典 + + return d[0] # 返回结果字典中和为0的方案数量 diff --git a/solutions/python3/495.py b/solutions/python3/495.py index 582b31f..385785e 100644 --- a/solutions/python3/495.py +++ b/solutions/python3/495.py @@ -1,13 +1,28 @@ + class Solution: - def findPoisonedDuration(self, timeSeries, duration): + # 定义一个解决方案类 + + def findPoisonedDuration(self, time_series, poison_duration): """ - :type timeSeries: List[int] - :type duration: int + :param time_series: 被毒药影响的时间序列,即每次中毒开始的时间点 + :type time_series: List[int] + :param poison_duration: 每次中毒持续的时长 + :type poison_duration: int + :return: 总共被毒药影响的总时间 :rtype: int """ - timeSeries.sort() - res, upper = 0, 0 - for i, num in enumerate(timeSeries): - if num > upper: upper = num - res, upper = res + num + duration - upper, num + duration - return res \ No newline at end of file + + # 将时间序列按顺序排序,方便计算重叠的时间段 + time_series.sort() + + result, upper_limit = 0, 0 + + for idx, time in enumerate(time_series): + # 如果当前时间段起始点大于上一个结束点,则更新上一个结束点为当前起始点 + if time > upper_limit: + upper_limit = time + + # 计算当前时间段对总时长的贡献,并更新下一个时间段的结束点 + result, upper_limit = result + (time + poison_duration - upper_limit), time + poison_duration + + return result diff --git a/solutions/python3/496.py b/solutions/python3/496.py index 9113ec7..53f459e 100644 --- a/solutions/python3/496.py +++ b/solutions/python3/496.py @@ -1,13 +1,24 @@ + class Solution: def nextGreaterElement(self, nums1, nums2): """ - :type nums1: List[int] - :type nums2: List[int] - :rtype: List[int] + :type nums1: List[int] # 输入列表 nums1,包含整数 + :type nums2: List[int] # 输入列表 nums2,包含整数 + :rtype: List[int] # 返回值为与 nums1 长度相同的结果列表 + + 解题思路:对于 nums1 中的每个元素,在 nums2 中查找第一个大于它的元素。 + 如果找到,则记录该元素;如果未找到,则记录 -1。 """ - out=list() - for num in nums1: + out = list() + + for num in nums1: + # 初始化为-1,表示默认找不到下一个更大元素 out.append(-1) - for j in range(nums2.index(num)+1,len(nums2)): - if nums2[j]>num: out[-1]=nums2[j]; break - return out \ No newline at end of file + + # 从 nums2 中对应元素的下一个位置开始查找 + for j in range(nums2.index(num) + 1, len(nums2)): + if nums2[j] > num: + out[-1] = nums2[j] + break + + return out diff --git a/solutions/python3/497.py b/solutions/python3/497.py index 6fdb9d8..70aacfe 100644 --- a/solutions/python3/497.py +++ b/solutions/python3/497.py @@ -1,11 +1,26 @@ + class Solution: def __init__(self, rects): + """ + 初始化类实例,设置矩形区域,并计算累积范围。 + + :param rects: 输入的矩形区域列表 + """ self.rects, self.ranges, sm = rects, [], 0 for x1, y1, x2, y2 in rects: + # 计算每个矩形面积并累加到总和中,用于后续随机选择 sm += (x2 - x1 + 1) * (y2 - y1 + 1) self.ranges.append(sm) def pick(self): - x1, y1, x2, y2 = self.rects[bisect.bisect_left(self.ranges, random.randint(1, self.ranges[-1]))] - return [random.randint(x1, x2), random.randint(y1, y2)] \ No newline at end of file + """ + 随机选择一个点从给定的矩形区域中。 + + :return: 返回在某个矩形中的随机坐标 + """ + idx = bisect.bisect_left(self.ranges, random.randint(1, self.ranges[-1])) + # 通过累积范围找到对应的矩形 + x1, y1, x2, y2 = self.rects[idx] + # 返回该矩形中的随机点坐标 + return [random.randint(x1, x2), random.randint(y1, y2)] diff --git a/solutions/python3/498.py b/solutions/python3/498.py index ca6b81e..0c65251 100644 --- a/solutions/python3/498.py +++ b/solutions/python3/498.py @@ -1,10 +1,23 @@ + class Solution: def findDiagonalOrder(self, matrix): - i, j, d, res, n, m = 0, 0, 1, [], len(matrix), len(matrix and matrix[0]) + """ + :param matrix: List[List[int]] - 输入的矩阵 + :return: List[int] - 矩阵对角线遍历的结果 + + 思路:使用双指针模拟对角线遍历过程。定义方向变量 d 来控制移动方向。 + """ + i, j, d, res, n, m = 0, 0, 1, [], len(matrix), len(matrix[0]) if matrix else 0 while i < n and j < m: res.append(matrix[i][j]) - if j + 1 < m and (i == 0 and d == 1) or (i == n - 1 and d == -1): j, d = j + 1, -d - elif i + 1 < n and (j == 0 and d == -1) or (j == m - 1 and d == 1): i, d = i + 1, -d - elif d == 1: i, j = i - 1, j + 1 - else: i, j = i + 1, j - 1 - return res \ No newline at end of file + # 判断是否到达边界或方向改变点,调整指针和方向 + if j + 1 < m and (i == 0 and d == 1) or (i == n - 1 and d == -1): + j, d = j + 1, -d + elif i + 1 < n and (j == 0 and d == -1) or (j == m - 1 and d == 1): + i, d = i + 1, -d + # 继续按当前方向移动指针 + elif d == 1: + i, j = i - 1, j + 1 + else: + i, j = i + 1, j - 1 + return res diff --git a/solutions/python3/499.py b/solutions/python3/499.py index 1871c84..ef9ab0a 100644 --- a/solutions/python3/499.py +++ b/solutions/python3/499.py @@ -1,19 +1,47 @@ + +import heapq + class Solution: - def findShortestWay(self, maze, ball, hole): + def findShortestWay(self, maze: list[list[int]], ball: list[int], hole: list[int]) -> str: + """ + Find the shortest path from the ball to the hole in a 2D grid. + + 参数: + maze (list[list[int]]): 球所在的迷宫网格,0 表示空地,1 表示障碍物。 + ball (list[int]): 起始球的位置 [x, y]。 + hole (list[int]): 目标孔的位置 [x, y]。 + + 返回: + str: 从起点到目标孔的最短路径表示字符串(例如 "ldu"),如果无解则返回 "impossible"。 + + 优化说明: + - 使用优先队列来确保每次选择当前最小的距离进行扩展。 + - 借助哈希表记录已经访问过的节点及其路径长度和模式,避免重复计算。 + """ m, n, q, stopped = len(maze), len(maze[0]), [(0, "", ball[0], ball[1])], {(ball[0], ball[1]): [0, ""]} + while q: dist, pattern, x, y = heapq.heappop(q) + + # 如果球已经进入洞中 if [x, y] == hole: return pattern + for i, j, p in ((-1, 0, "u"), (1, 0, "d"), (0, -1, "l"), (0, 1, "r")): newX, newY, d = x, y, 0 + # 球继续滚动直到撞到障碍物或者边界 while 0 <= newX + i < m and 0 <= newY + j < n and maze[newX + i][newY + j] != 1: newX += i newY += j d += 1 - if [newX, newY] == hole: + + # 如果球已经进入洞中则直接退出循环 + if [newX, newY] == hole: break + + # 只有当新位置未被访问过,或者找到了更短路径和模式时才继续 if (newX, newY) not in stopped or [dist + d, pattern + p] < stopped[(newX, newY)]: stopped[(newX, newY)] = [dist + d, pattern + p] heapq.heappush(q, (dist + d, pattern + p, newX, newY)) - return "impossible" \ No newline at end of file + + return "impossible" diff --git a/solutions/python3/5.py b/solutions/python3/5.py index d6c0d18..c184215 100644 --- a/solutions/python3/5.py +++ b/solutions/python3/5.py @@ -1,9 +1,16 @@ + class Solution: def longestPalindrome(self, s: str) -> str: + # 检查并扩展回文子串的辅助函数,英文:Helper function to check and expand palindrome substring def check(l, r): while 0 <= l <= r < len(s) and s[l] == s[r]: l -= 1 r += 1 return s[l + 1:r] - pals = [check(i, i) for i in range(len(s))] + [check(i, i + 1) for i in range(len(s) - 1) if s[i] == s[i + 1]] - return sorted(pals, key = len)[-1] if pals else '' \ No newline at end of file + + # 构建所有可能的回文子串,英文:Construct all possible palindrome substrings + pals = [check(i, i) for i in range(len(s))] + \ + [check(i, i + 1) for i in range(len(s) - 1) if s[i] == s[i + 1]] + + # 返回最长的回文子串,英文:Return the longest palindrome substring + return sorted(pals, key=len)[-1] if pals else '' diff --git a/solutions/python3/50.py b/solutions/python3/50.py index 0adeb5f..3ae3591 100644 --- a/solutions/python3/50.py +++ b/solutions/python3/50.py @@ -1,9 +1,25 @@ + class Solution: + # 定义一个类来实现求幂操作 + def myPow(self, x: float, n: int) -> float: + """ + :param x: 基数,浮点数类型 + :param n: 指数,整型 + :return: 计算结果为浮点数 + + 采用快速幂算法来计算x的n次方 + """ if n < 0: + # 如果指数为负,则将指数取反,并用1/x替换基数 n *= -1 x = 1 / x + elif not n: + # 如果指数为零,返回1(任何数的0次方都是1) return 1 + half = self.myPow(x, n // 2) - return x * half * half if n % 2 else half * half \ No newline at end of file + # 计算x^(n//2)的结果 + return x * half * half if n % 2 else half * half + # 如果n是偶数,直接返回half*half;否则返回x*half*half diff --git a/solutions/python3/500.py b/solutions/python3/500.py index 0c2108f..9bd4d98 100644 --- a/solutions/python3/500.py +++ b/solutions/python3/500.py @@ -1,3 +1,31 @@ + class Solution: + """ + 中文注释: + 定义一个解决方案类,包含一个方法用于查找满足特定条件的单词。 + + English comments: + Define a solution class containing a method to find words that meet specific conditions. + """ + def findWords(self, words): - return [w for w in words if any(not set(w.lower()) - row for row in (set("qwertyuiop"), set("asdfghjkl"), set("zxcvbnm")))] \ No newline at end of file + """ + 中文注释: + 该函数接收一个单词列表作为参数,返回其中只包含英文字母表三行中任意一行的字母的单词。 + + English comments: + This function accepts a list of words as an argument and returns the words that only contain letters from any one of the three rows of the QWERTY keyboard. + """ + + # 定义键盘三行字母集合 + rows = [set("qwertyuiop"), set("asdfghjkl"), set("zxcvbnm")] + + # 过滤并返回符合条件的单词列表 + return [ + w + for w in words + if any( + not (set(w.lower()) - row) # 检查当前单词的小写形式是否完全包含在某一行中 + for row in rows + ) + ] diff --git a/solutions/python3/501.py b/solutions/python3/501.py index a38e25a..fdca6a3 100644 --- a/solutions/python3/501.py +++ b/solutions/python3/501.py @@ -1,20 +1,35 @@ + # Definition for a binary tree node. -# class TreeNode: -# def __init__(self, x): -# self.val = x -# self.left = None -# self.right = None +class TreeNode: + def __init__(self, x): + self.val = x + self.left = None + self.right = None class Solution: - def findMode(self, root): + # 寻找二叉树中的众数 + def findMode(self, root: TreeNode) -> List[int]: """ :type root: TreeNode :rtype: List[int] """ + from collections import Counter + + # 递归遍历函数,统计节点值出现的次数 def traverse(node): - if node: dic[node.val]+=1; traverse(node.left); traverse(node.right) + if node: + dic[node.val] += 1 + traverse(node.left) + traverse(node.right) + + # 初始化计数器 dic = collections.Counter() + # 开始遍历 traverse(root) - mx=max(dic.values(),default=0) - return [k for k,v in dic.items() if v==mx] \ No newline at end of file + + # 获取最大频率 + mx = max(dic.values(), default=0) + + # 返回所有出现频率等于最大频率的节点值 + return [k for k, v in dic.items() if v == mx] diff --git a/solutions/python3/502.py b/solutions/python3/502.py index bd85be5..2655ed3 100644 --- a/solutions/python3/502.py +++ b/solutions/python3/502.py @@ -1,14 +1,27 @@ + class Solution: - def findMaximizedCapital(self, k, W, Profits, Capital): + # 定义一个类来解决最大化投资资本的问题 + + def findMaximizedCapital(self, k: int, W: int, Profits: List[int], Capital: List[int]) -> int: + # 初始化可选项目池和当前可用项目的堆 pool, new = [], [(c, p) for c, p in zip(Capital, Profits)] + + # 将当前可用的项目转换为最小堆 heapq.heapify(new) - for i in range(k): + + # 执行k次投资操作 + for _ in range(k): + # 优先选择可以立即开始的投资项目,即资本要求不大于当前资本W while new and new[0][0] <= W: c, p = heapq.heappop(new) - heapq.heappush(pool, -p) + heapq.heappush(pool, -p) # 将利润加入到最大堆中(通过取负号) + try: + # 如果有可选项目,则执行投资项目 p = -heapq.heappop(pool) - W += p + W += p # 更新当前资本W except: + # 如果没有新的投资项目可供选择,退出循环 break - return W \ No newline at end of file + + return W # 返回最终的资本值 diff --git a/solutions/python3/503.py b/solutions/python3/503.py index b888390..8c75766 100644 --- a/solutions/python3/503.py +++ b/solutions/python3/503.py @@ -1,9 +1,22 @@ + class Solution: + # 定义一个解决方案类 + def nextGreaterElements(self, nums): + # 初始化栈和结果列表 stack, res = [], [-1] * len(nums) - for j in range(2): + + for j in range(2): # 遍历两次数组,以处理环形特性 for i in range(len(nums)): - while stack and (nums[stack[-1]] < nums[i]): res[stack.pop()] = nums[i] - if j == 1 and not stack: break - stack += i, - return res \ No newline at end of file + # 当栈不为空且当前元素大于栈顶对应位置的元素时,更新结果列表并弹出栈顶 + while stack and (nums[stack[-1]] < nums[i]): + res[stack.pop()] = nums[i] + + # 如果是第二次遍历且栈为空,则停止 + if j == 1 and not stack: + break + + # 将当前索引压入栈中 + stack += i, + + return res # 返回结果列表 diff --git a/solutions/python3/504.py b/solutions/python3/504.py index e0e4484..4a2d53f 100644 --- a/solutions/python3/504.py +++ b/solutions/python3/504.py @@ -1,8 +1,15 @@ + class Solution: - def convertToBase7(self, num): + # 将整数转换为7进制表示 + def convertToBase7(self, num: int) -> str: + # 如果num大于0,前导字符串为空;等于0时设为"0";小于0时添加负号 lead = "" if num > 0 else "0" if num == 0 else "-" + res, num = [], abs(num) + # 当num不为0时循环,每次取模7并整除7 while num: res.append(int(num % 7)) num //= 7 - return lead + "".join(str(c) for c in res[::-1]) \ No newline at end of file + + # 反转结果列表,并转换成字符串拼接返回 + return lead + "".join(str(c) for c in res[::-1]) diff --git a/solutions/python3/505.py b/solutions/python3/505.py index 7d96d96..e75d8a5 100644 --- a/solutions/python3/505.py +++ b/solutions/python3/505.py @@ -1,17 +1,37 @@ + +import heapq + class Solution: def shortestDistance(self, maze, start, destination): - m, n, q, stopped = len(maze), len(maze[0]), [(0, start[0], start[1])], {(start[0], start[1]):0} + """ + 中文注释: 该方法用于计算从起始点到目标点的最短距离。 + + 英文注释: This method is used to calculate the shortest distance from the start point to the destination. + """ + m, n, q, stopped = len(maze), len(maze[0]), [(0, start[0], start[1])], {(start[0], start[1]): 0} + + # 使用优先队列进行最短路径搜索 while q: dist, x, y = heapq.heappop(q) + + # 如果当前节点为目标点,直接返回距离 if [x, y] == destination: return dist + + # 四个方向的移动 for i, j in ((-1, 0), (1, 0), (0, -1), (0, 1)): newX, newY, d = x, y, 0 + + # 移动直到遇到障碍物或超出边界 while 0 <= newX + i < m and 0 <= newY + j < n and maze[newX + i][newY + j] != 1: newX += i newY += j d += 1 + + # 如果新的位置没有被访问过,或者新计算的距离更短,则更新距离并加入优先队列 if (newX, newY) not in stopped or dist + d < stopped[(newX, newY)]: stopped[(newX, newY)] = dist + d heapq.heappush(q, (dist + d, newX, newY)) - return -1 \ No newline at end of file + + # 如果没有到达目标点,返回 -1 表示无法到达 + return -1 diff --git a/solutions/python3/506.py b/solutions/python3/506.py index 0f02135..5638bd6 100644 --- a/solutions/python3/506.py +++ b/solutions/python3/506.py @@ -1,4 +1,9 @@ + class Solution: + # 定义一个方法来找到相对排名 def findRelativeRanks(self, nums): - rank = {n:i>2 and str(i+1) or ["Gold","Silver","Bronze"][i] + ' Medal' for i,n in enumerate(sorted(nums,reverse=True))} - return [rank[num] for num in nums] \ No newline at end of file + # 创建一个字典,键为排序后的分数值,值为相应的排名 + rank = {n: i > 2 and str(i + 1) or ["Gold", "Silver", "Bronze"][i] + ' Medal' for i, n in enumerate(sorted(nums, reverse=True))} + + # 根据原始输入的分数列表返回对应的排名 + return [rank[num] for num in nums] diff --git a/solutions/python3/507.py b/solutions/python3/507.py index 47ad07d..5b95e60 100644 --- a/solutions/python3/507.py +++ b/solutions/python3/507.py @@ -1,11 +1,17 @@ + class Solution: def checkPerfectNumber(self, num): """ - :type num: int - :rtype: bool + :type num: int # 输入的整数 + :rtype: bool # 返回是否为完数(真则返回True,假则返回False) + + 检查给定整数是否为完数。 + 完数定义:一个正整数等于其所有正因子之和减去它本身。 """ - sm, div =1, 2 - while div**2<=num: - if num%div==0: sm+=div+(num//div) - div+=1 - return sm==num and div>2 \ No newline at end of file + sm, div = 1, 2 + # 循环条件:当前因子的平方小于或等于num,以减少不必要的计算 + while div ** 2 <= num: + if num % div == 0: + sm += div + (num // div) # 添加所有因子到总和中 + div += 1 + return sm == num and div > 2 # 判断是否为完数,并确保至少有两个因子(排除1) diff --git a/solutions/python3/508.py b/solutions/python3/508.py index 6bc5cfa..4b6c4f0 100644 --- a/solutions/python3/508.py +++ b/solutions/python3/508.py @@ -1,3 +1,4 @@ + # Definition for a binary tree node. # class TreeNode: # def __init__(self, x): @@ -6,21 +7,28 @@ # self.right = None class Solution: - def findFrequentTreeSum(self, root): - """ - :type root: TreeNode - :rtype: List[int] - """ - if not root: return [] + # 寻找二叉树中频率最高的子树和 + def findFrequentTreeSum(self, root: 'TreeNode') -> 'List[int]': + if not root: + return [] # 如果根节点为空,返回空列表 + def traverse(node): - if not node: return 0 + # 遍历每个节点,计算以该节点为根的子树的和 + if not node: + return 0 sm = traverse(node.left) + traverse(node.right) + node.val - if sm in dic: dic[sm] += 1 - else: dic[sm] = 1 + if sm in dic: + dic[sm] += 1 + else: + dic[sm] = 1 return sm + + # 使用字典记录每个子树和出现的频率 dic = {} traverse(root) + + # 找出最高频次 mx = max(dic.values()) - return [k for k in dic.keys() if dic[k] == mx] - \ No newline at end of file + # 返回最高频次的所有子树和 + return [k for k in dic.keys() if dic[k] == mx] diff --git a/solutions/python3/509.py b/solutions/python3/509.py index 42e24cf..25d5585 100644 --- a/solutions/python3/509.py +++ b/solutions/python3/509.py @@ -1,4 +1,6 @@ + class Solution: + # 计算斐波那契数列的第N项,使用递归方式实现 def fib(self, N: int) -> int: + # 如果N大于1,则返回fib(N-1)和fib(N-2)之和;否则直接返回N return self.fib(N - 1) + self.fib(N - 2) if N > 1 else N - \ No newline at end of file diff --git a/solutions/python3/51.py b/solutions/python3/51.py index fe6b627..9885f52 100644 --- a/solutions/python3/51.py +++ b/solutions/python3/51.py @@ -1,16 +1,38 @@ class Solution: - def solveNQueens(self, n): - res = [] - def dfs(i, l, r, m, arr): + def solveNQueens(self, n: int) -> list[str]: + """ + 解决N皇后问题,返回所有满足条件的棋盘布局。 + + 参数: + n (int): 棋盘大小(n x n) + + 返回: + list[str]: 所有解决方案的字符串表示 + """ + result = [] + + def dfs(i: int, left_diag: int, right_diag: int, col: int, board: list[str]): if i == n: - res.append(arr) - else: - l = l[1:] + [0] - r = [0] + r[:-1] - for j in range(n): - if m[j] == l[j] == r[j] == 0: - l[j] = r[j] = m[j] = 1 - dfs(i + 1, l, r, m, arr + [("." * j) + "Q" + ("." * (n - j - 1))]) - l[j] = r[j] = m[j] = 0 - dfs(0, [0] * n, [0] * n, [0] * n, []) - return res \ No newline at end of file + result.append(board[:]) + return + + for j in range(n): + if (col & (1 << j)) and \ + (left_diag & (1 << (i + j))) and \ + (right_diag & (1 << (n - 1 + i - j))): + # Place queen and mark positions as unavailable + col ^= (1 << j) + left_diag ^= (1 << (i + j)) + right_diag ^= (1 << (n - 1 + i - j)) + + new_row = "." * j + "Q" + "." * (n - j - 1) + dfs(i + 1, left_diag, right_diag, col, board + [new_row]) + + # Backtrack + col ^= (1 << j) + left_diag ^= (1 << (i + j)) + right_diag ^= (1 << (n - 1 + i - j)) + + # Initialize with all positions available + dfs(0, (1 << (2*n)) - 1, (1 << (2*n)) - 1, (1 << n) - 1, []) + return result \ No newline at end of file diff --git a/solutions/python3/510.py b/solutions/python3/510.py index 9ebaf14..ec8e845 100644 --- a/solutions/python3/510.py +++ b/solutions/python3/510.py @@ -1,10 +1,16 @@ + class Solution: + # 定义查找二叉搜索树中序后继节点的方法 def inorderSuccessor(self, node: 'Node') -> 'Node': + # 如果当前节点有右子树,则找其最左下的节点作为后继 if node.right: node = node.right while node.left: node = node.left return node + + # 从给定节点开始,向上查找父节点直到找到一个节点是其父节点的左子节点为止 while node.parent and node.parent.left != node: node = node.parent - return node.parent \ No newline at end of file + # 返回最后一个满足条件的父节点作为后继 + return node.parent diff --git a/solutions/python3/513.py b/solutions/python3/513.py index 24c840b..6f0a991 100644 --- a/solutions/python3/513.py +++ b/solutions/python3/513.py @@ -1,14 +1,25 @@ + # Definition for a binary tree node. -# class TreeNode: -# def __init__(self, x): -# self.val = x -# self.left = None -# self.right = None +class TreeNode: + def __init__(self, x): + self.val = x + self.left = None + self.right = None class Solution: + # 寻找二叉树最底层最左边的节点值 + # Find the leftmost value in the last level of a binary tree + def findBottomLeftValue(self, root: TreeNode) -> int: bfs = [root] + while bfs: + # 在每一层中,左节点的值即为该层最左侧节点的值 + # At each level, the leftmost node's value is the leftmost value of that level left = bfs[0].val + + # 使用列表生成式遍历当前层的所有子节点,并添加到队列中 + # Traverse all children nodes of current level and add them to the queue bfs = [child for node in bfs for child in (node.left, node.right) if child] - return left \ No newline at end of file + + return left diff --git a/solutions/python3/514.py b/solutions/python3/514.py index 93093e6..b86c03a 100644 --- a/solutions/python3/514.py +++ b/solutions/python3/514.py @@ -1,9 +1,25 @@ + class Solution: - def findRotateSteps(self, ring, key): - ind, n, dp, pre = collections.defaultdict(list), len(ring), [0] * len(ring), key[0] - for i, c in enumerate(ring): ind[c].append(i) - for i in ind[key[0]]: dp[i] = min(i, n - i) + 1 + # Python 解决旋转环与键的最小步骤问题 + + def findRotateSteps(self, ring: str, key: str) -> int: + # 用于存储字符在环中的位置索引 + index_dict = collections.defaultdict(list) + n = len(ring) # 环的长度 + dp = [0] * n # 动态规划数组,记录到达每个位置的最小步骤数 + + # 初始化: key的第一个字符在ring中对应的所有索引的位置,并计算初始步数 + for i, c in enumerate(ring): + index_dict[c].append(i) + for i in index_dict[key[0]]: + dp[i] = min(i, n - i) + 1 + + # 遍历key中的每个字符,更新dp数组和pre变量 for c in key[1:]: - for i in ind[c]: dp[i] = min(dp[j] + min(i - j, j + n - i) if i >= j else dp[j] + min(j - i, i + n - j) for j in ind[pre]) + 1 - pre = c - return min(dp[i] for i in ind[key[-1]]) \ No newline at end of file + pre = c # 当前处理的字符 + for i in index_dict[c]: + # 更新dp[i]为从上一个字符到当前字符所需的最小步骤数 + dp[i] = min(dp[j] + min(i - j, n + j - i) if i >= j else dp[j] + min(j - i, n + i - j) for j in index_dict[pre]) + 1 + + # 返回最终结果,即key最后一个字符在环中对应位置的最小旋转步骤 + return min(dp[i] for i in index_dict[key[-1]]) diff --git a/solutions/python3/515.py b/solutions/python3/515.py index 4af09ed..8ae8f08 100644 --- a/solutions/python3/515.py +++ b/solutions/python3/515.py @@ -1,23 +1,32 @@ + # Definition for a binary tree node. -# class TreeNode: -# def __init__(self, x): -# self.val = x -# self.left = None -# self.right = None +class TreeNode: + def __init__(self, x): + self.val = x + self.left = None + self.right = None class Solution: - def largestValues(self, root): - """ - :type root: TreeNode - :rtype: List[int] - """ + # Given the root of a binary tree, returns the largest values in each level. + # 中文注释:给定一个二叉树的根节点,返回每一层中的最大值。 + + def largestValues(self, root: TreeNode) -> List[int]: from collections import deque - q, res, target = deque([root]) if root else None, [root.val] if root else [], root + # 初始化队列和结果列表 + # 如果根节点为空,则直接返回空列表 + q, res = deque([root]) if root else None, [] if not root else [root.val] + while q: node = q.popleft() - if node.left: q.append(node.left) - if node.right: q.append(node.right) - if node == target and q: + if node.left: + q.append(node.left) + if node.right: + q.append(node.right) + + # 当前节点是当前层最后一个节点,记录该层最大值 + if not q or node == target: res.append(max([i.val for i in q])) - target = q[-1] - return res \ No newline at end of file + # 更新目标节点为下一层的最右节点 + if q: target = q[-1] + + return res diff --git a/solutions/python3/516.py b/solutions/python3/516.py index 18cd1de..c37cc4f 100644 --- a/solutions/python3/516.py +++ b/solutions/python3/516.py @@ -1,8 +1,22 @@ + class Solution: - def longestPalindromeSubseq(self, s): + def longestPalindromeSubseq(self, s: str) -> int: + # 初始化动态规划表,用于存储子问题的解 dp = [[0 for j in range(len(s))] for i in range(len(s))] + + # 从后往前遍历字符串,确保dp[i+1][j-1]已经计算过 for i in range(len(s) - 1, -1, -1): + # 每个字符单独作为一个回文子序列的最小情况 dp[i][i] = 1 + + # 遍历字符串的后半部分,避免重复计算 for j in range(i + 1, len(s)): - dp[i][j] = dp[i + 1][j - 1] + 2 if s[i] == s[j] else max(dp[i + 1][j], dp[i][j - 1]) - return dp[0][len(s) - 1] \ No newline at end of file + # 如果当前字符和对称位置的字符相等,则长度+2 + if s[i] == s[j]: + dp[i][j] = dp[i + 1][j - 1] + 2 + else: + # 否则取左右子序列的最大值 + dp[i][j] = max(dp[i + 1][j], dp[i][j - 1]) + + # 返回最长回文子序列的长度 + return dp[0][len(s) - 1] diff --git a/solutions/python3/517.py b/solutions/python3/517.py index edf8660..36fefd5 100644 --- a/solutions/python3/517.py +++ b/solutions/python3/517.py @@ -1,8 +1,20 @@ + class Solution: + # 定义一个用于查找移动次数最小值的方法 def findMinMoves(self, machines): + # 计算目标均值和机器总数,初始化累加和、结果变量以及总和 target, n, sm, res, total = sum(machines) // len(machines), len(machines), 0, 0, sum(machines) - if target * n != total: return -1 + + # 检查总和是否满足均值整除条件 + if target * n != total: + return -1 + + # 遍历每台机器 for i in range(n): + # 计算左侧移水量、累加当前机器的容量、计算右侧移水量 l, sm, r = target * i - sm, sm + machines[i], target * (n - i - 1) - total + sm + machines[i] + + # 更新最小移动次数结果 res = max(res, l + r, l, r) - return res \ No newline at end of file + + return res diff --git a/solutions/python3/519.py b/solutions/python3/519.py index fa61eab..cd2b56d 100644 --- a/solutions/python3/519.py +++ b/solutions/python3/519.py @@ -1,14 +1,34 @@ + class Solution: - def __init__(self, n_rows, n_cols): - self.rows, self.cols, self.used = n_rows, n_cols, set() + def __init__(self, n_rows: int, n_cols: int) -> None: + """ + 初始化类,设置行数和列数,并创建一个已使用位置的集合。 + + :param n_rows: 行数 (int) + :param n_cols: 列数 (int) + """ + self.rows = n_rows + self.cols = n_cols + self.used = set() + + def flip(self) -> list: + """ + 随机返回一个未被使用的位置,位置以 [行 - 1, 列 - 1] 的形式返回。 - def flip(self): + :return: 一个未被使用的随机位置 (list) + """ while True: - r, c = random.randint(1, self.rows), random.randint(1, self.cols) - if (r, c) not in self.used: + r = random.randint(1, self.rows) # 随机选择一个行号 + c = random.randint(1, self.cols) # 随机选择一个列号 + if (r, c) not in self.used: # 如果该位置未被使用,则跳出循环并返回 self.used.add((r, c)) return [r - 1, c - 1] - - def reset(self): - self.used = set() \ No newline at end of file + + def reset(self) -> None: + """ + 将已使用的位置集合清空,以便重新开始。 + + :return: 无 (None) + """ + self.used = set() diff --git a/solutions/python3/52.py b/solutions/python3/52.py index dcef9d3..9150cbc 100644 --- a/solutions/python3/52.py +++ b/solutions/python3/52.py @@ -1,16 +1,37 @@ + class Solution: - def totalNQueens(self, n): - res = [0] + def totalNQueens(self, n: int) -> int: + """ + 计算在n×n棋盘上放置不冲突的皇后的方法总数。 + + Parameters: + n (int): 棋盘大小,也是皇后的数量 + + Returns: + int: 放置方法的数量 + """ + res = [0] # 用于存储结果 + def dfs(i, l, r, m): - if i == n: - res[0] += 1 + """ + 深度优先搜索函数。 + + Parameters: + i (int): 当前行索引,表示当前处理的是第i+1行 + l, r (list of int): 分别代表左斜线和右斜线的掩码状态 + m (list of int): 用于存储每一列的状态(1为放置了皇后,0为空) + """ + if i == n: # 当处理完最后一行时 + res[0] += 1 # 结果计数加一 else: - l = l[1:] + [0] - r = [0] + r[:-1] - for j in range(n): - if m[j] == l[j] == r[j] == 0: - l[j] = r[j] = m[j] = 1 - dfs(i + 1, l, r, m) - l[j] = r[j] = m[j] = 0 - dfs(0, [0] * n, [0] * n, [0] * n) - return res[0] \ No newline at end of file + l = l[1:] + [0] # 更新左斜线掩码状态 + r = [0] + r[:-1] # 更新右斜线掩码状态 + + for j in range(n): # 遍历当前行的每个列位置 + if m[j] == l[j] == r[j] == 0: # 当前位置可以放置皇后 + m[j] = l[j] = r[j] = 1 # 放置皇后,并更新掩码状态 + dfs(i + 1, l, r, m) # 处理下一行 + m[j] = l[j] = r[j] = 0 # 恢复状态,回溯 + + dfs(0, [0]*n, [0]*n, [0]*n) + return res[0] diff --git a/solutions/python3/520.py b/solutions/python3/520.py index 2cc7b21..3223579 100644 --- a/solutions/python3/520.py +++ b/solutions/python3/520.py @@ -1,3 +1,7 @@ + class Solution: - def detectCapitalUse(self, word): - return word[0].isupper() and word[1:].islower() or word.isupper() or word.islower() \ No newline at end of file + # 检查给定单词的使用大写字母方式是否正确 + + def detectCapitalUse(self, word: str) -> bool: + # 如果首字母大写且后续全部小写,或全为大写,或全为小写,则符合要求 + return word[0].isupper() and word[1:].islower() or word.isupper() or word.islower() diff --git a/solutions/python3/521.py b/solutions/python3/521.py index 266f40f..5e9c9aa 100644 --- a/solutions/python3/521.py +++ b/solutions/python3/521.py @@ -1,8 +1,18 @@ + class Solution: - def findLUSlength(self, a, b): + # 定义一个名为findLUSlength的方法,用于查找两个字符串中不存在公共子序列的最大长度 + def findLUSlength(self, a: str, b: str) -> int: """ + :param a: 字符串a :type a: str + :param b: 字符串b :type b: str + :return: 如果两个字符串相等则返回-1,否则返回两者长度的最大值 :rtype: int """ - return -1 if a == b else max(len(a), len(b)) \ No newline at end of file + # 如果两个字符串相同,则不存在公共子序列,直接返回-1 + if a == b: + return -1 + else: + # 否则返回两个字符串长度中的较大者 + return max(len(a), len(b)) diff --git a/solutions/python3/522.py b/solutions/python3/522.py index c4744c7..2052d15 100644 --- a/solutions/python3/522.py +++ b/solutions/python3/522.py @@ -1,11 +1,21 @@ + class Solution: + # 定义一个辅助函数 find,用于判断字符串 s 是否是字符串 t 的子序列 def findLUSlength(self, strs): def find(s, t): i = 0 for c in t: - if c == s[i]: i += 1 - if i == len(s): return True + if c == s[i]: + i += 1 + if i == len(s): + return True return False + + # 对字符串列表按长度降序排序,以便优先检查较长的字符串 for s in sorted(strs, key=len, reverse=True): - if sum(find(s, t) for t in strs) == 1: return len(s) - return -1 \ No newline at end of file + # 检查当前字符串 s 是否是其他任何字符串的子序列 + if sum(find(s, t) for t in strs) == 1: + return len(s) + + # 如果没有找到满足条件的字符串,返回 -1 + return -1 diff --git a/solutions/python3/523.py b/solutions/python3/523.py index a0e67fc..ca3cfe3 100644 --- a/solutions/python3/523.py +++ b/solutions/python3/523.py @@ -1,9 +1,25 @@ + class Solution: - def checkSubarraySum(self, nums, k): - if not k: return any(nums[i] == nums[i - 1] == 0 for i in range(1, len(nums))) + # 检查是否存在一个连续子数组,其和为k的倍数 + + def checkSubarraySum(self, nums: list[int], k: int) -> bool: + # 如果k为0,则检查是否有两个相邻元素都为0的情况 + if not k: + return any(nums[i] == nums[i - 1] == 0 for i in range(1, len(nums))) + + # 使用集合存储模k后的余数,sm记录当前子数组的累积和 mods, sm = set(), 0 + + # 遍历nums中的每个元素 for i, num in enumerate(nums): - sm = (sm + num) % k - if (sm in mods and num or (i and not nums[i - 1])) or (not sm and i): return True + sm = (sm + num) % k # 更新累计和对k取模 + + # 检查当前余数是否在集合中,且当前数字不为0或前一个数字不存在的情况 + if (sm in mods and num or (i and not nums[i - 1])) or (not sm and i): + return True # 如果满足条件,则返回True + + # 将当前余数加入集合 mods |= {sm} - return False \ No newline at end of file + + # 遍历结束后未找到符合条件的子数组,返回False + return False diff --git a/solutions/python3/524.py b/solutions/python3/524.py index 314b88c..e252106 100644 --- a/solutions/python3/524.py +++ b/solutions/python3/524.py @@ -1,9 +1,18 @@ + class Solution: - def findLongestWord(self, s, d): - d.sort(key = lambda x: (-len(x), x)) + # 定义一个类来解决寻找字符串中包含的最长词的问题 + + def findLongestWord(self, s: str, d: list[str]) -> str: + # 对字典d中的单词按长度降序排序,如果长度相同则按字典序升序 + d.sort(key=lambda x: (-len(x), x)) + + # 遍历排序后的列表中的每个单词 for w in d: - i = 0 + i = 0 # 初始化指针i指向s的当前比较位置 for c in s: - if c == w[i]: i += 1 - if i == len(w): return w - return "" \ No newline at end of file + if c == w[i]: + i += 1 # 如果s中的字符与w中的匹配,移动指针i + if i == len(w): # 如果整个单词都匹配完成 + return w # 返回该单词 + + return "" # 如果没有找到匹配的最长词,则返回空字符串 diff --git a/solutions/python3/525.py b/solutions/python3/525.py index 92d472c..1c1b5ee 100644 --- a/solutions/python3/525.py +++ b/solutions/python3/525.py @@ -1,10 +1,19 @@ -class Solution: - def findMaxLength(self, nums: List[int]) -> int: - ind, res, sm = {0:-1}, 0, 0 - for i, num in enumerate(nums): - sm += num and 1 or -1 - if sm in ind: - res = max(res, i - ind[sm]) - else: - ind[sm] = i - return res \ No newline at end of file + + class Solution: + # 定义一个类,包含一个寻找最长有效括号子串的方法 + + def findMaxLength(self, nums: List[int]) -> int: + # 初始化索引字典、结果变量和当前计数值 + ind, res, sm = {0: -1}, 0, 0 + + # 遍历输入列表,计算前缀和,并更新结果和索引映射 + for i, num in enumerate(nums): + sm += num and 1 or -1 # 更新当前计数值:遇到1增加1,遇到0减少1 + + if sm in ind: + res = max(res, i - ind[sm]) # 如果当前计数值已存在字典中,则更新最大长度 + else: + ind[sm] = i # 否则将当前计数值及其索引存入字典 + + return res # 返回最长有效子串的长度 + \ No newline at end of file diff --git a/solutions/python3/526.py b/solutions/python3/526.py index 925f801..077c968 100644 --- a/solutions/python3/526.py +++ b/solutions/python3/526.py @@ -1,7 +1,28 @@ -memo = {} + +# 中文注释:定义一个类来解决排列问题,其中countArrangement方法用于计算满足条件的排列个数。 class Solution: - def countArrangement(self, N, arr = None): - if not arr: arr = tuple(range(1, N + 1)) - if (N, arr) in memo or N == 1: return N == 1 and 1 or memo[(N, arr)] - memo[(N, arr)] = sum([self.countArrangement(N-1, arr[:j]+arr[j + 1:]) for j in range(len(arr)) if arr[j]%N==0 or N%arr[j]==0]) - return memo[(N, arr)] \ No newline at end of file + # 英文注释: Define a class to solve the arrangement problem. The countArrangement method is used to calculate the number of valid arrangements. + + memo = {} + + def countArrangement(self, N, arr=None): + # 中文注释:如果未传入arr参数,则初始化为1到N的整数序列。 + # 英文注释: If no arr parameter is provided, initialize it as a sequence of integers from 1 to N. + if not arr: + arr = tuple(range(1, N + 1)) + + # 中文注释:如果该问题已经计算过,或者N等于1,则直接返回结果。 + # 英文注释: If the problem has been calculated before or N equals 1, return the result directly. + if (N, arr) in self.memo or N == 1: + return N == 1 and 1 or self.memo[(N, arr)] + + # 中文注释:计算满足条件的排列数,并存储在memo字典中以备后续使用。 + # 英文注释: Calculate the number of valid arrangements that satisfy the condition, and store it in the memo dictionary for future use. + self.memo[(N, arr)] = sum([ + self.countArrangement(N-1, arr[:j] + arr[j+1:]) + for j in range(len(arr)) if arr[j] % N == 0 or N % arr[j] == 0 + ]) + + # 中文注释:返回计算结果。 + # 英文注释: Return the calculated result. + return self.memo[(N, arr)] diff --git a/solutions/python3/527.py b/solutions/python3/527.py index 8cd4372..d6b1bd5 100644 --- a/solutions/python3/527.py +++ b/solutions/python3/527.py @@ -1,13 +1,20 @@ + class Solution: + # 中文: 定义一个Solution类,包含wordsAbbreviation方法来处理词组缩写。 + # 英文: Define a Solution class with the wordsAbbreviation method to handle word abbreviations. + def wordsAbbreviation(self, dict): - abb = collections.defaultdict(int) - for i, w in enumerate(dict): + abb = collections.defaultdict(int) # 中文: 使用defaultdict统计每个缩写的出现次数。英文: Use defaultdict to count occurrences of each abbreviation. + + for i, w in enumerate(dict): # 中文: 遍历字典中的每一个词。英文: Iterate through the dictionary and its words. for j in range(1, len(w) - 2): - abb[w[:j] + str(len(w) - j - 1) + w[-1]] += 1 - for i, w in enumerate(dict): + abb[w[:j] + str(len(w) - j - 1) + w[-1]] += 1 # 中文: 构造缩写并统计出现次数。英文: Construct abbreviation and count occurrences. + + for i, w in enumerate(dict): # 中文: 再次遍历字典中的每一个词。英文: Iterate through the dictionary again. for j in range(1, len(w) - 2): new = w[:j] + str(len(w) - j - 1) + w[-1] - if abb[new] == 1: + if abb[new] == 1: # 中文: 判断缩写出现次数是否为1。英文: Check if the abbreviation's count is 1. dict[i] = new - break - return dict \ No newline at end of file + break # 中文: 如果是,则更新词组并跳出循环。英文: Update the word and break out of the loop. + + return dict # 中文: 返回处理后的字典。英文: Return the processed dictionary. diff --git a/solutions/python3/528.py b/solutions/python3/528.py index a12c1d7..1a9c28a 100644 --- a/solutions/python3/528.py +++ b/solutions/python3/528.py @@ -1,18 +1,41 @@ + class Solution: def __init__(self, w): + """ + 初始化方法,构建权重对应的区间。 + + 参数: + w (List[int]): 权重列表 + + 返回值:无 + """ self.ranges, sm = [], 0 for weight in w: + # 将当前总和添加到区间起始位置 self.ranges.append([sm, sm + weight]) + # 更新累积权重 sm += weight + # 定义查找范围的最小值和最大值 self.mn, self.mx = 1, sm + def pickIndex(self): + """ + 随机选择一个索引,其概率与对应的权重成正比。 + + 参数:无 + + 返回值: + int: 按照权重随机选择的索引 + """ num, l, r = random.randint(self.mn, self.mx), 0, len(self.ranges) - 1 while l <= r: mid = (l + r) // 2 if self.ranges[mid][1] < num: + # 如果中点右边界小于目标数,调整左边界 l = mid + 1 elif num <= self.ranges[mid][0]: + # 如果目标数小于等于中点左边界,调整右边界 r = mid - 1 else: - return mid \ No newline at end of file + return mid diff --git a/solutions/python3/529.py b/solutions/python3/529.py index d25b5df..a47c8f3 100644 --- a/solutions/python3/529.py +++ b/solutions/python3/529.py @@ -1,19 +1,42 @@ + class Solution(object): def updateBoard(self, board, click): + """ + :param board: List[List[str]] - 代表游戏板的状态,其中'M'表示地雷,'B'表示空白,数字表示周围地雷数量。 + :param click: List[int] - 点击的位置 (i, j)。 + :return: List[List[str]] - 更新后的游戏板状态。 + """ + def explore(i, j): + """ + 深度优先搜索函数,用于探索并标记相邻的空白格子或地雷数量。 + + :param i: int - 当前行索引 + :param j: int - 当前列索引 + """ visited.add((i, j)) - if board[i][j] == "M": board[i][j] = "X" + if board[i][j] == "M": + # 如果是地雷,则标记为X + board[i][j] = "X" else: - points = ((i - 1, j), (i + 1, j), (i, j - 1), (i, j + 1), (i - 1, j - 1), (i - 1, j + 1), (i + 1, j + 1), (i + 1, j - 1)) + points = [(i - 1, j), (i + 1, j), (i, j - 1), (i, j + 1), (i - 1, j - 1), (i - 1, j + 1), (i + 1, j + 1), (i + 1, j - 1)] cnt, adj = 0, [] + for p in points: - if 0 <= p[0] < m and 0 <= p[1] < n: - if board[p[0]][p[1]] == "M": cnt += 1 - elif p not in visited: adj += p, + if 0 <= p[0] < m and 0 <= p[1] < n: # 检查点是否在边界内 + if board[p[0]][p[1]] == "M": + cnt += 1 + elif p not in visited: + adj.append(p) + if cnt == 0: + # 如果没有相邻地雷,则标记为B并继续探索 board[i][j] = "B" for p in adj: explore(p[0], p[1]) - else: board[i][j] = str(cnt) - m, n, visited = len(board), len(board and board[0]), set() - explore(click[0], click[1]) - return board \ No newline at end of file + else: + # 否则,记录周围地雷数量 + board[i][j] = str(cnt) + + m, n, visited = len(board), len(board and board[0]), set() # 获取行数、列数和已访问集合 + explore(click[0], click[1]) # 从点击位置开始探索 + return board # 返回更新后的游戏板状态 diff --git a/solutions/python3/53.py b/solutions/python3/53.py index 6e5fab8..58dedeb 100644 --- a/solutions/python3/53.py +++ b/solutions/python3/53.py @@ -1,7 +1,17 @@ + class Solution: + # 定义一个类来解决问题 + def maxSubArray(self, nums): + # 初始化当前和、最小前缀和、最大子数组和为0,负无穷大 sm, mn, mx = 0, 0, -float("inf") + for num in nums: + # 累加当前数字到总和中 sm += num + + # 更新最大子数组和,采用动态规划的思想 mx, mn = max(mx, sm - mn), min(mn, sm) - return mx \ No newline at end of file + + # 返回最终的最大子数组和 + return mx diff --git a/solutions/python3/530.py b/solutions/python3/530.py index 33bb35f..419a14d 100644 --- a/solutions/python3/530.py +++ b/solutions/python3/530.py @@ -1,18 +1,36 @@ + # Definition for a binary tree node. -# class TreeNode: -# def __init__(self, x): -# self.val = x -# self.left = None -# self.right = None +class TreeNode: + def __init__(self, x): + self.val = x + self.left = None + self.right = None class Solution: + # 初始化结果为最大值 + res = sys.maxsize + def getMinimumDifference(self, root: TreeNode) -> int: - self.res = sys.maxsize + """ + :param root: 二叉树根节点 + :return: 二叉树任意两节点值之差的最小值 + """ + + # 定义深度优先搜索函数,返回当前子树最大最小值 def dfs(node): - if not node: return sys.maxsize, -sys.maxsize + if not node: + return sys.maxsize, -sys.maxsize + + # 对左子树递归调用dfs lMn, lMx = dfs(node.left) + # 对右子树递归调用dfs rMn, rMx = dfs(node.right) + + # 更新最小差值 self.res = min(self.res, node.val - lMx, rMn - node.val) + + # 返回当前节点的最小值和最大值 return min(node.val, lMn), max(node.val, rMx) - dfs(root) - return self.res \ No newline at end of file + + dfs(root) # 调用dfs函数从根节点开始 + return self.res # 返回最终结果 diff --git a/solutions/python3/531.py b/solutions/python3/531.py index eccaa2c..a400841 100644 --- a/solutions/python3/531.py +++ b/solutions/python3/531.py @@ -1,16 +1,27 @@ + class Solution: + # 寻找孤独像素 - 找到满足条件的黑色像素数量 + def findLonelyPixel(self, grid: List[List[str]]) -> int: + # 使用defaultdict存储每行和每列中'B'的位置 rows = collections.defaultdict(list) cols = collections.defaultdict(list) - m, n = len(grid), len(grid[0]) + + m, n = len(grid), len(grid[0]) # 获取矩阵的行数m和列数n + for i in range(m): for j in range(n): if grid[i][j] == 'B': - rows[i].append(j) - cols[j].append(i) - res = 0 + rows[i].append(j) # 将该位置的列索引加入对应行的列表 + cols[j].append(i) # 将该位置的行索引加入对应列的列表 + + res = 0 # 初始化结果计数器 + for i in range(m): for j in range(n): - if grid[i][j] == 'B' and rows[i] == [j] and cols[j] == [i]: + if grid[i][j] == 'B' and len(rows[i]) == 1 and rows[i][0] == j and \ + len(cols[j]) == 1 and cols[j][0] == i: + # 检查当前'B'是否为孤独像素 res += 1 - return res \ No newline at end of file + + return res # 返回满足条件的黑色像素数量 diff --git a/solutions/python3/532.py b/solutions/python3/532.py index 8d264f0..d26cfc2 100644 --- a/solutions/python3/532.py +++ b/solutions/python3/532.py @@ -1,16 +1,34 @@ + class Solution: def findPairs(self, nums, k): """ - :type nums: List[int] - :type k: int - :rtype: int + :type nums: List[int] # 输入列表nums,其中包含整数 + :type k: int # 整数值k + :rtype: int # 返回满足条件的pair数量 """ - dic, pair = {}, 0 + + dic, pair = {}, 0 # 初始化字典dic和计数器pair + for num in nums: - if (num-k in dic or num+k in dic) and (not num in dic or (k==0 and dic[num]==1)) and k>=0: - if num-k in dic and k!=0: pair+=1 - if num+k in dic: pair+=1 - if num in dic: dic[num]+=1; continue - if num in dic: continue - dic[num]=1 - return pair \ No newline at end of file + # 检查num-k或num+k在字典中是否存在,同时考虑k==0的情况 + if (num - k in dic or num + k in dic) and \ + (not num in dic or (k == 0 and dic[num] == 1)) and k >= 0: + + # 当k不为零且num-k在字典中时,增加pair计数 + if num - k in dic and k != 0: + pair += 1 + + # 当num+k在字典中时,增加pair计数 + if num + k in dic: + pair += 1 + + # 如果当前数字已在字典中,则只需更新其出现次数 + if num in dic: + dic[num] += 1 + continue + + # 如果当前数字不在字典中,则将其加入字典并设置初始计数为1 + if num not in dic: + dic[num] = 1 + + return pair # 返回满足条件的pair数量 diff --git a/solutions/python3/533.py b/solutions/python3/533.py index da9582d..662427b 100644 --- a/solutions/python3/533.py +++ b/solutions/python3/533.py @@ -1,20 +1,38 @@ + class Solution: - def findBlackPixel(self, picture, N): + def findBlackPixel(self, picture: List[str], N: int) -> int: + """ + 找出由 'B' 构成的恰好有 N 列的黑色像素个数。 + + 参数: + picture (List[str]): 二维列表表示的图片,其中'B'代表黑色像素 + N (int): 黑色像素所在列的数量 + + 返回: + int: 满足条件的黑色像素总数 + """ m, n, res = len(picture), len(picture[0]), 0 + for row in picture: + # 统计当前行中'B'的数量 r_cnt = row.count("B") if r_cnt != N: continue + + # 遍历每列,检查是否满足条件 for j in range(n): if row[j] == "B": - col_cnt = same = 0 + col_cnt, same = 0, 1 # 初始化列中'B'计数和行相同计数 for i in range(m): if picture[i][j] == "B": col_cnt += 1 if picture[i] == row: - same += 1 + same += 1 else: break + + # 判断是否满足条件:列中'B'数量等于行中'B'数量且所有对应行都相同 if r_cnt == col_cnt == same: res += 1 - return res \ No newline at end of file + + return res diff --git a/solutions/python3/536.py b/solutions/python3/536.py index bde4baf..f98c7b9 100644 --- a/solutions/python3/536.py +++ b/solutions/python3/536.py @@ -1,27 +1,39 @@ + # Definition for a binary tree node. -# class TreeNode: -# def __init__(self, x): -# self.val = x -# self.left = None -# self.right = None +class TreeNode: + def __init__(self, x): + self.val = x + self.left = None + self.right = None class Solution: - def str2tree(self, s): + # 将字符串表示的二叉树转换为实际的树节点结构 + def str2tree(self, s: str) -> TreeNode: stack, cur = [], "" + for i, c in enumerate(s): if c.isnumeric() or c == "-": + # 如果当前字符是数字或负号,累积构建当前节点值 cur += c elif not cur: + # 当前节点值未初始化时 if c == ")": + # 遇到右括号时,弹出栈顶节点(结束当前子树) stack.pop() else: + # 当前节点值已累积完成 node = TreeNode(int(cur)) + # 将构建好的节点添加到父节点下 if stack: if not stack[-1].left: stack[-1].left = node else: stack[-1].right = node - cur = "" + + cur = "" # 重置累积字符串 if c == "(": + # 遇到左括号时,将节点压入栈中(开始构建子树) stack.append(node) - return stack and stack[0] or (cur and TreeNode(int(cur))) or [] \ No newline at end of file + + # 返回根节点或空树 + return stack and stack[0] or (cur and TreeNode(int(cur))) or [] diff --git a/solutions/python3/537.py b/solutions/python3/537.py index 3e05048..4496c8d 100644 --- a/solutions/python3/537.py +++ b/solutions/python3/537.py @@ -1,13 +1,17 @@ + class Solution: - def complexNumberMultiply(self, a, b): + def complexNumberMultiply(self, a: str, b: str) -> str: """ - :type a: str - :type b: str - :rtype: str + :type a: str # 输入字符串a,例如 "2+3i" + :type b: str # 输入字符串b,例如 "4+5i" + :rtype: str # 返回结果字符串,例如 "13+14i" + + 实现两个复数的乘法运算。 """ - re, im = 0, 0 - re_a, im_a = list(map(int,a[:-1].split("+"))) - re_b, im_b = list(map(int,b[:-1].split("+"))) - re += re_a * re_b - im_a * im_b - im += re_a * im_b + re_b *im_a - return str(re)+"+"+str(im)+"i" \ No newline at end of file + real_a, imag_a = map(int, a[:-1].split("+")) + real_b, imag_b = map(int, b[:-1].split("+")) + + real_part = real_a * real_b - imag_a * imag_b + imag_part = real_a * imag_b + real_b * imag_a + + return f"{real_part}+{imag_part}i" diff --git a/solutions/python3/538.py b/solutions/python3/538.py index f78cd23..f854ed8 100644 --- a/solutions/python3/538.py +++ b/solutions/python3/538.py @@ -1,21 +1,35 @@ + # Definition for a binary tree node. -# class TreeNode: -# def __init__(self, x): -# self.val = x -# self.left = None -# self.right = None +class TreeNode: + def __init__(self, x): + self.val = x + self.left = None + self.right = None class Solution: - def convertBST(self, root): + # 将二叉搜索树转换为累加树 + # Convert a binary search tree to a greater sum tree (累加树) + def convertBST(self, root: TreeNode) -> TreeNode: """ :type root: TreeNode :rtype: TreeNode """ + def traverse(node): - if not node: return + # 递归遍历右子树 + if not node: + return traverse(node.right) + + # 更新当前节点值为累加和 node.val = residue[0] = node.val + residue[0] + + # 递归遍历左子树 traverse(node.left) - return node + + # 初始化累加和列表 residue = [0] - return traverse(root) \ No newline at end of file + + # 调用遍历函数并返回结果 + return traverse(root) + diff --git a/solutions/python3/539.py b/solutions/python3/539.py index 59fdd28..d663955 100644 --- a/solutions/python3/539.py +++ b/solutions/python3/539.py @@ -1,11 +1,22 @@ + class Solution: + # 寻找时间数组中最小的时间差 + def findMinDifference(self, tp): + # 将时间字符串转换为分钟数 def getMinute(t): h , m = t.split(":") return int(h) * 60 + int(m) + + # 对时间进行排序 tp = sorted(map(getMinute, tp)) - mn = sys.maxsize + + mn = sys.maxsize # 初始化最小时间差为一个很大的数 + + # 遍历时间数组,找到最小的时间差 for i in range(len(tp) - 1): mn = min(mn, tp[i + 1] - tp[i]) - if mn == 0: return 0 - return min(mn, 1440 + tp[0] - tp[-1]) \ No newline at end of file + if mn == 0: return 0 # 如果找到了0分钟的间隔直接返回 + + # 考虑跨午夜的情况 + return min(mn, 1440 + tp[0] - tp[-1]) # 返回最小的时间差,考虑跨越一天的情况 diff --git a/solutions/python3/54.py b/solutions/python3/54.py index aead196..e86d2b4 100644 --- a/solutions/python3/54.py +++ b/solutions/python3/54.py @@ -1,32 +1,63 @@ + class Solution: def spiralOrder(self, matrix: List[List[int]]) -> List[int]: + """ + 给定一个整数矩阵,按螺旋顺序返回其元素。 + + 中文注释:给定一个整数矩阵,按螺旋顺序返回其元素。 + """ res = [] seen = set() + + """ + 定义递归深度优先搜索函数,用于模拟螺旋遍历过程。 + + 中文注释:定义递归深度优先搜索函数,用于模拟螺旋遍历过程。 + """ def dfs(i, j, d): seen.add((i, j)) res.append(matrix[i][j]) - if d == 'r': + + if d == 'r': # 右 + next_dir = 'd' if j + 1 < n and (i, j + 1) not in seen: dfs(i, j + 1, d) - elif i + 1 < m and (i + 1, j) not in seen: - dfs(i + 1, j , 'd') - elif d == 'd': + elif i + 1 < m and (i + 1, j) not in seen: # 下 + next_dir = 'd' + dfs(i + 1, j, next_dir) + elif d == 'd': # 下 + next_dir = 'l' if i + 1 < m and (i + 1, j) not in seen: - dfs(i + 1, j , d) - elif j and (i, j - 1) not in seen: - dfs(i, j - 1, 'l') - elif d == 'l': - if j and (i, j - 1) not in seen: + dfs(i + 1, j, d) + elif j - 1 >= 0 and (i, j - 1) not in seen: # 左 + next_dir = 'l' + dfs(i, j - 1, next_dir) + elif d == 'l': # 左 + next_dir = 'u' + if j - 1 >= 0 and (i, j - 1) not in seen: dfs(i, j - 1, d) - elif i and (i - 1, j) not in seen: - dfs(i - 1, j, 'u') - else: - if i and (i - 1, j) not in seen: + elif i - 1 >= 0 and (i - 1, j) not in seen: # 上 + next_dir = 'u' + dfs(i - 1, j, next_dir) + else: # u(上) + if i - 1 >= 0 and (i - 1, j) not in seen: dfs(i - 1, j, d) elif j + 1 < n and (i, j + 1) not in seen: dfs(i, j + 1, 'r') + + """ + 如果输入矩阵为空,直接返回空列表。 + + 中文注释:如果输入矩阵为空,直接返回空列表。 + """ if not matrix: return [] m, n = len(matrix), len(matrix[0]) + + """ + 从 (0, 0) 点开始,初始方向为 'r'(右)进行遍历 + + 中文注释:从 (0, 0) 点开始,初始方向为 'r'(右)进行遍历 + """ dfs(0, 0, 'r') + return res - \ No newline at end of file diff --git a/solutions/python3/540.py b/solutions/python3/540.py index b248295..db7a1f7 100644 --- a/solutions/python3/540.py +++ b/solutions/python3/540.py @@ -1,17 +1,24 @@ + class Solution: def singleNonDuplicate(self, nums): """ - :type nums: List[int] - :rtype: int + :type nums: List[int] # 输入的列表nums,包含多个整数 + :rtype: int # 返回一个整数,即列表中唯一的非重复元素 """ - left, right = 0, len(nums)-1 - while left<=right: - mid = (left+right)//2 - if mid+1=0 and nums[mid] == nums[mid-1]: - if mid % 2 == 0: right = mid-2 - else: left = mid+1 - else: return nums[mid] - \ No newline at end of file + left, right = 0, len(nums) - 1 + while left <= right: + mid = (left + right) // 2 + if mid + 1 < len(nums) and nums[mid] == nums[mid + 1]: + # 如果mid和mid+1相等,说明非重复元素在右半部分 + if mid % 2 == 0: + left = mid + 2 + else: + right = mid - 1 + elif mid - 1 >= 0 and nums[mid] == nums[mid - 1]: + # 如果mid和mid-1相等,说明非重复元素在左半部分 + if mid % 2 == 0: + right = mid - 2 + else: + left = mid + 1 + else: + return nums[mid] diff --git a/solutions/python3/541.py b/solutions/python3/541.py index 778b1b6..3d46505 100644 --- a/solutions/python3/541.py +++ b/solutions/python3/541.py @@ -1,8 +1,12 @@ + class Solution: - def reverseStr(self, s, k): + def reverseStr(self, s: str, k: int) -> str: """ - :type s: str - :type k: int - :rtype: str + :param s: 输入字符串 + :param k: 每段长度 + :return: 反转指定段落后的字符串 """ - return "".join([s[i:i+k][::-1]+s[i+k:i+2*k] if len(s)>=i or len(s)>i-k else s[k*i:][::-1] for i in range(0,len(s),k*2)]) \ No newline at end of file + + # 使用列表推导式,分段处理字符串 + return "".join([s[i:i + k][::-1] + s[i + k:i + 2 * k] + for i in range(0, len(s), 2 * k)]) # 每2k个字符为一段进行处理 diff --git a/solutions/python3/542.py b/solutions/python3/542.py index 314765b..5620441 100644 --- a/solutions/python3/542.py +++ b/solutions/python3/542.py @@ -1,19 +1,32 @@ + class Solution: - def updateMatrix(self, matrix): - m, n = len(matrix), len(matrix and matrix[0]) + # 定义一个类来解决更新矩阵的问题 + + def updateMatrix(self, matrix: list[list[int]]) -> list[list[int]]: + # 获取矩阵的行数和列数 + m, n = len(matrix), len(matrix[0]) + + # 第一遍遍历,将所有非零元素初始化为无穷大,并检查其上方或左方的邻居元素是否可以减少距离 for i in range(m): for j in range(n): if matrix[i][j] != 0: matrix[i][j] = float("inf") + # 检查上方元素,如果上方元素+1更小,则更新当前元素的距离 if i > 0 and matrix[i - 1][j] + 1 < matrix[i][j]: matrix[i][j] = matrix[i - 1][j] + 1 + # 检查左方元素,如果左方元素+1更小,则更新当前元素的距离 if j > 0 and matrix[i][j - 1] + 1 < matrix[i][j]: matrix[i][j] = matrix[i][j - 1] + 1 + + # 第二遍遍历,检查下方或右方的邻居元素是否可以减少距离,并进行更新 for i in range(m - 1, -1, -1): for j in range(n - 1, -1, -1): if matrix[i][j] != 0: + # 检查下方元素,如果下方元素+1更小,则更新当前元素的距离 if i + 1 < m and matrix[i + 1][j] + 1 < matrix[i][j]: matrix[i][j] = matrix[i + 1][j] + 1 + # 检查右方元素,如果右方元素+1更小,则更新当前元素的距离 if j + 1 < n and matrix[i][j + 1] + 1 < matrix[i][j]: matrix[i][j] = matrix[i][j + 1] + 1 - return matrix \ No newline at end of file + + return matrix diff --git a/solutions/python3/543.py b/solutions/python3/543.py index accb244..1a8c825 100644 --- a/solutions/python3/543.py +++ b/solutions/python3/543.py @@ -1,21 +1,41 @@ + # Definition for a binary tree node. -# class TreeNode: -# def __init__(self, x): -# self.val = x -# self.left = None -# self.right = None +class TreeNode: + def __init__(self, x): + self.val = x + self.left = None + self.right = None class Solution: - def diameterOfBinaryTree(self, root): + # 计算二叉树的最大直径 + def diameterOfBinaryTree(self, root: 'TreeNode') -> int: """ :type root: TreeNode :rtype: int + + 输入: + - root: 二叉树的根节点 + 输出: + - 返回二叉树的最大直径 + + 思路: + 使用深度优先搜索(DFS)遍历每个节点,计算以该节点为根的左右子树的最大路径长度之和。 + 更新全局最大值 res[0] 来记录整个树中的最大直径。 """ res = [0] + def traverse(node): + # 如果当前节点为空,返回 0 if not node: return 0 + + # 递归遍历左右子树,并计算路径长度 left, right = traverse(node.left), traverse(node.right) - res[0] = max(left+right, res[0]) - return 1+ max(left, right) + + # 更新最大直径 + res[0] = max(left + right, res[0]) + + # 返回当前节点的最大路径长度 + return 1 + max(left, right) + traverse(root) - return res[0] \ No newline at end of file + return res[0] diff --git a/solutions/python3/544.py b/solutions/python3/544.py index 98af6f7..faefa55 100644 --- a/solutions/python3/544.py +++ b/solutions/python3/544.py @@ -1,5 +1,15 @@ + class Solution: - def findContestMatch(self, n): + # 定义一个类用于解决比赛配对问题 + + def findContestMatch(self, n: int) -> str: + # 初始化参赛选手编号列表,str(i)将数字转换为字符串形式 arr = [str(i) for i in range(1, n + 1)] - while len(arr) > 1: arr = ["(" + arr[i] + "," + arr[len(arr) - 1 - i] + ")" for i in range(len(arr) // 2)] - return ",".join(arr) \ No newline at end of file + + # 当数组长度大于1时继续循环 + while len(arr) > 1: + # 对于每个配对,生成新的格式并替换原列表中的对应位置 + arr = ["(" + arr[i] + "," + arr[len(arr) - 1 - i] + ")" for i in range(len(arr) // 2)] + + # 最终返回数组拼接后的字符串结果 + return ",".join(arr) diff --git a/solutions/python3/545.py b/solutions/python3/545.py index f36a6ae..674ec40 100644 --- a/solutions/python3/545.py +++ b/solutions/python3/545.py @@ -1,41 +1,58 @@ + # Definition for a binary tree node. -# class TreeNode: -# def __init__(self, x): -# self.val = x -# self.left = None -# self.right = None +class TreeNode: + def __init__(self, x): + self.val = x + self.left = None + self.right = None class Solution: + # 获取二叉树的边界节点 def boundaryOfBinaryTree(self, root: TreeNode) -> List[int]: - if not root: return [] - used, res, r = {root}, [root.val], [] + if not root: + return [] + + used, res, r = {root}, [root.val], [] # 初始化已使用节点集合、结果列表和右边界临时列表 + + # 获取左边界节点 def lb(node): if node not in used: used.add(node) res.append(node.val) - if node.left: - lb(node.left) - elif node.right: + if node.left: + lb(node.left) # 先访问左子树 + elif node.right: lb(node.right) + + # 获取右边界节点 def rb(node): if node not in used: used.add(node) r.append(node.val) - if node.right: - rb(node.right) - elif node.left: + if node.right: + rb(node.right) # 先访问右子树 + elif node.left: rb(node.left) + + # 获取叶子节点 def lv(node): if not node.left and not node.right and node not in used: used.add(node) res.append(node.val) - if node.left: + if node.left: lv(node.left) - if node.right: + if node.right: lv(node.right) - if root.left: + + # 处理左边界 + if root.left: lb(root.left) + + # 获取叶子节点 lv(root) + + # 处理右边界 if root.right: rb(root.right) - return res + r[::-1] \ No newline at end of file + + return res + r[::-1] # 结果加上反转后的右边界列表 diff --git a/solutions/python3/546.py b/solutions/python3/546.py index 926bffe..596e66d 100644 --- a/solutions/python3/546.py +++ b/solutions/python3/546.py @@ -1,18 +1,46 @@ + class Solution: def removeBoxes(self, A): + """ + 解决问题:给定一个由整数组成的列表A,从列表中移除所有元素并获取最大分数。 + 移除相同数字的连续段可得额外分数(移除一段长度为k的相同数字得(k+1)^2分)。 + + 参数: + A (List[int]): 由整数组成的列表 + + 返回值: + int: 最大得分 + """ + n = len(A) - memo = [[[0] * n for _ in range(n) ] for _ in range(n)] + memo = [[[0] * n for _ in range(n)] for _ in range(n)] + def dp(i, j, k): - if i > j: return 0 + """ + 动态规划函数,计算移除子数组A[i:j+1]的最大得分,其中连续相同数字k表示已经预处理的连续段。 + + 参数: + i (int): 子数组起始索引 + j (int): 子数组结束索引 + k (int): 连续相同数字计数 + + 返回值: + int: 移除子数组的最大得分 + """ + if i > j: + return 0 if not memo[i][j][k]: m = i - while m+1 <= j and A[m+1] == A[i]: + # 寻找A[i]的连续段并合并进k中 + while m + 1 <= j and A[m+1] == A[i]: m += 1 i, k = m, k + m - i - ans = dp(i+1, j, 0) + (k+1) ** 2 + ans = dp(i+1, j, 0) + (k+1)**2 + # 尝试在A[i]和A[j]之间插入分界线,以获得更大得分 for m in range(i+1, j+1): if A[i] == A[m]: ans = max(ans, dp(i+1, m-1, 0) + dp(m, j, k+1)) memo[i][j][k] = ans return memo[i][j][k] - return dp(0, n-1, 0) \ No newline at end of file + + return dp(0, n-1, 0) diff --git a/solutions/python3/547.py b/solutions/python3/547.py index 64ab8c2..93eafa4 100644 --- a/solutions/python3/547.py +++ b/solutions/python3/547.py @@ -1,10 +1,27 @@ + class Solution: - def findCircleNum(self, m): - res, n = 0, len(m) - def explore(i): - m[i][i] = 0 - for j in range(n): - if i != j and m[i][j] == m[j][j] == 1: explore(j) - for i in range(n): - if m[i][i] == 1: explore(i); res += 1 - return res \ No newline at end of file + def findCircleNum(self, m): # 寻找朋友圈数量 + + """ + :param m: 友情关系矩阵,m[i][j] = 1 表示 i 和 j 是朋友,0 则不是 + :return: 返回朋友圈的数量 + """ + + res, n = 0, len(m) # 初始化结果和矩阵大小 + + def explore(i): # 深度优先搜索函数 + """ + :param i: 当前要探索的朋友编号 + :return: 无返回值,用于标记已访问过的节点 + """ + m[i][i] = 0 # 标记当前节点为已访问 + for j in range(n): # 遍历所有节点 + if i != j and m[i][j] == m[j][j] == 1: # 如果是朋友且未访问过 + explore(j) # 递归探索 + + for i in range(n): # 遍历每个可能的起始点 + if m[i][i] == 1: # 初始节点为1,表示是一个新的朋友圈起点 + explore(i) + res += 1 # 新发现一个朋友圈 + + return res # 返回朋友圈的数量 diff --git a/solutions/python3/549.py b/solutions/python3/549.py index e256609..1b831b4 100644 --- a/solutions/python3/549.py +++ b/solutions/python3/549.py @@ -1,21 +1,49 @@ + class Solution: + # 定义一个求最长连续序列的方法,输入是树的根节点 def longestConsecutive(self, root): + # 初始化递增和递减计数字典 dec, inc = {}, {} + + # 使用深度优先搜索方法遍历树 def dfs(node): - if not node: return 0 + if not node: + return 0 + + # 递归左子节点,获取其递增长度 l = dfs(node.left) + + # 递归右子节点,获取其递增长度 r = dfs(node.right) + + # 计算当前节点的递增序列长度(考虑左子节点) incL = inc[node.left] + 1 if node.left and node.val == node.left.val + 1 else 1 + + # 计算当前节点的递增序列长度(考虑右子节点) incR = inc[node.right] + 1 if node.right and node.val == node.right.val + 1 else 1 + + # 更新当前节点的最大递增序列长度 inc[node] = max(incL, incR) + + # 计算当前节点的递减序列长度(考虑左子节点) decL = dec[node.left] + 1 if node.left and node.val == node.left.val - 1 else 1 + + # 计算当前节点的递减序列长度(考虑右子节点) decR = dec[node.right] + 1 if node.right and node.val == node.right.val - 1 else 1 + + # 更新当前节点的最大递减序列长度 dec[node] = max(decL, decR) - if node.left and node.right and node.left.val == node.val - 1 and node.right.val == node.val + 1: + + # 如果存在左、右孩子且左右孩子分别满足递增/递减关系,则计算最大连续序列长度 + if node.left and node.right and \ + (node.left.val == node.val - 1 and node.right.val == node.val + 1) or \ + (node.left.val == node.val + 1 and node.right.val == node.val - 1): m = inc[node.left] + dec[node.right] + 1 - elif node.left and node.right and node.left.val == node.val + 1 and node.right.val == node.val - 1: - m = dec[node.left] + inc[node.right] + 1 else: m = 0 + + # 返回当前节点的最大连续序列长度(考虑左右子节点和自身) return max(m, l, r, inc[node], dec[node]) - return dfs(root) \ No newline at end of file + + # 从根节点开始进行深度优先搜索 + return dfs(root) diff --git a/solutions/python3/55.py b/solutions/python3/55.py index 2a7b4fc..37e4b4a 100644 --- a/solutions/python3/55.py +++ b/solutions/python3/55.py @@ -1,11 +1,24 @@ + class Solution: def canJump(self, nums): """ :type nums: List[int] :rtype: bool """ + # 初始化当前能到达的最大索引 mx 和起始位置 i i = mx = 0 + + # 当 i 小于数组长度且 i 不大于最大可到达索引 mx 时,继续循环 while i < len(nums) and i <= mx: - if nums[i] + i >= len(nums) - 1: return True - mx, i = max(mx, i + nums[i]), i + 1 - return False \ No newline at end of file + # 如果从当前位置可以跳到最后一个元素或更远,则返回 True + if nums[i] + i >= len(nums) - 1: + return True + + # 更新能到达的最大索引 mx 为 max(mx, 当前位置加跳跃距离) + mx = max(mx, i + nums[i]) + + # 移动到下一个位置 i+1 + i += 1 + + # 如果跳出循环且无法跳到最后一个元素,则返回 False + return False diff --git a/solutions/python3/551.py b/solutions/python3/551.py index 4c21429..ee9bc9b 100644 --- a/solutions/python3/551.py +++ b/solutions/python3/551.py @@ -1,7 +1,11 @@ + class Solution: + # 检查学生成绩记录是否合格 def checkRecord(self, s): """ - :type s: str - :rtype: bool + :type s: str # 输入字符串s,表示学生的出勤记录 + :rtype: bool # 返回布尔值,True表示合格,False表示不合格 """ - return False if "LLL" in s or s.count("A")>1 else True \ No newline at end of file + + # 如果s中包含"LLL"或者A的数量超过1次,则返回False + return False if "LLL" in s or s.count("A") > 1 else True diff --git a/solutions/python3/553.py b/solutions/python3/553.py index cdc5682..520195e 100644 --- a/solutions/python3/553.py +++ b/solutions/python3/553.py @@ -1,9 +1,21 @@ + class Solution: def optimalDivision(self, nums): """ :type nums: List[int] :rtype: str """ - if len(nums) == 1: return str(nums[0]) - elif len(nums) == 2: return str(nums[0])+"/"+str(nums[1]) - else: return str(nums[0])+"/("+"/".join(str(i) for i in nums[1:])+")" \ No newline at end of file + # 如果列表只有一个数字,直接返回该数字的字符串形式 + if len(nums) == 1: + return str(nums[0]) + + # 如果列表有两个数字,返回两个数字用 '/' 连接的结果 + elif len(nums) == 2: + return str(nums[0]) + "/" + str(nums[1]) + + # 对于长度大于2的列表,优化表达式以最大化除法运算结果 + else: + # 使用 join 方法将剩余元素组合成一个字符串,并在每个元素之间插入 '/' + inner_part = "/".join(str(i) for i in nums[1:]) + # 返回第一个数字与括号内其他元素组合后的最终表达式 + return str(nums[0]) + "/(" + inner_part + ")" diff --git a/solutions/python3/554.py b/solutions/python3/554.py index 070d800..170c395 100644 --- a/solutions/python3/554.py +++ b/solutions/python3/554.py @@ -1,18 +1,27 @@ + class Solution: + # 定义一个类来解决最少打破的砖墙问题 + def leastBricks(self, wall: List[List[int]]) -> int: - m = len(wall) - sm = sum(wall[0]) - cnt = collections.defaultdict(int) + from collections import defaultdict # 导入defaultdict用于统计边界点出现次数 + + m = len(wall) # 墙的高度 + sm = sum(wall[0]) # 第一行砖块的总长度,用于判断是否到达墙的尽头 + cnt = defaultdict(int) # 使用defaultdict来记录每个边界点出现的次数 + for i in range(m): x = 0 for num in wall[i]: - x += num - if x != sm: - cnt[x] += 1 - mx = 0 + x += num # 累加当前砖块长度 + if x != sm: # 如果还没有到达墙的尽头 + cnt[x] += 1 # 记录边界点出现次数 + + mx = 0 # 初始化最大边界点数为0 + for i in range(m): x = 0 for num in wall[i]: - x += num - mx = max(mx, cnt[x]) - return m - mx \ No newline at end of file + x += num # 累加当前砖块长度 + mx = max(mx, cnt[x]) # 更新最大边界点数 + + return m - mx # 返回最小打破的砖墙次数,即总高度减去最大边界点数 diff --git a/solutions/python3/555.py b/solutions/python3/555.py index 9be1f53..adb9921 100644 --- a/solutions/python3/555.py +++ b/solutions/python3/555.py @@ -1,11 +1,21 @@ + class Solution: def splitLoopedString(self, strs): - arr, res = [s > s[::-1] and s or s[::-1] for s in strs], "" + # 将每个字符串处理成按原序或反转后较大者,并初始化结果为空字符串 + arr, res = [s if s > s[::-1] else s[::-1] for s in strs], "" + + # 遍历每个字符串及其反向字符串,尝试不同分割组合方式 for i, word in enumerate(strs): for w in (word, word[::-1]): s, ind = "", 0 + # 寻找当前单词的最佳分割点以构成最大字典序结果 for j in range(len(w)): - if not s or w[j:] + w[:j] > s: s, ind = w[j:] + w[:j], j + if not s or w[j:] + w[:j] > s: + s, ind = w[j:] + w[:j], j + + # 构造最终候选字符串并更新最优解 cur = w[ind:] + "".join(arr[i + 1:]) + "".join(arr[:i]) + w[:ind] - if not res or cur > res: res = cur - return res \ No newline at end of file + if not res or cur > res: + res = cur + + return res diff --git a/solutions/python3/556.py b/solutions/python3/556.py index 41563b3..71cbcb7 100644 --- a/solutions/python3/556.py +++ b/solutions/python3/556.py @@ -1,13 +1,23 @@ + class Solution: - def nextGreaterElement(self, n): - arr = [c for c in str(n)] + # 定义一个方法用于查找下一个更大的数 + def nextGreaterElement(self, n: int) -> int: + arr = [c for c in str(n)] # 将整数转换为字符列表 + + # 从右向左遍历数字的每一位,找到第一个满足arr[l] < arr[r]的位置l for l in range(len(arr) - 2, -1, -1): r = len(arr) - 1 while l < r and arr[r] <= arr[l]: - r -= 1 + r -= 1 # 如果当前右边的数不大于左边的,则向左移动r指针 + if l != r: + # 找到了可以交换的位置,进行交换,并对l之后的部分排序 arr[l], arr[r] = arr[r], arr[l] arr[l + 1:] = sorted(arr[l + 1:]) + + # 将字符列表转换回整数并返回,同时考虑溢出情况 num = int("".join(arr)) return num if -2 ** 31 <= num <= 2 ** 31 - 1 else -1 - return -1 \ No newline at end of file + + # 如果没有找到更大数据,则返回-1 + return -1 diff --git a/solutions/python3/557.py b/solutions/python3/557.py index 7eba590..6bd80cd 100644 --- a/solutions/python3/557.py +++ b/solutions/python3/557.py @@ -1,11 +1,19 @@ + class Solution: - def reverseWords(self, s): + def reverseWords(self, s: str) -> str: """ - :type s: str - :rtype: str + :param s: 输入字符串 + :return: 反转单词后的字符串 """ - j, s_out=0, str() + j, s_out = 0, "" for i, char in enumerate(s): - if i==len(s)-1: s_out+=s[j:i+1][::-1]; return "".join(s_out) - if char==" ": s_out+=s[j:i][::-1]; j=i+1; s_out+=" " - return "".join(s_out) \ No newline at end of file + # 如果是最后一个字符,处理剩余部分并返回结果 + if i == len(s) - 1: + s_out += s[j:i + 1][::-1] + return "".join(s_out) + # 遇到空格,处理当前单词,并重置起始位置 + if char == " ": + s_out += s[j:i][::-1] + " " + j = i + 1 + # 返回最终结果 + return "".join(s_out) diff --git a/solutions/python3/558.py b/solutions/python3/558.py index ccb6b1c..ebaa11b 100644 --- a/solutions/python3/558.py +++ b/solutions/python3/558.py @@ -1,16 +1,40 @@ + class Solution: + # 解决类 + def intersect(self, q1, q2): + """ + 传入两个节点q1和q2,返回它们的交集节点。 + :param q1: Node 类型,第一个节点 + :param q2: Node 类型,第二个节点 + :return: Node 类型,交集结果节点 + """ + + # 如果q1是叶子节点 if q1.isLeaf: + # 返回值为t的逻辑:如果t有值则返回t,否则返回q2 return q1.val and q1 or q2 + + # 如果q2是叶子节点 elif q2.isLeaf: + # 返回值为q2的逻辑:如果q2有值则返回q2,否则返回q1 return q2.val and q2 or q1 + else: + # 递归计算左上交集 tLeft = self.intersect(q1.topLeft, q2.topLeft) + # 递归计算右上交集 tRight = self.intersect(q1.topRight, q2.topRight) + # 递归计算左下交集 bLeft = self.intersect(q1.bottomLeft, q2.bottomLeft) + # 递归计算右下交集 bRight = self.intersect(q1.bottomRight, q2.bottomRight) - if tLeft.isLeaf and tRight.isLeaf and bLeft.isLeaf and bRight.isLeaf and tLeft.val == tRight.val == bLeft.val == bRight.val: - node = Node(tLeft.val, True, None, None, None, None) + + # 如果所有子节点都是叶子且值相等,合并为一个叶子节点 + if tLeft.isLeaf and tRight.isLeaf and bLeft.isLeaf and bRight.isLeaf and \ + tLeft.val == tRight.val == bLeft.val == bRight.val: + node = Node(tLeft.val, True, None, None, None, None) # 合并后的叶子节点 else: - node = Node(False, False, tLeft, tRight, bLeft, bRight) - return node \ No newline at end of file + node = Node(False, False, tLeft, tRight, bLeft, bRight) # 非叶子节点 + + return node diff --git a/solutions/python3/56.py b/solutions/python3/56.py index ea0a995..9c46c99 100644 --- a/solutions/python3/56.py +++ b/solutions/python3/56.py @@ -1,23 +1,38 @@ # Definition for an interval. -# class Interval: -# def __init__(self, s=0, e=0): -# self.start = s -# self.end = e +class Interval: + def __init__(self, s=0, e=0): + self.start = s + self.end = e class Solution: def merge(self, intervals): """ - :type intervals: List[Interval] - :rtype: List[Interval] + :type intervals: List[List[int]] + :rtype: List[List[int]] """ + if not intervals: + return [] + + # Sort by start time instead of end time + intervals.sort(key=lambda x: x[0]) + res = [] - intervals.sort(key = lambda x: x.end) - for intr in intervals: - if not re: - res.append([intr.start, intr.end]) + for interval in intervals: + # If result is empty or no overlap with last interval + if not res or res[-1][1] < interval[0]: + res.append(interval) + # If overlap, merge with last interval else: - s = intr.start - while res and res[-1][1] >= intr.start: - s = min(s, res.pop()[0]) - res.append([s, intr.end]) - return res \ No newline at end of file + res[-1][1] = max(res[-1][1], interval[1]) + + return res + + def insert(self, intervals, newInterval): + """ + :type intervals: List[List[int]] + :type newInterval: List[int] + :rtype: List[List[int]] + """ + # Add new interval and use existing merge logic + intervals.append(newInterval) + return self.merge(intervals) \ No newline at end of file diff --git a/solutions/python3/560.py b/solutions/python3/560.py index c5b0f61..4003779 100644 --- a/solutions/python3/560.py +++ b/solutions/python3/560.py @@ -1,7 +1,16 @@ + class Solution: + # 定义一个类来解决子数组和的问题 + def subarraySum(self, nums, k): + # 初始化字典用于存储累积和的出现次数,结果计数器以及当前累积和 sums, res, sm = {}, 0, 0 + for i in range(len(nums)): - sums[sm], sm = sm in sums and sums[sm] + 1 or 1, sm + nums[i] + # 更新字典中的累积和出现次数,并计算当前元素加入后的新的累积和 + sums[sm], sm = (sums[sm] + 1 if sm in sums else 1), sm + nums[i] + + # 如果当前累积和减去目标值 k 在字典中存在,则累加计数器 if sm - k in sums: res += sums[sm - k] - return res \ No newline at end of file + + return res # 返回结果计数器的值,即满足条件的子数组数量 diff --git a/solutions/python3/561.py b/solutions/python3/561.py index 22ee5a2..ed53df7 100644 --- a/solutions/python3/561.py +++ b/solutions/python3/561.py @@ -1,14 +1,18 @@ + class Solution: def arrayPairSum(self, nums): """ - :type nums: List[int] - :rtype: int + :type nums: List[int] # 输入是一个整数列表 + :rtype: int # 返回一个整数,表示按规则计算的和 """ - nums.sort() - sum=0 - while nums: - num1=nums.pop() - num2=nums.pop() - sum+=num2 - return sum - \ No newline at end of file + nums.sort() # 对输入列表进行排序 + + sum = 0 # 初始化总和为0 + + while nums: # 当nums非空时循环 + num1 = nums.pop() # 弹出最后一个元素作为num1 + num2 = nums.pop() # 弹出倒数第二个元素作为num2 + + sum += num2 # 将num2加到总和中 + + return sum # 返回最终的总和 diff --git a/solutions/python3/562.py b/solutions/python3/562.py index b2b6c6a..68cf83b 100644 --- a/solutions/python3/562.py +++ b/solutions/python3/562.py @@ -1,12 +1,29 @@ + class Solution: + # 定义一个类来解决问题 + def longestLine(self, M): + # 初始化四个方向的最大连续线数字典,以及最大值变量mx、矩阵的行数m和列数n hor, ver, dig, aDig, mx, m, n = {}, {}, {}, {}, 0, len(M), len(M and M[0]) + for i in range(m): + # 遍历每一行 for j in range(n): + # 如果当前位置为1(表示存在线) if M[i][j]: - ver[(i, j)] = j > 0 and M[i][j - 1] and ver[(i, j - 1)] + 1 or 1 - hor[(i, j)] = i > 0 and M[i - 1][j] and hor[(i - 1, j)] + 1 or 1 - dig[(i, j)] = i > 0 and j > 0 and M[i - 1][j - 1] and dig[(i - 1, j - 1)] + 1 or 1 - aDig[(i, j)] = i > 0 and j + 1 < n and M[i - 1][j + 1] and aDig[(i - 1, j + 1)] + 1 or 1 + # 更新竖直方向的最大连续线数 + ver[(i, j)] = (ver.get((i, j - 1), 0) + 1) if j > 0 and M[i][j - 1] else 1 + + # 更新水平方向的最大连续线数 + hor[(i, j)] = (hor.get((i - 1, j), 0) + 1) if i > 0 and M[i - 1][j] else 1 + + # 更新主对角线方向的最大连续线数 + dig[(i, j)] = (dig.get((i - 1, j - 1), 0) + 1) if i > 0 and j > 0 and M[i - 1][j - 1] else 1 + + # 更新副对角线方向的最大连续线数 + aDig[(i, j)] = (aDig.get((i - 1, j + 1), 0) + 1) if i > 0 and j + 1 < n and M[i - 1][j + 1] else 1 + + # 更新最大值mx mx = max(mx, ver[(i, j)], hor[(i, j)], dig[(i, j)], aDig[(i, j)]) - return mx \ No newline at end of file + + return mx diff --git a/solutions/python3/563.py b/solutions/python3/563.py index 56b86b4..ab3e48f 100644 --- a/solutions/python3/563.py +++ b/solutions/python3/563.py @@ -1,22 +1,34 @@ + # Definition for a binary tree node. -# class TreeNode: -# def __init__(self, x): -# self.val = x -# self.left = None -# self.right = None +class TreeNode: + def __init__(self, x): + self.val = x + self.left = None + self.right = None class Solution: - def findTilt(self, root): + # 计算二叉树的倾斜度 + def findTilt(self, root: 'TreeNode') -> 'int': """ :type root: TreeNode :rtype: int """ + def traverse(node): - if not node: return 0 + # 如果节点为空,返回0 + if not node: + return 0 + # 递归计算左子树的值和 left = traverse(node.left) + # 递归计算右子树的值和 right = traverse(node.right) - res.append(abs(right -left)) + # 将左右子树值差的绝对值加入结果列表 + res.append(abs(right - left)) + # 返回当前节点及其子树的值和 return node.val + left + right + res = [] + # 从根节点开始遍历 traverse(root) - return sum(res) \ No newline at end of file + # 返回所有倾斜度之和 + return sum(res) diff --git a/solutions/python3/564.py b/solutions/python3/564.py index 3436461..499b537 100644 --- a/solutions/python3/564.py +++ b/solutions/python3/564.py @@ -1,19 +1,37 @@ + class Solution: - def nearestPalindromic(self, S): + def nearestPalindromic(self, S: str) -> str: + """ + 生成可能的回文数候选列表。 + + :param S: 输入字符串,表示数字 + :return: 最接近输入数字且为回文数的字符串形式的数字 + """ + K = len(S) + # 生成一些基本的候选值:比原数大/小1和比原数长度多一位或少一位的数字 candidates = [str(10**k + d) for k in (K-1, K) for d in (-1, 1)] - prefix = S[:(K+1)//2] + + prefix = S[:(K+1)//2] # 获取前半部分作为回文数的前缀 + P = int(prefix) for start in map(str, (P-1, P, P+1)): - candidates.append(start + (start[:-1] if K%2 else start)[::-1]) + candidates.append(start + (start[:-1] if K%2 else start)[::-1]) # 构造完整的回文数候选值 def delta(x): + """ + 计算输入数字与目标数字之间的差值。 + + :param x: 输入字符串形式的数字 + :return: 差值的绝对值 + """ return abs(int(S) - int(x)) - ans = None + ans = None # 初始化最优解 for cand in candidates: - if cand != S and not cand.startswith('00'): + if cand != S and not cand.startswith('00'): # 排除非法或相同情况 if (ans is None or delta(cand) < delta(ans) or delta(cand) == delta(ans) and int(cand) < int(ans)): - ans = cand - return ans \ No newline at end of file + ans = cand # 更新最优解 + + return ans diff --git a/solutions/python3/565.py b/solutions/python3/565.py index 5dfccdf..3eb36dc 100644 --- a/solutions/python3/565.py +++ b/solutions/python3/565.py @@ -1,17 +1,23 @@ + class Solution: def arrayNesting(self, nums): """ - :type nums: List[int] - :rtype: int + :type nums: List[int] # 输入参数,整数列表 + :rtype: int # 返回最大环的长度 """ - dic={} + + dic = {} # 使用字典来记录每个元素访问过的次数 + for i in range(len(nums)): if i in dic: - continue - j=i - dic[j]=1 - while nums[i]!=j: - dic[j]+=1 - i=nums[i] - dic[i]=1 - return max(dic.values()) \ No newline at end of file + continue # 如果当前索引已经处理过,则跳过 + + j = i + dic[j] = 1 # 初始化环的第一个节点的计数为1 + + while nums[i] != j: # 当未回到起始点时,继续循环 + dic[j] += 1 # 增加当前元素的访问次数 + i = nums[i] # 更新索引到下一个元素位置 + dic[i] = 1 # 记录新节点被访问 + + return max(dic.values()) # 返回所有环的最大长度 diff --git a/solutions/python3/566.py b/solutions/python3/566.py index 2760612..2b6b298 100644 --- a/solutions/python3/566.py +++ b/solutions/python3/566.py @@ -1,13 +1,21 @@ + class Solution: - def matrixReshape(self, nums, r, c): + def matrixReshape(self, nums: List[List[int]], r: int, c: int) -> List[List[int]]: """ - :type nums: List[List[int]] - :type r: int - :type c: int - :rtype: List[List[int]] + :param nums: 二维整数列表 + :param r: 期望重塑后的矩阵行数 + :param c: 期望重塑后的矩阵列数 + :return: 如果可以重塑,返回重塑后的矩阵;否则返回原矩阵 """ - nums_ordered=[x for y in nums for x in y] - if r*c==len(nums)*len(nums[0]): - return [nums_ordered[c*i:c*(i+1)] for i in range(r)] - else:return nums - \ No newline at end of file + + # 将原始二维数组展平为一维列表 + nums_ordered = [x for y in nums for x in y] + + # 判断是否可以进行重塑操作 + if r * c == len(nums) * len(nums[0]): + # 可以重塑,按要求分割并重组为新的矩阵 + return [nums_ordered[c * i:c * (i + 1)] for i in range(r)] + else: + # 无法重塑,返回原矩阵 + return nums + \ No newline at end of file diff --git a/solutions/python3/567.py b/solutions/python3/567.py index 740a89c..6c86280 100644 --- a/solutions/python3/567.py +++ b/solutions/python3/567.py @@ -1,18 +1,30 @@ + class Solution: - def checkInclusion(self, s1, s2): - if len(s1) > len(s2): return False - dic = collections.defaultdict(int) + # 检查s1是否为s2的排列组合 + def checkInclusion(self, s1: str, s2: str) -> bool: + if len(s1) > len(s2): + return False # 如果s1长度大于s2,直接返回False + + from collections import defaultdict + dic = defaultdict(int) + + # 预处理窗口内字符频率 for i in range(len(s1)): dic[s1[i]] += 1 if dic[s1[i]] == 0: del dic[s1[i]] dic[s2[i]] -= 1 if dic[s2[i]] == 0: del dic[s2[i]] + + # 滑动窗口检查 i = 0 for j in range(len(s1), len(s2)): - if not dic: return True + if not dic: + return True # 如果字典为空,说明s1是s2的排列组合 + dic[s2[j]] -= 1 if dic[s2[j]] == 0: del dic[s2[j]] dic[s2[i]] += 1 if dic[s2[i]] == 0: del dic[s2[i]] i += 1 - return not dic \ No newline at end of file + + return not dic # 检查最后的字典是否为空 diff --git a/solutions/python3/568.py b/solutions/python3/568.py index ba91f99..3da6cad 100644 --- a/solutions/python3/568.py +++ b/solutions/python3/568.py @@ -1,11 +1,34 @@ + class Solution: def maxVacationDays(self, flights: List[List[int]], days: List[List[int]]) -> int: + """ + 如果航班或假期天数为空,返回0 + :param flights: 航班可用性矩阵 + :param days: 每个城市的假期天数组成的列表 + :return: 最大可利用的假期天数 + """ + if not flights or not days: return 0 - n, k = len(flights), len(days[0]) - dp = [[-1] * (k + 1) for c in range(n)] + + n, k = len(flights), len(days[0]) # 城市数量和假期天数 + dp = [[-1] * (k + 1) for _ in range(n)] # 动态规划数组,初始化为-1 + + # 初始状态:在第一个城市,第0天开始度假 dp[0][0] = 0 + + # 遍历每一天和每个城市 for w in range(1, k + 1): for c in range(n): - dp[c][w] = max([dp[pre][w - 1] + days[c][w - 1] for pre in range(n) if (flights[pre][c] or pre == c) and dp[pre][w - 1] >= 0] or [-1]) - return max(dp[c][-1] for c in range(n)) \ No newline at end of file + + # 计算当前城市当前天数的最大假期天数 + max_days = -1 + for pre in range(n): # 遍历所有可能的前一个城市 + + if (flights[pre][c] or pre == c) and dp[pre][w - 1] >= 0: # 如果可以到达当前城市或者在原地 + max_days = max(max_days, dp[pre][w - 1] + days[c][w - 1]) + + dp[c][w] = max_days + + # 返回所有城市的最大假期天数 + return max(dp[c][-1] for c in range(n)) diff --git a/solutions/python3/57.py b/solutions/python3/57.py index 3a68d10..407bd59 100644 --- a/solutions/python3/57.py +++ b/solutions/python3/57.py @@ -1,13 +1,29 @@ + class Solution: def insert(self, intervals: List[List[int]], newInterval: List[int]) -> List[List[int]]: + """ + 将新的区间插入到已存在的区间列表中,并调整重叠的区间。 + + 中文注释: + - 初始化一个新的空列表 `new` 用于存储合并后的结果 + - 遍历所有现有区间,决定如何处理新插入的区间 + - 如果新区间完全在当前区间的右侧,则直接插入当前区间到 `new` + - 否则,更新新区间以与当前区间重叠的部分 + + 英文注释: + - Initialize an empty list `new` to store the merged intervals. + - Iterate through all existing intervals and decide how to handle the new interval: + - If the new interval is completely to the right of the current interval, directly append the current interval to `new`. + - Otherwise, update the new interval to merge with the overlapping parts. + """ + new, i = [], 0 for i, it in enumerate(intervals): - if newInterval[1] < it[0]: - i -= 1 - break - elif it[1] < newInterval[0]: - new += it, - else: - newInterval[0], newInterval[1] = min(it[0], newInterval[0]), max(it[1], newInterval[1]) - return new + [newInterval] + intervals[i + 1:] - \ No newline at end of file + if newInterval[1] < it[0]: + break # 新区间在当前区间的右侧,停止遍历 + elif it[1] < newInterval[0]: + new += it, # 当前区间完全在新区间的左侧,直接添加到结果中 + else: + newInterval = [min(it[0], newInterval[0]), max(it[1], newInterval[1])] # 更新新区间以合并重叠部分 + + return new + [newInterval] + intervals[i + 1:] # 返回合并后的区间列表 diff --git a/solutions/python3/572.py b/solutions/python3/572.py index 5a882ed..7e181ce 100644 --- a/solutions/python3/572.py +++ b/solutions/python3/572.py @@ -1,11 +1,25 @@ + class Solution: + # 判断t是否为s的子树 + def isSubtree(self, s, t): """ :type s: TreeNode :type t: TreeNode :rtype: bool + + 通过遍历生成字符串的方式判断两棵树的内容是否匹配,进而确定t是否是s的子树。 + + 思路:对每个节点进行遍历,使用特殊字符标记节点值,并递归处理左右子树。在最终比较时,直接检查两个字符串是否包含关系。 """ + def traverse(node): - if not node: return "^" - return "$"+str(node.val)+"?"+traverse(node.left)+"@"+traverse(node.right) - return traverse(t) in traverse(s) \ No newline at end of file + # 递归生成表示当前树结构的字符串 + if not node: + return "^" # 空节点用"^"表示 + return "$"+str(node.val)+"?"+traverse(node.left)+"@"+traverse(node.right) # 根据节点值及左右子树构造唯一标识 + + s_str = traverse(s) # 获取s的字符串表示 + t_str = traverse(t) # 获取t的字符串表示 + + return t_str in s_str # 检查t是否为s的子串 diff --git a/solutions/python3/573.py b/solutions/python3/573.py index 36a2716..85de59a 100644 --- a/solutions/python3/573.py +++ b/solutions/python3/573.py @@ -1,4 +1,13 @@ + class Solution: + # 定义一个方法来计算将n个点移动到目标位置t和s所需的最小距离 + def minDistance(self, height, width, t, s, n): + # 计算当前布局下所有点到目标位置t的曼哈顿距离总和 sm = 2 * sum(abs(x - t[0]) + abs(y - t[1]) for x, y in n) - return min(sm - abs(x - t[0]) - abs(y - t[1]) + abs(x - s[0]) + abs(y - s[1]) for x, y in n) \ No newline at end of file + + # 遍历每个点,找到将某个点移动到s位置时,最小化整体变化量的情况 + return min( + sm - abs(x - t[0]) - abs(y - t[1]) + abs(x - s[0]) + abs(y - s[1]) + for x, y in n + ) diff --git a/solutions/python3/575.py b/solutions/python3/575.py index fe82b50..9798a38 100644 --- a/solutions/python3/575.py +++ b/solutions/python3/575.py @@ -1,7 +1,12 @@ + class Solution: def distributeCandies(self, candies): """ :type candies: List[int] :rtype: int """ - return len(set(candies)) if len(set(candies))<=len(candies)//2 else len(candies)//2 \ No newline at end of file + # 计算唯一糖果种类数 + unique_candies = len(set(candies)) + + # 如果唯一糖果种类数小于等于总糖果数量的一半,则返回唯一糖果种类数,否则返回总糖果数量一半 + return unique_candies if unique_candies <= len(candies) // 2 else len(candies) // 2 diff --git a/solutions/python3/576.py b/solutions/python3/576.py index b66d805..937c64e 100644 --- a/solutions/python3/576.py +++ b/solutions/python3/576.py @@ -1,8 +1,33 @@ + +from collections import defaultdict + class Solution: - def __init__(self): self.dic = collections.defaultdict(int) - def findPaths(self, m, n, N, i, j): - if N >= 0 and (i < 0 or j < 0 or i >= m or j >= n): return 1 - elif N < 0: return 0 - elif (i, j, N) not in self.dic: - for p in ((1, 0), (-1, 0), (0, 1), (0, -1)): self.dic[(i, j, N)] += self.findPaths(m, n, N - 1, i + p[0], j + p[1]) - return self.dic[(i, j, N)] % (10 ** 9 + 7) \ No newline at end of file + def __init__(self): + """初始化字典用于存储中间结果""" + self.dic = defaultdict(int) + + def findPaths(self, m: int, n: int, N: int, i: int, j: int) -> int: + """ + :param m: 行数 + :param n: 列数 + :param N: 步数 + :param i: 起始行位置 + :param j: 起始列位置 + :return: 在给定步数内到达边界次数(模10^9+7) + """ + + # 检查是否超出边界或步数为负 + if N >= 0 and (i < 0 or j < 0 or i >= m or j >= n): + return 1 + + # 如果步数小于0,返回0 + elif N < 0: + return 0 + + # 如果当前状态已计算过,则直接返回结果 + elif (i, j, N) not in self.dic: + for p in ((1, 0), (-1, 0), (0, 1), (0, -1)): + self.dic[(i, j, N)] += self.findPaths(m, n, N - 1, i + p[0], j + p[1]) + + # 返回结果取模 + return self.dic[(i, j, N)] % (10 ** 9 + 7) diff --git a/solutions/python3/58.py b/solutions/python3/58.py index 0cec937..ff6b8c2 100644 --- a/solutions/python3/58.py +++ b/solutions/python3/58.py @@ -1,21 +1,31 @@ + class Solution: - def lengthOfLastWord(self, s): + def lengthOfLastWord(self, s: str) -> int: """ - :type s: str - :rtype: int + :param s: 输入字符串 + :return: 最后一个单词的长度 """ - if len(s)==0: + if len(s) == 0: + # 如果输入为空字符串,返回0 return 0 - count=0 - prev_count=0 + + count = 0 + prev_count = 0 + for letter in s: - if count>0: - prev_count=count - if letter==" ": - count=0 + # 如果当前计数大于0,记录前一个计数值 + if count > 0: + prev_count = count + + # 遇到空格时重置计数并跳过该循环迭代 + if letter == " ": + count = 0 continue - count+=1 - if count>0: + + count += 1 + + # 如果最后一个单词长度大于0,返回其长度;否则返回前一个计数值 + if count > 0: return count else: - return prev_count \ No newline at end of file + return prev_count diff --git a/solutions/python3/581.py b/solutions/python3/581.py index 43b590b..f86ffb3 100644 --- a/solutions/python3/581.py +++ b/solutions/python3/581.py @@ -1,10 +1,21 @@ + class Solution: + # 寻找数组中未排序的子数组长度 + def findUnsortedSubarray(self, nums: List[int]) -> int: - arr = sorted(nums) + arr = sorted(nums) # 对原数组进行排序 + i = 0 for i in range(len(arr)): - if arr[i] != nums[i]: - for j in range(len(arr) - 1, -1, -1): - if arr[j] != nums[j]: - return j - i + 1 - return 0 \ No newline at end of file + if arr[i] != nums[i]: # 找到第一个不匹配的位置 + break + + # 从后向前找到最后一个不匹配的位置 + j = len(arr) - 1 + while j >= 0: + if arr[j] != nums[j]: + break + j -= 1 + + # 计算未排序子数组的长度 + return j - i + 1 if i < j else 0 diff --git a/solutions/python3/582.py b/solutions/python3/582.py index 1386fbb..7d09141 100644 --- a/solutions/python3/582.py +++ b/solutions/python3/582.py @@ -1,11 +1,23 @@ + class Solution: + # 定义一个名为Solution的类,用于处理进程杀掉逻辑 + def killProcess(self, pid, ppid, kill): + # 初始化索引字典和结果列表 indexes, res = collections.defaultdict(list), [kill] + + # 遍历ppid数组,填充索引字典 for i, p in enumerate(ppid): indexes[p].append(i) + + # 使用栈进行深度优先搜索遍历 stack = [kill] while stack: - for i in indexes[stack.pop()]: + # 从栈中弹出一个元素 + current_pid = stack.pop() + # 将当前节点的所有子节点添加到结果列表和栈中 + for i in indexes[current_pid]: res.append(pid[i]) stack.append(pid[i]) - return res \ No newline at end of file + + return res # 返回最终的结果列表 diff --git a/solutions/python3/583.py b/solutions/python3/583.py index 49b22e8..a619303 100644 --- a/solutions/python3/583.py +++ b/solutions/python3/583.py @@ -1,13 +1,32 @@ + class Solution: - def minDistance(self, w1, w2): + # Python solution to find minimum distance between two strings + + def minDistance(self, w1: str, w2: str) -> int: + """ + 计算两个字符串的最小编辑距离 + + :param w1: 第一个字符串 + :param w2: 第二个字符串 + :return: 最小编辑距离 + """ + m, n = len(w1), len(w2) + + # 创建动态规划表 dp = [[0] * (n + 1) for _ in range(m + 1)] + + # 初始化边界条件 for i in range(m + 1): for j in range(n + 1): if i == 0 or j == 0: dp[i][j] = i + j - elif w1[i - 1] == w2[j - 1]: + elif w1[i - 1] == w2[j - 1]: + # 如果字符相同,不需要编辑操作 dp[i][j] = dp[i - 1][j - 1] - else: + else: + # 计算插入、删除或替换的最小编辑距离 dp[i][j] = min(dp[i][j - 1] + 1, dp[i - 1][j] + 1) - return dp[-1][-1] \ No newline at end of file + + # 返回最终结果 + return dp[-1][-1] diff --git a/solutions/python3/587.py b/solutions/python3/587.py index 3d5c95b..68965f1 100644 --- a/solutions/python3/587.py +++ b/solutions/python3/587.py @@ -1,49 +1,41 @@ -# http://www.algorithmist.com/index.php/Monotone_Chain_Convex_Hull.py - class Solution(object): def outerTrees(self, points): - """Computes the convex hull of a set of 2D points. - - Input: an iterable sequence of (x, y) pairs representing the points. - Output: a list of vertices of the convex hull in counter-clockwise order, - starting from the vertex with the lexicographically smallest coordinates. - Implements Andrew's monotone chain algorithm. O(n log n) complexity. + """ + 计算二维点集的凸包。 + + 输入:一个表示点对的可迭代序列,形式为 (x, y)。 + 输出:按照逆时针顺序列出凸包的顶点,从最左边(或y坐标最小)的顶点开始。 + 实现 Andrew 的单调链算法。复杂度为 O(n log n)。 """ - # Sort the points lexicographically (tuples are compared lexicographically). - # Remove duplicates to detect the case we have just one unique point. - # points = sorted(set(points)) + # 按字典序排序点对,并去除重复项以处理仅有一个独特点的情况。 points = sorted(points, key=lambda p: (p.x, p.y)) - # Boring case: no points or a single point, possibly repeated multiple times. + # 边缘情况:无点或单个点(可能多次出现)。 if len(points) <= 1: return points - # 2D cross product of OA and OB vectors, i.e. z-component of their 3D cross product. - # Returns a positive value, if OAB makes a counter-clockwise turn, - # negative for clockwise turn, and zero if the points are collinear. + # 计算 OA 和 OB 向量的叉积,即 OAB 在三维空间中的向量积的 z 分量。 + # 返回正值表示逆时针转向,负值表示顺时针转向,零表示共线。 def cross(o, a, b): - # return (a[0] - o[0]) * (b[1] - o[1]) - (a[1] - o[1]) * (b[0] - o[0]) return (a.x - o.x) * (b.y - o.y) - (a.y - o.y) * (b.x - o.x) - # Build lower hull + # 构建下凸包 lower = [] for p in points: while len(lower) >= 2 and cross(lower[-2], lower[-1], p) < 0: lower.pop() lower.append(p) - # Build upper hull + # 构建上凸包 upper = [] for p in reversed(points): while len(upper) >= 2 and cross(upper[-2], upper[-1], p) < 0: upper.pop() upper.append(p) - # Concatenation of the lower and upper hulls gives the convex hull. - # Last point of each list is omitted because it is repeated at the - # beginning of the other list. - # return lower[:-1] + upper[:-1] - return list(set(lower[:-1] + upper[:-1])) \ No newline at end of file + # 下凸包和上凸包的组合构成完整的凸包。 + # 每个列表的最后一项重复,因此需要去除。 + return list(set(lower[:-1] + upper[:-1])) diff --git a/solutions/python3/588.py b/solutions/python3/588.py index b6ec4b4..935d62b 100644 --- a/solutions/python3/588.py +++ b/solutions/python3/588.py @@ -1,16 +1,47 @@ + class File: + """ + File class represents a file in the file system. - def __init__(self, name): + Attributes: + name (str): The name of the file. + files (dict): A dictionary to store sub-files under this file. + content (str): Content of the file. + """ + + def __init__(self, name: str): + """ + Initialize a File object. + + Args: + name (str): The name of the file. + """ self.name = name self.files = {} self.content = '' + class FileSystem: + """ + Represents a file system with operations to manipulate files and directories. + """ def __init__(self): + """ + Initialize a FileSystem object, starting from root directory '/'. + """ self.root = File('/') - def move(self, path): + def move(self, path: str) -> File: + """ + Navigate through the paths and return the current file. + + Args: + path (str): The path to navigate. + + Returns: + File: The current file at the given path. + """ cur = self.root if path[1:]: for dr in path[1:].split('/'): @@ -18,26 +49,48 @@ def move(self, path): cur.files[dr] = File(dr) cur = cur.files[dr] return cur - + def ls(self, path: str) -> List[str]: + """ + List the names of files and directories under the given path. + + Args: + path (str): The path to list contents from. + + Returns: + List[str]: A list containing file/directory names. + """ cur = self.move(path) return [cur.name] if cur.content else sorted(cur.files.keys()) def mkdir(self, path: str) -> None: + """ + Create a directory at the given path. + + Args: + path (str): The path to create the directory. + """ self.move(path) def addContentToFile(self, filePath: str, content: str) -> None: + """ + Add content to a file located at the given path. + + Args: + filePath (str): The path to the file. + content (str): Content to be added to the file. + """ cur = self.move(filePath) cur.content += content def readContentFromFile(self, filePath: str) -> str: - return self.move(filePath).content - + """ + Read and return the content of a file located at the given path. + Args: + filePath (str): The path to the file. -# Your FileSystem object will be instantiated and called as such: -# obj = FileSystem() -# param_1 = obj.ls(path) -# obj.mkdir(path) -# obj.addContentToFile(filePath,content) -# param_4 = obj.readContentFromFile(filePath) \ No newline at end of file + Returns: + str: The content of the file. + """ + return self.move(filePath).content diff --git a/solutions/python3/59.py b/solutions/python3/59.py index 15d6d53..4c63203 100644 --- a/solutions/python3/59.py +++ b/solutions/python3/59.py @@ -1,18 +1,39 @@ + class Solution: - def generateMatrix(self, n): + def generateMatrix(self, n: int) -> List[List[int]]: """ :type n: int :rtype: List[List[int]] + + 生成一个 n x n 的矩阵,按照螺旋顺序填充数字1到n*n。 """ - def dirToIndex(x, y, d): - if d == "r": return (x, y + 1, d) if y + 1 < n and matrix[x][y + 1] == 0 else (x + 1, y, "d") - elif d == "d": return (x + 1, y, d) if x + 1 < n and matrix[x + 1][y] == 0 else (x, y - 1, "l") - elif d == "l": return (x, y - 1, d) if y > 0 and matrix[x][y - 1] == 0 else (x - 1, y, "u") - else: return (x - 1, y, d) if x > 0 and matrix[x - 1][y] == 0 else (x, y +1, "r") - matrix = [[0 for i in range(1, n + 1)] for j in range(n)] + + def dirToIndex(x: int, y: int, d: str) -> Tuple[int, int, str]: + """ + 根据当前方向d计算下一个位置和新方向 + :param x: 当前行索引 + :param y: 当前列索引 + :param d: 当前方向,r(右), d(下), l(左), u(上) + :return: (new_x, new_y, new_direction) + """ + if d == "r": + return (x, y + 1, d) if y + 1 < n and matrix[x][y + 1] == 0 else (x + 1, y, "d") + elif d == "d": + return (x + 1, y, d) if x + 1 < n and matrix[x + 1][y] == 0 else (x, y - 1, "l") + elif d == "l": + return (x, y - 1, d) if y > 0 and matrix[x][y - 1] == 0 else (x - 1, y, "u") + else: + return (x - 1, y, d) if x > 0 and matrix[x - 1][y] == 0 else (x, y + 1, "r") + + # 初始化矩阵 + matrix = [[0 for i in range(n)] for j in range(n)] + num, dir, i, j = 1, "r", 0, 0 + + # 按照螺旋顺序填充数字 while 0 <= i < n and 0 <= j < n and matrix[i][j] == 0: matrix[i][j] = num num += 1 i, j, dir = dirToIndex(i, j, dir) - return matrix \ No newline at end of file + + return matrix diff --git a/solutions/python3/591.py b/solutions/python3/591.py index c4f2650..41b403a 100644 --- a/solutions/python3/591.py +++ b/solutions/python3/591.py @@ -1,47 +1,88 @@ + class Solution: - def isValid(self, S): - CDATA_BEGIN = '![CDATA[' - CDATA_END = ']]>' + # CDATA区开始和结束标记 + CDATA_BEGIN = '![CDATA[' + CDATA_END = ']]>' + + def isValid(self, S: str) -> bool: + """ + 判断给定的字符串S是否为有效的HTML标签格式。 + - CDATA_BEGIN 和 CDATA_END 用于标记CDATA区段 + + :param S: 输入的字符串 + :return: 如果输入满足HTML标签格式返回True,否则返回False + """ + + def collect_tag(i: int) -> str: + """ + 收集从索引i开始的标签内容。 + - 遇到 '>' 结束 + - 若未遇到 '>', 返回None + + :param i: 开始收集标签的位置 + :return: 标签内容或None + """ - def collect_tag(i): for j in range(i, len(S)): if S[j] == '>': break else: return None return S[i+1:j] - def valid_tag(tag): + def valid_tag(tag: str) -> bool: + """ + 判断给定的tag是否有效。 + - tag长度在1到9之间且仅包含大写字母 + + :param tag: 要验证的标签字符串 + :return: 如果有效返回True,否则False + """ + return 1 <= len(tag) <= 9 and all('A' <= c <= 'Z' for c in tag) - if not S or S[0] != '<': return False + # 检查输入格式 + if not S or S[0] != '<': + return False + + # 获取初始标签 tag = collect_tag(0) if (tag is None or not S.startswith('<{}>'.format(tag)) or not S.endswith(''.format(tag)) or not valid_tag(tag)): return False + + # 去除已验证的起始和结束标签 S = S[len(tag) + 2: -len(tag) - 3] i = 0 stack = [] + while i < len(S): if S[i] == '<': tag = collect_tag(i) if tag is None: return False + + # 检查CDATA区段 if tag.startswith(CDATA_BEGIN): while i < len(S) and S[i:i+3] != CDATA_END: i += 1 if not S[i:i+3] == CDATA_END: return False i += 2 + + # 检查结束标签 elif tag.startswith('/'): tag = tag[1:] if not valid_tag(tag) or not stack or stack.pop() != tag: return False + + # 添加新的开始标签到栈中 else: if not valid_tag(tag): return False stack.append(tag) i += 1 - return not stack \ No newline at end of file + # 栈为空表示所有标签都正确闭合 + return not stack diff --git a/solutions/python3/592.py b/solutions/python3/592.py index 6fab166..42234a8 100644 --- a/solutions/python3/592.py +++ b/solutions/python3/592.py @@ -1,16 +1,21 @@ + class Solution: - def fractionAddition(self, e): - + # 计算分子和分母 + def fractionAddition(self, e: str) -> str: + + # 解析字符串中的一个分数片段 def calc(i): l, r = i - 1, i + 1 while l > 0 and e[l - 1].isdigit(): l -= 1 while r < len(e) - 1 and e[r + 1].isdigit(): r += 1 + # 处理负号情况 l = -int(e[l:i]) if l > 0 and e[l - 1] == "-" else int(e[l:i]) r = int(e[i + 1:r + 1]) return l, r + # 计算最小公倍数 (LCM) def lcm(x, y): lcm = max(x, y) while True: @@ -18,6 +23,7 @@ def lcm(x, y): return lcm lcm += 1 + # 计算最大公约数 (GCD) def gcd(x, y): for i in range(min(x, y), 0, -1): if not x % i and not y % i: @@ -29,6 +35,7 @@ def gcd(x, y): if n: n2, d2 = calc(i) newD = lcm(d, d2) + # 计算新的分子和分母 newN = n * (newD // d) + n2 * (newD // d2) if newN: r = gcd(abs(newD), abs(newN)) @@ -36,5 +43,6 @@ def gcd(x, y): else: n, d = 0, 1 else: + # 处理第一个分数 n, d = calc(i) - return str(n) + "/" + str(d) \ No newline at end of file + return str(n) + "/" + str(d) diff --git a/solutions/python3/593.py b/solutions/python3/593.py index db0b264..b00699b 100644 --- a/solutions/python3/593.py +++ b/solutions/python3/593.py @@ -1,14 +1,33 @@ + class Solution: - def validSquare(self, p1, p2, p3, p4): + def validSquare(self, p1: list[int], p2: list[int], p3: list[int], p4: list[int]) -> bool: """ - :type p1: List[int] - :type p2: List[int] - :type p3: List[int] - :type p4: List[int] - :rtype: bool + 判断四个点是否能构成一个非退化的正方形。 + + :param p1: 第一个点的坐标 + :param p2: 第二个点的坐标 + :param p3: 第三个点的坐标 + :param p4: 第四个点的坐标 + :return: 如果可以构成非退化的正方形返回True,否则返回False + + 1. 计算每对点之间的距离平方。 + 2. 集合存储这些距离平方。 + 3. 判断集合长度是否为2且包含0的情况不存在。 """ from itertools import combinations as cb - def D(C): - return (C[0][0] - C[1][0]) ** 2 + (C[0][1] - C[1][1]) ** 2 - S = set(map(D, cb((p1, p2, p3, p4), 2))) - return len(S) == 2 and 0 not in S \ No newline at end of file + + def distance_squared(coord1, coord2): + """ + 计算两个坐标之间的距离的平方。 + + :param coord1: 第一个坐标的元组形式 (x, y) + :param coord2: 第二个坐标的元组形式 (x, y) + :return: 两点间距离的平方 + """ + return (coord1[0] - coord2[0]) ** 2 + (coord1[1] - coord2[1]) ** 2 + + # 计算所有点对的距离平方并去重 + distances = set(map(lambda pair: distance_squared(pair), cb([p1, p2, p3, p4], 2))) + + # 检查条件:必须有两个不同的距离且没有长度为0的情况(三点共线) + return len(distances) == 2 and 0 not in distances diff --git a/solutions/python3/598.py b/solutions/python3/598.py index e1453ad..e920fb2 100644 --- a/solutions/python3/598.py +++ b/solutions/python3/598.py @@ -1,11 +1,18 @@ + class Solution: - def maxCount(self, m, n, ops): + def maxCount(self, m: int, n: int, ops: list[list[int]]) -> int: """ - :type m: int - :type n: int - :type ops: List[List[int]] - :rtype: int + :param m: 整数m,表示矩阵的行数 + :param n: 整数n,表示矩阵的列数 + :param ops: 列表,包含操作列表,每个操作为[行数, 列数] + :return: 返回值是最大可能的小矩形个数 """ - if ops==[]: - return m*n - return min(op[0] for op in ops)* min(op[1] for op in ops) \ No newline at end of file + if not ops: + # 如果没有操作,返回整个矩阵的大小 + return m * n + + min_row = min(op[0] for op in ops) # 操作中的最小行数 + min_col = min(op[1] for op in ops) # 操作中的最小列数 + + # 最大可能的小矩形个数为:最小行数 * 最小列数 + return min_row * min_col diff --git a/solutions/python3/599.py b/solutions/python3/599.py index d0a3e97..6ed5323 100644 --- a/solutions/python3/599.py +++ b/solutions/python3/599.py @@ -1,13 +1,21 @@ + class Solution: - def findRestaurant(self, list1, list2): + def findRestaurant(self, list1: List[str], list2: List[str]) -> List[str]: """ :type list1: List[str] + :param list1: 第一个餐厅列表 :type list2: List[str] + :param list2: 第二个餐厅列表 :rtype: List[str] + :return: 同时出现在两个列表中且索引和最小的餐厅名称列表 """ - dic={} + + # 创建字典存储公共餐厅及其总索引值 + dic = {} for item1 in list1: - for item2 in list2: - if item1==item2: - dic[item1]=list1.index(item1)+list2.index(item2) - return [k for k in dic if dic[k]==min(dic.values())] \ No newline at end of file + if item1 in list2: # 直接检查是否在第二个列表中,减少不必要的比较 + dic[item1] = list1.index(item1) + list2.index(item1) + + # 找到最小索引和对应的餐厅名称 + min_index_sum = min(dic.values()) + return [k for k, v in dic.items() if v == min_index_sum] diff --git a/solutions/python3/6.py b/solutions/python3/6.py index 01b5f64..fee4e69 100644 --- a/solutions/python3/6.py +++ b/solutions/python3/6.py @@ -1,9 +1,26 @@ + class Solution: - def convert(self, s, numRows): - if numRows == 1 or numRows >= len(s): return s + # 定义一个转换函数,将字符串s按照指定行数numRows进行转换 + def convert(self, s: str, numRows: int) -> str: + + if numRows == 1 or numRows >= len(s): + # 如果行数为1或大于等于字符串长度,则直接返回原字符串 + return s + row, direction, res = 0, -1, [""] * numRows + # 初始化行索引row,方向direction和结果列表res + for char in s: + # 遍历字符串中的每个字符char res[row] += char - if row == 0 or row == numRows - 1: direction *= -1 + # 将当前字符添加到对应行的result列表中 + + if row == 0 or row == numRows - 1: + direction *= -1 + # 当到达第一行或最后一行时,改变方向(向下变向上,向上变向下) + row += direction - return "".join(res) \ No newline at end of file + # 更新行索引row + + return "".join(res) + # 将result列表中的所有字符串连接成一个完整的字符串并返回 diff --git a/solutions/python3/60.py b/solutions/python3/60.py index 10b3ab0..ba2983f 100644 --- a/solutions/python3/60.py +++ b/solutions/python3/60.py @@ -1,6 +1,15 @@ + class Solution: - def getPermutation(self, n, k): + # 定义一个类,用于生成全排列 + + def getPermutation(self, n: int, k: int) -> str: + # 使用itertools.permutations生成1到n的数字的所有全排列 p = itertools.permutations(range(1, n + 1)) - for i in range(k): - res = next(p) - return ''.join([str(i) for i in res]) \ No newline at end of file + + # 循环k次获取第k个排列 + for _ in range(k - 1): + next(p) + + # 获取并返回第k个排列,转换为字符串形式 + res = next(p) + return ''.join([str(i) for i in res]) diff --git a/solutions/python3/600.py b/solutions/python3/600.py index 8ae4ee6..371cba8 100644 --- a/solutions/python3/600.py +++ b/solutions/python3/600.py @@ -1,10 +1,27 @@ + class Solution: def findIntegers(self, num): + """ + :param num: 输入的整数 (integer) + :return: 满足条件的整数个数 (满足条件的整数数量) + + 该函数用于计算给定二进制表示中,不包含连续两个 '1' 的子序列个数。 + """ + + # 将十进制转换为二进制字符串,并去除前缀 '0b' num, sub = bin(num)[2:], 0 + # 初始化两个数组用于存放以 '0' 和 '1' 开头的合法序列数量 zero, one = [1] * len(num), [1] * len(num) + for i in range(1, len(num)): + # 根据前一个状态更新当前位置的状态数 zero[i], one[i] = zero[i - 1] + one[i - 1], zero[i - 1] + for i in range(1, len(num)): + # 如果找到连续两个 '1',停止循环 if num[i] == num[i - 1] == "1": break - if num[i] == num[i - 1] == "0": sub += one[-1 - i] - return zero[-1] + one[-1] - sub \ No newline at end of file + # 计算不包含连续零的子序列个数 + if num[i] == num[i - 1] == "0": + sub += one[-1 - i] + + return zero[-1] + one[-1] - sub diff --git a/solutions/python3/604.py b/solutions/python3/604.py index fa365d1..6c78446 100644 --- a/solutions/python3/604.py +++ b/solutions/python3/604.py @@ -1,23 +1,29 @@ + class StringIterator: - def findCount(self): - j = self.ind + 1 - while j < self.n and self.s[j].isnumeric(): j += 1 - self.count = int(self.s[self.ind + 1:j]) - self.new = j - + # 构造函数,初始化字符串和索引相关变量,并调用findCount方法解析第一个字符及其计数 def __init__(self, compressedString): self.s, self.n = compressedString, len(compressedString) self.ind = self.count = self.new = 0 self.findCount() + # 解析字符串中的下一个数字计数值,更新ind和new指针位置 + def findCount(self): + j = self.ind + 1 + while j < self.n and self.s[j].isnumeric(): j += 1 + self.count = int(self.s[self.ind + 1:j]) # 计算字符计数 + self.new = j # 更新新指针位置 + + # 返回下一个字符,如果count为0且没有更多字符,则返回空格 def next(self): if not self.count: if self.new >= self.n: return " " elif self.new < self.n: - self.ind = self.new - self.findCount() - self.count -= 1 - return self.s[self.ind] + self.ind = self.new # 将ind更新到new指针位置 + self.findCount() # 解析下一个数字计数值 + + self.count -= 1 # 减少count值,模拟字符被消费掉 + return self.s[self.ind] # 返回当前索引指向的字符 + # 判断是否有更多字符可返回 def hasNext(self): - return self.count > 0 or self.new < self.n - 1 \ No newline at end of file + return self.count > 0 or self.new < self.n - 1 diff --git a/solutions/python3/605.py b/solutions/python3/605.py index 23cdd9e..33f56ea 100644 --- a/solutions/python3/605.py +++ b/solutions/python3/605.py @@ -1,27 +1,36 @@ + class Solution: - def canPlaceFlowers(self, flowerbed, n): + def canPlaceFlowers(self, flowerbed: list[int], n: int) -> bool: """ - :type flowerbed: List[int] - :type n: int - :rtype: bool + :param flowerbed: 一个整数列表,表示花坛的状态。1 表示位置已有花朵,0 表示可以种植花朵。 + :param n: 需要尝试在花坛中种植的花朵数量 + :return: 如果可以成功种植指定数量的花朵返回 True, 否则返回 False. """ - num=n - if len(flowerbed)<=1: - if (num==1 and flowerbed==[0]) or (num==0): + # 剩余需要种植的花朵数 + num = n + + # 检查花坛长度小于等于1的情况 + if len(flowerbed) <= 1: + if (num == 1 and flowerbed == [0]) or (num == 0): return True else: return False - if flowerbed[0]==0 and flowerbed[1]==0: - flowerbed[0]=1 - num-=1 - if flowerbed[-1]==0 and flowerbed[-2]==0: - flowerbed[-1]=1 - num-=1 - for i in range(1,len(flowerbed)-2): - if flowerbed[i]!=1 and flowerbed[i+1]!=1 and flowerbed[i-1]!=1: - flowerbed[i]=1 - num-=1 - if num<=0: - return True - return False - \ No newline at end of file + + # 处理边界情况:在起始位置种植花朵 + if flowerbed[0] == 0 and flowerbed[1] == 0: + flowerbed[0] = 1 + num -= 1 + + # 处理边界情况:在末尾位置种植花朵 + if flowerbed[-1] == 0 and flowerbed[-2] == 0: + flowerbed[-1] = 1 + num -= 1 + + # 遍历花坛中间部分,尝试种植花朵 + for i in range(1, len(flowerbed) - 1): + if flowerbed[i] != 1 and flowerbed[i + 1] != 1 and flowerbed[i - 1] != 1: + flowerbed[i] = 1 + num -= 1 + + # 检查是否成功种植了所有需要的花朵 + return num <= 0 diff --git a/solutions/python3/606.py b/solutions/python3/606.py index 7ec3320..eafa436 100644 --- a/solutions/python3/606.py +++ b/solutions/python3/606.py @@ -1,12 +1,29 @@ -class Solution: + +class Solution: def tree2str(self, t): """ :type t: TreeNode :rtype: str + + 英文注释:This function converts a binary tree into a string representation. + + 中文注释:此函数将二叉树转换为字符串表示形式。 """ - if not t: return "" - parent="%s" %t.val - left, right= "", "" - if t.left or t.right: left= "(%s)" % self.tree2str(t.left) - if t.right: right= "(%s)" % self.tree2str(t.right) - return parent+left+right \ No newline at end of file + if not t: + return "" + + # 树节点的值 + parent = str(t.val) + + # 左子树部分 + left = "" + if t.left or t.right: + left = f"({self.tree2str(t.left)})" + + # 右子树部分 + right = "" + if t.right: + right = f"(.{self.tree2str(t.right)})" + + # 返回完整的字符串表示形式 + return parent + left + right diff --git a/solutions/python3/609.py b/solutions/python3/609.py index dd642b6..e4f9d1a 100644 --- a/solutions/python3/609.py +++ b/solutions/python3/609.py @@ -1,9 +1,20 @@ + class Solution: + # 定义一个用于查找重复文件的类 + def findDuplicate(self, paths): - dic = collections.defaultdict(list) + """ + :param paths: 列表,包含多个路径字符串,每个路径字符串以空格分隔,形式为 "根目录 文件名(内容)" + :return: 返回所有重复文件的列表 + """ + + from collections import defaultdict # 引入字典默认值处理模块 + + dic = defaultdict(list) # 初始化一个默认值为list的字典用于存储相同内容的文件路径 for path in paths: - root, *f = path.split(" ") - for file in f: - txt, content = file.split("(") - dic[content] += root + "/" + txt, - return [dic[key] for key in dic if len(dic[key]) > 1] \ No newline at end of file + root, *files = path.split(" ") # 分割路径字符串,root是根目录,files是一系列文件名(内容) + for file in files: + name, content = file.split("(") # 拆分文件名和内容 + dic[content[:-1]].append(root + "/" + name) # 去除内容尾部的 ')' 并添加路径到字典中 + + return [dic[key] for key in dic if len(dic[key]) > 1] # 返回所有重复文件列表 diff --git a/solutions/python3/61.py b/solutions/python3/61.py index c16a944..8eedc98 100644 --- a/solutions/python3/61.py +++ b/solutions/python3/61.py @@ -1,17 +1,29 @@ + class Solution: - def rotateRight(self, head, k): + # 定义一个方法用于向右旋转链表,k是旋转次数 + def rotateRight(self, head: ListNode, k: int) -> ListNode: + # 初始化数组和计数器,数组用于存储节点指针,计数器用于统计链表长度 arr, count = [head], 0 root = last = head + + # 遍历链表,更新last(最后一个节点)并计算链表的总长度 while last and last.next and count < k: - last, count = last.next, count+1 + last, count = last.next, count + 1 arr.append(last) + + # 如果k不等于count,则需要调整k值为实际有效的旋转次数 if k != count: - k = k % (count+1) - last = arr[k] + k = k % (count + 1) # 计算实际需要的旋转次数 + last = arr[k] # 更新last为新的最后一个节点 + + # 如果没有有效节点或无需旋转,直接返回原头结点 if k == 0 or not last: return head + + # 找到新的尾节点和原来的倒数第二个节点,并完成链表的重新连接 curr = root while last.next: last, curr = last.next, curr.next - last.next, curr.next, start = root, None, curr.next - return start \ No newline at end of file + last.next, curr.next, start = root, None, curr.next # 新的头结点 + + return start # 返回旋转后的链表新头结点 diff --git a/solutions/python3/611.py b/solutions/python3/611.py index ff35439..8ac4c2f 100644 --- a/solutions/python3/611.py +++ b/solutions/python3/611.py @@ -1,9 +1,23 @@ + class Solution: + # 定义一个求三角形个数的类 + def triangleNumber(self, nums): - res, n = 0, len(nums); nums.sort() - for i in range(n - 1, 1, -1): - j, k = i - 1, 0 - while k < j: - if nums[j] + nums[k] > nums[i]: res, j = res + j - k, j - 1 - else: k += 1 - return res \ No newline at end of file + """ + :param nums: List[int] -- 输入的一组整数数组 + :return: int -- 满足条件的三角形个数 + """ + res, n = 0, len(nums) # 初始化结果和数组长度 + nums.sort() # 对输入数组进行排序,便于后续操作 + + for i in range(n - 1, 1, -1): # 从右向左遍历,减少不必要的计算 + j, k = i - 1, 0 # 定义双指针j和k,初始值分别为i-1和0 + + while k < j: # 当j > k时继续循环 + if nums[j] + nums[k] > nums[i]: # 判断是否能构成三角形 + res += (j - k) # 满足条件则计算个数并累加到结果中 + j -= 1 # 更新指针位置 + else: + k += 1 # 移动左指针,寻找可能的组合 + + return res # 返回最终结果 diff --git a/solutions/python3/616.py b/solutions/python3/616.py index 587c936..a30044f 100644 --- a/solutions/python3/616.py +++ b/solutions/python3/616.py @@ -1,6 +1,11 @@ + class Solution: - def addBoldTag(self, S, words): + # 定义一个用于将字符串S中包含指定单词列表words中的单词添加粗体标签的方法 + + def addBoldTag(self, S: str, words: list[str]) -> str: trie, n, mask, res = {}, len(S), set(), "" + + # 构建前缀树(Trie) for w in words: cur = trie for c in w: @@ -8,6 +13,8 @@ def addBoldTag(self, S, words): cur[c] = {} cur = cur[c] cur["#"] = cur.get("#", set()) | {w} + + # 遍历字符串S并构建mask集合,记录需要加粗的部分的索引范围 for i in range(n): cur, j = trie, i while j < n and S[j] in cur: @@ -15,10 +22,13 @@ def addBoldTag(self, S, words): if "#" in cur: mask |= {ind for ind in range(i, j + 1)} j += 1 + + # 根据mask集合生成最终的加粗字符串res for i in range(n): if i in mask and (not i or i - 1 not in mask): res += "" res += S[i] if i in mask and (i == n - 1 or i + 1 not in mask): res += "" - return res \ No newline at end of file + + return res diff --git a/solutions/python3/617.py b/solutions/python3/617.py index 280bd37..71855c3 100644 --- a/solutions/python3/617.py +++ b/solutions/python3/617.py @@ -1,11 +1,23 @@ + class Solution: - def mergeTrees(self, t1, t2): + def mergeTrees(self, t1: 'TreeNode', t2: 'TreeNode') -> 'TreeNode': """ + 合并两棵二叉树,将它们的节点值相加。 + + :param t1: 第一棵二叉树的根节点 :type t1: TreeNode + :param t2: 第二棵树的根节点 :type t2: TreeNode + :return: 合并后的二叉树的根节点 :rtype: TreeNode """ if t1 and t2: - root, root.left, root.right = TreeNode(t1.val + t2.val), self.mergeTrees(t1.left, t2.left), self.mergeTrees(t1.right, t2.right) + # 创建新的根节点,值为两棵树根节点值之和 + root = TreeNode(t1.val + t2.val) + # 递归合并左子树 + root.left = self.mergeTrees(t1.left, t2.left) + # 递归合并右子树 + root.right = self.mergeTrees(t1.right, t2.right) return root - else: return t1 or t2 \ No newline at end of file + else: + return t1 or t2 diff --git a/solutions/python3/62.py b/solutions/python3/62.py index af1a50d..7b9ce24 100644 --- a/solutions/python3/62.py +++ b/solutions/python3/62.py @@ -1,11 +1,33 @@ + class Solution: + # Python 解决方案 + def uniquePaths(self, m: int, n: int) -> int: + """ + 计算从左上角到右下角的不同路径数。 + + 参数: + m (int): 列的数量。 + n (int): 行的数量。 + + 返回: + int: 不同路径的总数。 + """ + + # 动态规划数组,用于存储每个位置的路径数量 dp = [[0] * m for _ in range(n)] + + # 起始点的路径数为1 dp[0][0] = 1 + + # 填充动态规划表 for i in range(n): for j in range(m): if i - 1 >= 0: dp[i][j] += dp[i - 1][j] if j - 1 >= 0: dp[i][j] += dp[i][j - 1] - return dp[-1][-1] \ No newline at end of file + + # 返回右下角的路径数,即为不同路径总数 + return dp[-1][-1] + diff --git a/solutions/python3/621.py b/solutions/python3/621.py index 8029df8..9ddb1db 100644 --- a/solutions/python3/621.py +++ b/solutions/python3/621.py @@ -1,6 +1,24 @@ + class Solution: - def leastInterval(self, tasks, n): - cnt = sorted(collections.Counter(tasks).values()) + def leastInterval(self, tasks: list[str], n: int) -> int: + """ + 计算最少需要的空闲时间单位以确保每个任务之间至少有n个空闲时间单位。 + + :param tasks: 需要执行的任务列表,形式为字符串 + :param n: 两个相同任务之间的最小间隔数(不包含当前任务) + :return: 最少需要的空闲时间单位数量 + """ + from collections import Counter + + # 统计每个任务出现的次数并排序 + cnt = sorted(Counter(tasks).values()) + + # 计算最大频率的任务的数量,并计算初始空闲槽数 idles = (cnt[-1] - 1) * n - for i in range(len(cnt) - 1): idles -= min(cnt[i], cnt[-1] - 1) - return idles > 0 and idles + len(tasks) or len(tasks) \ No newline at end of file + + # 减去最小间隔中可以利用的最大空闲时间 + for i in range(len(cnt) - 1): + idles -= min(cnt[i], cnt[-1] - 1) + + # 返回需要的空闲时间单位数量,考虑边界情况 + return (idles > 0 and idles + len(tasks)) or len(tasks) diff --git a/solutions/python3/622.py b/solutions/python3/622.py index c0c9164..ceec4d7 100644 --- a/solutions/python3/622.py +++ b/solutions/python3/622.py @@ -1,19 +1,33 @@ + class Node: + # 节点类,用于构建循环双向链表的节点 def __init__(self, value): - self.val = value - self.next = self.pre = None + self.val = value # 节点值 + self.next = None # 下一个节点引用 + self.pre = None # 前一个节点引用 + class MyCircularQueue: - def __init__(self, k): - self.size = k - self.curSize = 0 - self.head = self.tail = Node(-1) - self.head.next = self.tail + def __init__(self, k: int): # 初始化循环队列,大小为k + """ + :param k: 队列的最大容量 + """ + self.size = k # 最大容量 + self.curSize = 0 # 当前元素数量 + self.head = Node(-1) # 头哨兵节点 + self.tail = Node(-1) # 尾哨兵节点 + self.head.next = self.tail # 构建循环链表结构 self.tail.pre = self.head - def enQueue(self, value): + def enQueue(self, value: int) -> bool: + """ + 向队列尾部插入一个元素,返回操作是否成功 + :param value: 要插入的值 + :return: 操作是否成功 + """ if self.curSize < self.size: node = Node(value) + # 将新节点连接到链表中 node.pre = self.tail.pre node.next = self.tail node.pre.next = node.next.pre = node @@ -21,23 +35,44 @@ def enQueue(self, value): return True return False - def deQueue(self): + def deQueue(self) -> bool: + """ + 从队列头部移除一个元素,返回操作是否成功 + :return: 操作是否成功 + """ if self.curSize > 0: node = self.head.next + # 移除节点并更新指针 node.pre.next = node.next node.next.pre = node.pre self.curSize -= 1 return True return False - def Front(self): - return self.head.next.val + def Front(self) -> int: + """ + 获取队列头部元素,如果为空返回 -1 + :return: 队列头部元素或-1 + """ + return self.head.next.val if not self.isEmpty() else -1 - def Rear(self): - return self.tail.pre.val + def Rear(self) -> int: + """ + 获取队列尾部元素,如果为空返回 -1 + :return: 队列尾部元素或-1 + """ + return self.tail.pre.val if not self.isEmpty() else -1 - def isEmpty(self): + def isEmpty(self) -> bool: + """ + 判断队列是否为空 + :return: 是否为空 + """ return self.curSize == 0 - def isFull(self): - return self.curSize == self.size \ No newline at end of file + def isFull(self) -> bool: + """ + 判断队列是否已满 + :return: 是否已满 + """ + return self.curSize == self.size diff --git a/solutions/python3/623.py b/solutions/python3/623.py index 8bbf5d5..9448d4a 100644 --- a/solutions/python3/623.py +++ b/solutions/python3/623.py @@ -1,16 +1,28 @@ + class Solution: - def addOneRow(self, root, v, d): + def addOneRow(self, root: 'TreeNode', v: int, d: int) -> 'TreeNode': """ :type root: TreeNode :type v: int :type d: int :rtype: TreeNode """ + + # 初始化队列和深度计数器 q, depth = [root], 1 - while depth != d: parent, q, depth = q, [kid for node in q for kid in (node.left, node.right) if kid], depth+1 + + # 遍历至目标插入行的父节点所在的层级 + while depth != d: + parent, q, depth = q, [kid for node in q for kid in (node.left, node.right) if kid], depth + 1 + + # 当插入行不在根节点时,创建新节点并连接到原树 if d != 1: - for node in parent: node.left, node.right, node.left.left, node.right.right = TreeNode(v), TreeNode(v), node.left, node.right + for node in parent: + node.left, node.right = TreeNode(v), TreeNode(v) + node.left.left, node.right.right = node.left, node.right return root + + # 当插入行为根节点所在的行时,创建新根节点并连接原树 else: - first, first.left = TreeNode(v), root - return first \ No newline at end of file + first = TreeNode(v); first.left = root + return first diff --git a/solutions/python3/624.py b/solutions/python3/624.py index f910bc7..76a41de 100644 --- a/solutions/python3/624.py +++ b/solutions/python3/624.py @@ -1,7 +1,19 @@ + class Solution: + # 定义一个类来解决最大距离问题 + def maxDistance(self, arrays): - arrays.sort(key = lambda x: x[0]) + # 首先按照每个数组的第一个元素进行排序 + arrays.sort(key=lambda x: x[0]) + + # 计算以第一个数组为基准的最大距离:最后一个数组的最后一个元素减去第一个数组的第一个元素 d1 = max(arr[-1] for arr in arrays[1:]) - arrays[0][0] - arrays.sort(key = lambda x: x[-1]) + + # 再次对数组进行排序,这次按照每个数组的最后一个元素进行排序 + arrays.sort(key=lambda x: x[-1]) + + # 计算以最后一个数组为基准的最大距离:最后一个数组的最后一个元素减去第一个数组的第一个元素 d2 = arrays[-1][-1] - min(arr[0] for arr in arrays[:-1]) - return max(d1, d2) \ No newline at end of file + + # 返回两个最大距离中的较大值 + return max(d1, d2) diff --git a/solutions/python3/625.py b/solutions/python3/625.py index 7d0f1f1..08ca630 100644 --- a/solutions/python3/625.py +++ b/solutions/python3/625.py @@ -1,12 +1,35 @@ + class Solution: def smallestFactorization(self, a): + """ + 获取a的最小因子分解结果。 + + 参数: + a (int): 需要进行因子分解的整数 + + 返回: + int: 最小因子分解的结果,若无有效解则返回0 + """ + res = [] + def dfs(num): - if num == 1: return True + """ + 深度优先搜索实现最小因子分解。 + + 参数: + num (int): 当前待分解的数字 + + 返回: + bool: 若成功找到因子则返回True,否则返回False + """ + if num == 1: + return True for n in range(9, 1, -1): if not num % n: res.append(str(n)) return dfs(num // n) - return False + return False + bol, num = dfs(a), int("".join(sorted(res))) if res else 1 - return num if bol and -(2 ** 31) <= num <= 2 ** 31 - 1 else 0 \ No newline at end of file + return num if bol and -(2 ** 31) <= num <= 2 ** 31 - 1 else 0 diff --git a/solutions/python3/628.py b/solutions/python3/628.py index 74719e4..82c7420 100644 --- a/solutions/python3/628.py +++ b/solutions/python3/628.py @@ -1,8 +1,14 @@ + class Solution: def maximumProduct(self, nums): """ :type nums: List[int] :rtype: int """ + # 对数字列表进行排序,以方便获取最大值和最小值 + # Sort the numbers to easily access max and min values nums.sort() - return max(nums[-1]*nums[-2]*nums[-3], nums[-1]*nums[0]*nums[1]) \ No newline at end of file + + # 计算最后三个数的乘积和第一个数与前两个最小数的乘积的最大值 + # Calculate the maximum product of the last three or first two minimums and one maximum value + return max(nums[-1]*nums[-2]*nums[-3], nums[0]*nums[1]*nums[-1]) diff --git a/solutions/python3/629.py b/solutions/python3/629.py index 6792bfd..6434bce 100644 --- a/solutions/python3/629.py +++ b/solutions/python3/629.py @@ -1,7 +1,16 @@ + class Solution: - def kInversePairs(self, n, k): - dp = [1] + [0] * k - for i in range(2, n + 1): - for j in range(1, k + 1): dp[j] += dp[j - 1] - for j in range(k, 0, -1): dp[j] -= j - i >= 0 and dp[j - i] - return dp[-1] % (10 ** 9 + 7) \ No newline at end of file + def kInversePairs(self, n: int, k: int) -> int: + # 使用动态规划计算k逆序对个数 + # Dynamic Programming to calculate the number of k inverse pairs + + dp = [1] + [0] * k # 初始化dp数组,dp[0]=1表示没有元素时逆序对为0种情况 + + for i in range(2, n + 1): # 遍历n的取值 + for j in range(1, k + 1): + dp[j] += dp[j - 1] # 状态转移方程的第一部分,累加前一个状态 + + for j in range(k, 0, -1): + dp[j] -= (j - i >= 0 and dp[j - i]) # 状态转移方程的第二部分,减去超出范围的部分 + + return dp[-1] % (10 ** 9 + 7) # 返回结果,并取模 diff --git a/solutions/python3/63.py b/solutions/python3/63.py index 1b0a6af..761e854 100644 --- a/solutions/python3/63.py +++ b/solutions/python3/63.py @@ -1,12 +1,32 @@ class Solution: def uniquePathsWithObstacles(self, obstacleGrid): - if obstacleGrid[0][0] == 1: return 0 - for i in range(len(obstacleGrid)): - for j in range(len(obstacleGrid[0])): - if obstacleGrid[i][j] == 1 or i == j == 0: - obstacleGrid[i][j] -= 1 - else: - add1 = obstacleGrid[i - 1][j] if i > 0 else 0 - add2 = obstacleGrid[i][j - 1] if j > 0 else 0 - obstacleGrid[i][j] += add1 + add2 - return abs(obstacleGrid[-1][-1]) \ No newline at end of file + """ + :param obstacleGrid: List[List[int]], grid with obstacles (1) and free cells (0) + :return: int, number of unique paths from top-left to bottom-right + """ + if not obstacleGrid or not obstacleGrid[0]: + return 0 + + m, n = len(obstacleGrid), len(obstacleGrid[0]) + dp = [[0] * n for _ in range(m)] + + # Initialize first cell + dp[0][0] = 1 if obstacleGrid[0][0] == 0 else 0 + + # Initialize first row + for j in range(1, n): + if obstacleGrid[0][j] == 0: + dp[0][j] = dp[0][j-1] + + # Initialize first column + for i in range(1, m): + if obstacleGrid[i][0] == 0: + dp[i][0] = dp[i-1][0] + + # Fill dp table + for i in range(1, m): + for j in range(1, n): + if obstacleGrid[i][j] == 0: + dp[i][j] = dp[i-1][j] + dp[i][j-1] + + return dp[m-1][n-1] \ No newline at end of file diff --git a/solutions/python3/630.py b/solutions/python3/630.py index c0a2996..a8a73a7 100644 --- a/solutions/python3/630.py +++ b/solutions/python3/630.py @@ -1,10 +1,22 @@ + class Solution: + # 定义一个解题类 + def scheduleCourse(self, courses): - pq = [] - start = 0 - for t, end in sorted(courses, key = lambda x: x[1]): - start += t - heapq.heappush(pq, -t) - while start > end: - start += heapq.heappop(pq) - return len(pq) \ No newline at end of file + """ + :param courses: 课程列表,每个元素为 (开始时间, 结束时间) 的元组 + :return: 最多可以完成的课程数 + """ + import heapq + pq = [] # 使用优先队列来存储选中的课程时长(取负数以利用最小堆实现最大堆效果) + + start = 0 # 当前已完成课程的时间总和 + + for t, end in sorted(courses, key=lambda x: x[1]): # 按照结束时间排序 + start += t # 加入当前课程所需时间到已选课程总时间中 + heapq.heappush(pq, -t) # 将当前课程时长取负后加入优先队列 + + while start > end: # 若已完成课程总时间超过了当前课程的结束时间 + start += heapq.heappop(pq) # 移除优先队列中时长最大的课程(即弹出并加上正值) + + return len(pq) # 返回优先队列中的元素个数,即最多可以完成的课程数量 diff --git a/solutions/python3/631.py b/solutions/python3/631.py index a17426b..aac80f3 100644 --- a/solutions/python3/631.py +++ b/solutions/python3/631.py @@ -1,20 +1,26 @@ + class Excel(object): + # 构造函数,初始化Excel表格,H为行数,W为列数(字母表示) def __init__(self, H, W): self.M = [[{'v': 0, 'sum': None} for i in range(H)] for j in range(ord(W) - 64)] + # 设置单元格值 def set(self, r, c, v): self.M[r - 1][ord(c) - 65] = {'v': v, 'sum': None} + # 获取单元格的计算结果,优先返回直接设置的值,否则进行累加求和 def get(self, r, c): cell = self.M[r - 1][ord(c) - 65] if not cell['sum']: return cell['v'] return sum(self.get(*pos) * cell['sum'][pos] for pos in cell['sum']) + # 设置单元格的计算公式,返回计算结果 def sum(self, r, c, strs): self.M[r - 1][ord(c) - 65]['sum'] = self.parse(strs) return self.get(r, c) + # 解析字符串为二维坐标集合 def parse(self, strs): c = collections.Counter() for s in strs: @@ -22,4 +28,4 @@ def parse(self, strs): for i in range(int(s[1:]), int(e[1:]) + 1): for j in range(ord(s[0]) - 64, ord(e[0]) - 64 + 1): c[(i, chr(j + 64))] += 1 - return c \ No newline at end of file + return c diff --git a/solutions/python3/632.py b/solutions/python3/632.py index d9627f2..e86aa3c 100644 --- a/solutions/python3/632.py +++ b/solutions/python3/632.py @@ -1,9 +1,17 @@ + class Solution: + # 定义解决方案类 + def smallestRange(self, nums): + # nums: List[List[int]] -> 二维数组,每个子数组为一个升序序列 L = R = None + # 初始化最小值L和最大值R为None + while True: mn = mx = nums[0][-1] ind = [0] + # 初始化最小值mn和最大值mx为第一个子数组的最后一个元素,索引列表ind初始化为包含起点0 + for i, ls in enumerate(nums[1:]): if ls[-1] > mx: mx, ind = ls[-1], [i + 1] @@ -11,9 +19,14 @@ def smallestRange(self, nums): ind.append(i + 1) elif ls[-1] < mn: mn = ls[-1] - if L == None or mx - mn <= R - L: + # 遍历其他子数组,更新最大值mx和最小值mn,并记录对应的索引 + + if L is None or mx - mn <= R - L: L, R = mn, mx + # 如果L为None或当前区间比已有区间更小,则更新L和R + for j in ind: nums[j].pop() if not nums[j]: - return [L, R] \ No newline at end of file + return [L, R] + # 从满足条件的子数组中移除最后一个元素,若该子数组为空则返回[L,R] diff --git a/solutions/python3/633.py b/solutions/python3/633.py index ec73e8f..b70dd33 100644 --- a/solutions/python3/633.py +++ b/solutions/python3/633.py @@ -1,3 +1,10 @@ + class Solution: + # 判断一个数是否可以表示为两个平方数之和 def judgeSquareSum(self, c: int) -> bool: - return not all(((c - i ** 2) ** 0.5) % 1 for i in range(int(c ** 0.5) + 1)) \ No newline at end of file + # 遍历从0到根号c的所有可能值i + for i in range(int(c ** 0.5) + 1): + # 检查c - i**2 是否为完全平方数 + if not ((c - i ** 2) ** 0.5) % 1: + return True + return False diff --git a/solutions/python3/635.py b/solutions/python3/635.py index 0ae0819..d2c6796 100644 --- a/solutions/python3/635.py +++ b/solutions/python3/635.py @@ -1,13 +1,31 @@ + class LogSystem: def __init__(self): + """ + 初始化日志系统,存储时间戳和对应ID的列表。 + Initialize the log system with a list to store timestamps and corresponding IDs. + """ self.times = [] self.g = {"Year": 4, "Month": 7, "Day": 10, "Hour": 13, "Minute": 16, "Second": 19} - - def put(self, id, timestamp): + + def put(self, id: str, timestamp: str): + """ + 添加一条记录,包含ID和对应的时间戳。 + Add a record with the given ID and timestamp. + :param id: 记录的ID + :param timestamp: 时间戳字符串 + """ self.times.append([timestamp, id]) - def retrieve(self, s, e, gra): + def retrieve(self, s: str, e: str, gra: str): + """ + 根据给定的时间段和粒度检索记录。 + Retrieve records based on the given time range and granularity. + :param s: 时间范围的起始时间戳 + :param e: 时间范围的结束时间戳 + :param gra: 粒度标识,可以是"Year", "Month", "Day", "Hour", "Minute", "Second" + """ ind = self.g[gra] - s, e = s[:ind], e[:ind] - return [i for time, i in self.times if s <= time[:ind] <= e] \ No newline at end of file + s, e = s[:ind], e[:ind] # 截取指定粒度的时间戳 + return [i for time, i in self.times if s <= time[:ind] <= e] # 检索符合条件的记录 diff --git a/solutions/python3/636.py b/solutions/python3/636.py index 43073eb..9df611e 100644 --- a/solutions/python3/636.py +++ b/solutions/python3/636.py @@ -1,14 +1,29 @@ + class Solution: - def exclusiveTime(self, n, logs): - res, stack = [0] * n, [] + # 定义一个类来解决exclusive时间的问题 + + def exclusiveTime(self, n: int, logs: list) -> list: + # 初始化结果列表和栈 + res = [0] * n + stack = [] + for log in logs: - log = log.split(":") - if log[1] == "start": - stack.append([int(log[2]), 0]) + # 解析日志字符串 + log_info = log.split(":") + + if log_info[1] == "start": + # 开始任务,记录开始时间和任务ID入栈 + stack.append([int(log_info[2]), 0]) else: - start = stack.pop() - time = int(log[2]) - start[0] + 1 - res[int(log[0])] += time - start[1] + # 结束任务,计算执行时间并更新结果列表 + start_time, prev_exec_time = stack.pop() + duration = int(log_info[2]) - start_time + 1 + + # 更新当前任务的执行时间 + res[int(log_info[0])] += duration - prev_exec_time + if stack: - stack[-1][1] += time - return res \ No newline at end of file + # 如果栈不为空,将子任务的执行时间累加到父任务上 + stack[-1][1] += duration + + return res diff --git a/solutions/python3/637.py b/solutions/python3/637.py index 1b2848b..3978176 100644 --- a/solutions/python3/637.py +++ b/solutions/python3/637.py @@ -1,24 +1,36 @@ + # Definition for a binary tree node. -# class TreeNode: -# def __init__(self, x): -# self.val = x -# self.left = None -# self.right = None +class TreeNode: + def __init__(self, x): + self.val = x + self.left = None + self.right = None class Solution: - def averageOfLevels(self, root): + def averageOfLevels(self, root: 'TreeNode') -> 'List[float]': """ :type root: TreeNode :rtype: List[float] """ from collections import deque + + # 初始化队列和目标节点,记录每一层的平均值 q, target, avg = deque([root]), root, [float(root.val)] + while q: - node=q.popleft() - if node.left: q.append(node.left) - if node.right: q.append(node.right) - if q and node==target: + node = q.popleft() + + # 将左右子节点加入队列中 + if node.left: + q.append(node.left) + if node.right: + q.append(node.right) + + # 当前层遍历结束时计算平均值 + if q and node == target: target, sm = q[-1], 0 - for item in q: sm+=item.val - avg.append(sm/len(q)) - return avg \ No newline at end of file + for item in q: + sm += item.val + avg.append(sm / len(q)) + + return avg diff --git a/solutions/python3/638.py b/solutions/python3/638.py index 883144e..9f14cfd 100644 --- a/solutions/python3/638.py +++ b/solutions/python3/638.py @@ -1,8 +1,17 @@ + class Solution: - def shoppingOffers(self, price, special, needs): - def dfs(cur, needs): + def shoppingOffers(self, price: List[int], special: List[List[int]], needs: List[int]) -> int: + # 定义深度优先搜索函数,参数为当前已选物品总价和剩余需求 + def dfs(cur: int, needs: List[int]) -> int: + # 计算不使用任何优惠券的直接购买成本 val = cur + sum(p * needs[i] for i, p in enumerate(price)) + # 遍历所有优惠券组合 for s in special: - if all(n >= s[i] for i,n in enumerate(needs)): val = min(val, dfs(cur + s[-1], [n - s[i] for i,n in enumerate(needs)])) + # 检查当前需求是否满足使用该优惠券的条件,即每种商品数量都不小于优惠券中要求的数量 + if all(n >= s[i] for i, n in enumerate(needs)): + # 更新最小总成本为当前值与使用优惠券后的新组合价格中的较小者 + val = min(val, dfs(cur + s[-1], [n - s[i] for i, n in enumerate(needs)])) return val - return dfs(0, needs) \ No newline at end of file + + # 从0元开始,根据初始需求调用dfs函数计算最小花费 + return dfs(0, needs) diff --git a/solutions/python3/639.py b/solutions/python3/639.py index 4c318f8..a1baf15 100644 --- a/solutions/python3/639.py +++ b/solutions/python3/639.py @@ -1,19 +1,71 @@ + class Solution: - def numDecodings(self, s): - if s[0] == "0": return 0 + # 定义一个解码方法的数量的类 + def numDecodings(self, s: str) -> int: + """ + 计算给定字符串s中的数字解码方式数量。 + + 参数: + s (str): 给定的包含星号和数字字符的字符串 + + 返回: + int: 解码方式的数量,结果对10^9 + 7取模 + """ + + # 如果第一个字符是'0',直接返回0,因为无法解码 + if s[0] == "0": + return 0 + + # 初始化动态规划数组的前两个值 dp1 = dp2 = 1 - if s[0] == "*": dp2 = 9 + + # 处理第一个字符为'*'的情况 + if s[0] == "*": + dp2 = 9 + + # 遍历字符串从第二个字符开始 for i in range(1, len(s)): - couple, newDp1 = s[i -1: i + 1], dp2 + # 当前两个字符组成的数 + couple, newDp1 = s[i - 1:i + 1], dp2 + + # 如果当前字符是'0' if s[i] == "0": - if s[i - 1] == "0" or s[i - 1] >= "3": return 0 + # 如果前一个字符也是'0'或大于等于'3',则无法解码返回0 + if s[i - 1] == "0" or s[i - 1] >= "3": + return 0 + # 更新dp2为当前的dp1值乘以2(因为两个字符可以看作一个整体) dp2 = 2 * dp1 if s[i - 1] == "*" else dp1 + + # 当前字符是'*' elif s[i] == "*": + # '*'代表0到9,所以乘以9 dp2 *= 9 - if s[i - 1] == "2": dp2 += 6 * dp1 - elif s[i - 1] == "1": dp2 += 9 * dp1 - elif s[i - 1] == "*": dp2 += 15 * dp1 - elif "10" <= couple <= "26": dp2 += dp1 - elif s[i - 1] == "*": dp2 += 2 * dp1 if s[i] <= "6" else dp1 + # 如果前一个字符为'2', 则当前'*'可以组合成20-26,共6种可能,加上dp1的值 + if s[i - 1] == "2": + dp2 += 6 * dp1 + # 前一个字符为'1', '*0-*9'共有9种解码方式,加到dp2中 + elif s[i - 1] == "1": + dp2 += 9 * dp1 + # 前一个字符为'*', 当前 '*'可以与'1'和'2'组合成10-19或20-26,共15种可能 + elif s[i - 1] == "*": + dp2 += 15 * dp1 + + # 当前两个字符组成的数在10到26之间 + elif "10" <= couple <= "26": + # 加上dp1的值,因为这两个数字组合可以单独解码 + dp2 += dp1 + + # 前一个字符为'*'且当前字符小于等于'6' + elif s[i - 1] == "*" and s[i] <= "6": + # '*'可以与前一位置的字符组成10-19或20-26,共12种可能 + dp2 += 2 * dp1 + + else: + # 其他情况,直接加上dp1的值 + dp2 += dp1 + + # 更新dp1为上一步的结果 dp1 = newDp1 - return dp2 % (10 ** 9 + 7) \ No newline at end of file + + # 返回结果对10^9 + 7取模 + return dp2 % (10 ** 9 + 7) diff --git a/solutions/python3/64.py b/solutions/python3/64.py index a1b33d2..864c551 100644 --- a/solutions/python3/64.py +++ b/solutions/python3/64.py @@ -4,7 +4,22 @@ def minPathSum(self, grid): :type grid: List[List[int]] :rtype: int """ - for i in range(len(grid)): - for j in range(len(grid[0])): - grid[i][j] += min(grid[i][j - 1] if j > 0 else float("inf"), grid[i - 1][j] if i > 0 else float("inf")) if i!=0 or j != 0 else 0 - return grid[-1][-1] \ No newline at end of file + if not grid: + return 0 + + m, n = len(grid), len(grid[0]) + + # Handle first row + for j in range(1, n): + grid[0][j] += grid[0][j-1] + + # Handle first column + for i in range(1, m): + grid[i][0] += grid[i-1][0] + + # Calculate minimum path for rest of the grid + for i in range(1, m): + for j in range(1, n): + grid[i][j] += min(grid[i-1][j], grid[i][j-1]) + + return grid[m-1][n-1] \ No newline at end of file diff --git a/solutions/python3/640.py b/solutions/python3/640.py index cd69b13..711b6e7 100644 --- a/solutions/python3/640.py +++ b/solutions/python3/640.py @@ -1,6 +1,19 @@ + class Solution: def solveEquation(self, equation): + """ + 解决一元一次方程问题 + + :param equation: 代表方程的字符串,格式如 "x+5-3+x=6+x-2" + """ + def calc(eq): + """ + 计算表达式中的x系数和常数项 + + :param eq: 字符串形式的一元一次方程部分 + :return: x系数与常数项组成的元组 + """ smX = smNum = 0 add, num = True, "" for c in eq + "+": @@ -13,8 +26,13 @@ def calc(eq): smNum += int(num) if add and num else -int(num) if num else 0 num, add = "", c == "+" return smX, smNum + + # 分割等号左右两边的表达式 eq = equation.split("=") lX, lNum, rX, rNum = calc(eq[0]) + calc(eq[1]) - if lX == rX: + + if lX == rX: return "No solution" if lNum != rNum else "Infinite solutions" - return "x=" + str((lNum - rNum) // (rX - lX)) \ No newline at end of file + + # 计算x的值 + return f"x={str((lNum - rNum) // (rX - lX))}" diff --git a/solutions/python3/641.py b/solutions/python3/641.py index e20c2bc..f0bfdf8 100644 --- a/solutions/python3/641.py +++ b/solutions/python3/641.py @@ -1,66 +1,115 @@ + class Node: + """节点类,包含值和前后节点指针""" def __init__(self, value): self.val = value self.next = self.pre = None - + class MyCircularDeque: - def __init__(self, k): + def __init__(self, k: int): + """ + 初始化循环双端队列。k为最大容量。 + :param k: + """ + # 使用虚拟头尾节点简化边界情况处理 self.head = self.tail = Node(-1) self.head.next = self.tail self.tail.pre = self.head - self.size = k - self.curSize = 0 + self.size = k # 容量 + self.curSize = 0 # 当前容量 + + def add(self, value: int, preNode: 'Node'): + """ + 在指定节点后插入新节点。 + :param value: 新值 + :param preNode: 前驱节点 + """ + new_node = Node(value) + new_node.pre = preNode + new_node.next = preNode.next + new_node.next.pre = new_node + preNode.next = new_node + + def remove(self, preNode: 'Node'): + """ + 移除指定节点的后继节点。 + :param preNode: 前驱节点 + """ + node_to_remove = preNode.next + node_to_remove.pre.next = node_to_remove.next + node_to_remove.next.pre = node_to_remove.pre - def add(self, value, preNode): - new = Node(value) - new.pre = preNode - new.next = preNode.next - new.pre.next = new.next.pre = new - self.curSize += 1 - - def remove(self, preNode): - node = preNode.next - node.pre.next = node.next - node.next.pre = node.pre - self.curSize -= 1 - - def insertFront(self, value): + def insertFront(self, value: int) -> bool: + """ + 在队列头部插入值,返回是否成功。 + :param value: 要插入的值 + :return: 是否成功 + """ if self.curSize < self.size: self.add(value, self.head) return True return False - def insertLast(self, value): + def insertLast(self, value: int) -> bool: + """ + 在队列尾部插入值,返回是否成功。 + :param value: 要插入的值 + :return: 是否成功 + """ if self.curSize < self.size: self.add(value, self.tail.pre) return True return False - def deleteFront(self): - if self.curSize: + def deleteFront(self) -> bool: + """ + 删除队列头部元素,返回是否成功。 + :return: 是否成功 + """ + if self.curSize > 0: self.remove(self.head) return True return False - def deleteLast(self): - if self.curSize: + def deleteLast(self) -> bool: + """ + 删除队列尾部元素,返回是否成功。 + :return: 是否成功 + """ + if self.curSize > 0: self.remove(self.tail.pre.pre) return True return False def getFront(self): - if self.curSize: + """ + 获取头部值。若为空,则返回-1。 + :return: 队列首部元素或-1 + """ + if self.curSize > 0: return self.head.next.val return -1 def getRear(self): - if self.curSize: + """ + 获取尾部值。若为空,则返回-1。 + :return: 队列尾部元素或-1 + """ + if self.curSize > 0: return self.tail.pre.val return -1 - def isEmpty(self): + def isEmpty(self) -> bool: + """ + 检查是否为空。 + :return: 是否为空 + """ return self.curSize == 0 - def isFull(self): - return self.curSize == self.size \ No newline at end of file + def isFull(self) -> bool: + """ + 检查是否已满。 + :return: 是否已满 + """ + return self.curSize == self.size diff --git a/solutions/python3/642.py b/solutions/python3/642.py index 2e95bdb..54f44cf 100644 --- a/solutions/python3/642.py +++ b/solutions/python3/642.py @@ -1,28 +1,46 @@ + class AutocompleteSystem: def __init__(self, sentences: List[str], times: List[int]): + """ + 初始化类对象,设置根节点和排名字典。 + :param sentences: 输入的句子列表 + :param times: 各句子出现次数 + """ self.cur = self.root = {} self.rank = collections.defaultdict(int) for i, s in enumerate(sentences): self.s = s - self.rank[s] = times[i] - 1 + self.rank[s] = times[i] self.input('#') - - def move(self, c): + + def move(self, c: str) -> None: + """ + 移动到当前节点的子节点。 + :param c: 当前字符 + """ if c not in self.cur: self.cur[c] = {} self.cur = self.cur[c] if 'sentences' not in self.cur: self.cur['sentences'] = [] - - def addSentence(self): + + def addSentence(self) -> None: + """ + 添加句子到当前节点。 + :return: 无 + """ self.cur = self.root for c in self.s: self.move(c) self.search() heapq.heappush(self.cur['sentences'], [-self.rank[self.s], self.s]) - - def search(self): + + def search(self) -> List[str]: + """ + 搜索并返回排名最高的三个句子。 + :return: 三个句子列表 + """ q, used, i = [], set(), 0 while i < 3 and self.cur['sentences']: r, s = heapq.heappop(self.cur['sentences']) @@ -33,8 +51,13 @@ def search(self): for r, s in q: heapq.heappush(self.cur['sentences'], [r, s]) return [s for r, s in q] - + def input(self, c: str) -> List[str]: + """ + 处理输入字符,返回当前可能的建议列表。 + :param c: 输入字符 + :return: 三个句子列表或空列表 + """ if c == '#': self.rank[self.s] += 1 self.addSentence() @@ -45,9 +68,8 @@ def input(self, c: str) -> List[str]: self.s += c self.move(c) return self.search() - # Your AutocompleteSystem object will be instantiated and called as such: # obj = AutocompleteSystem(sentences, times) -# param_1 = obj.input(c) \ No newline at end of file +# param_1 = obj.input(c) diff --git a/solutions/python3/643.py b/solutions/python3/643.py index e81d713..c2f5b0e 100644 --- a/solutions/python3/643.py +++ b/solutions/python3/643.py @@ -1,11 +1,26 @@ + class Solution: - def findMaxAverage(self, nums, k): + def findMaxAverage(self, nums: list[int], k: int) -> float: """ - :type nums: List[int] - :type k: int - :rtype: float + :param nums: 输入的整数列表 + :param k: 滑动窗口大小,用于计算平均值 + :return: 最大滑动窗口均值 """ - sm=sum(nums[:k]) - mx,j=sm/k, 0 - for i in range(k,len(nums)): sm+=nums[i]; sm-=nums[j]; curr=sm/k; mx=max(curr,mx); j+=1 - return mx \ No newline at end of file + + # 初始化滑动窗口的前k个元素之和 + window_sum = sum(nums[:k]) + # 初始最大均值及起始位置索引 + max_avg, j = window_sum / k, 0 + + # 滑动窗口遍历输入列表 + for i in range(k, len(nums)): + # 更新滑动窗口的元素和 + window_sum += nums[i] + window_sum -= nums[j] + # 当前均值 + curr_avg = window_sum / k + # 更新最大均值 + max_avg = max(curr_avg, max_avg) + j += 1 + + return max_avg diff --git a/solutions/python3/644.py b/solutions/python3/644.py index bd0062c..172d096 100644 --- a/solutions/python3/644.py +++ b/solutions/python3/644.py @@ -1,11 +1,18 @@ + class Solution: + # 寻找长度为k的子数组的最大平均值 + def findMaxAverage(self, nums: List[int], k: int) -> float: + # 辅助函数,检查给定mid是否满足条件 def sub(mid): sm = pre = mn = 0 + # 初始化前k个元素的和与最小前缀和 for i in range(k): sm += nums[i] - mid if sm >= 0: return True + + # 遍历剩余元素,维护滑动窗口内的和与最小前缀和 for i in range(k, len(nums)): sm += nums[i] - mid pre += nums[i - k] - mid @@ -13,11 +20,16 @@ def sub(mid): if sm >= mn: return True return False + + # 初始化二分查找的左右边界 l, r = min(nums), max(nums) + + # 二分查找,找到满足条件的最大mid值 while l + 1E-6 < r: mid = (l + r) / 2 if sub(mid): l = mid else: r = mid - return l \ No newline at end of file + + return l diff --git a/solutions/python3/645.py b/solutions/python3/645.py index bcbccc6..7611a95 100644 --- a/solutions/python3/645.py +++ b/solutions/python3/645.py @@ -1,4 +1,15 @@ + class Solution: + # 定义一个方法 findErrorNums,输入是一个整数列表 nums,返回两个整数的列表 def findErrorNums(self, nums: List[int]) -> List[int]: - cnt = collections.Counter(nums) - return [k for k in cnt if cnt[k] == 2] + [i for i in range(1, len(nums) + 1) if i not in cnt] \ No newline at end of file + from collections import Counter # 引入计数器模块 + + cnt = Counter(nums) # 统计每个数字出现的次数 + + # 首先找到重复的数字,即在计数中出现了两次的数字 + duplicate = [k for k in cnt if cnt[k] == 2] + + # 然后找出缺失的数字,即1到nums长度范围内的数字但不在cnt中的数字 + missing = [i for i in range(1, len(nums) + 1) if i not in cnt] + + return duplicate + missing # 返回重复和缺失的数字列表 diff --git a/solutions/python3/646.py b/solutions/python3/646.py index a5ee1f5..95d3ef3 100644 --- a/solutions/python3/646.py +++ b/solutions/python3/646.py @@ -1,9 +1,19 @@ + class Solution: + # 寻找最长链路的方法,输入为一个二维数组pairs def findLongestChain(self, pairs): - pairs.sort(key = lambda x: x[1]) + # 按照每对元素的第二个值排序 + pairs.sort(key=lambda x: x[1]) + + # 初始化结果res和前一个元素的第二位值pre res, pre = 1, pairs[0][1] + + # 遍历pairs中的每个元素,从索引为1开始 for c, d in pairs[1:]: + # 如果当前元素的第一个值大于前一个元素的第二个值,则形成一个新的链路 if pre < c: - pre = d - res += 1 - return res \ No newline at end of file + pre = d # 更新pre为当前元素的第二个值 + res += 1 # 长度加一 + + # 返回最长链路的长度 + return res diff --git a/solutions/python3/647.py b/solutions/python3/647.py index 33ebb22..e1fb7ae 100644 --- a/solutions/python3/647.py +++ b/solutions/python3/647.py @@ -1,15 +1,33 @@ + class Solution: def countSubstrings(self, s): + """ + 计算字符串s的所有回文子串的数量。 + + 参数: + s (str): 输入的字符串 + + 返回: + int: 回文子串的数量 + """ res = 0 for k in range(len(s)): - i = j = k + # 中心扩展法,以单个字符为中心向两边扩散 + i, j = k, k while 0 <= i and j < len(s): - if s[i] == s[j]: res += 1 - else: break - i , j = i - 1, j + 1 - i , j =k , k + 1 + if s[i] == s[j]: + res += 1 + else: + break + i, j = i - 1, j + 1 + + # 中心扩展法,以两个字符之间的空隙为中心向两边扩散 + i, j = k, k + 1 while 0 <= i and j < len(s): - if s[i] == s[j]: res += 1 - else: break - i , j = i - 1, j + 1 - return res \ No newline at end of file + if s[i] == s[j]: + res += 1 + else: + break + i, j = i - 1, j + 1 + + return res diff --git a/solutions/python3/648.py b/solutions/python3/648.py index 92a12ce..4764ffa 100644 --- a/solutions/python3/648.py +++ b/solutions/python3/648.py @@ -1,15 +1,28 @@ + class Solution: def replaceWords(self, dict, sentence): """ :type dict: List[str] :type sentence: str :rtype: str + + 方法说明:使用集合加速前缀查找,遍历句子中的每个单词,寻找其最短前缀在词典中,并替换之。 """ + + # 使用集合存储词典以加快查找速度 s = set(dict) + + # 将句子按空格分割成单词列表 sentence = sentence.split() + + # 遍历每个单词 for j, w in enumerate(sentence): + # 检查该单词的每一个前缀是否在词典中 for i in range(1, len(w)): - if w[:i] in s: + if w[:i] in s: + # 如果找到,则替换为最短前缀 sentence[j] = w[:i] break - return " ".join(sentence) \ No newline at end of file + + # 将处理后的单词列表重新组合成句子并返回 + return " ".join(sentence) diff --git a/solutions/python3/649.py b/solutions/python3/649.py index ef59418..9d2c434 100644 --- a/solutions/python3/649.py +++ b/solutions/python3/649.py @@ -1,28 +1,43 @@ + class Solution: def predictPartyVictory(self, senate): + # 初始化R和D的禁用计数器 ban_r = ban_d = 0 + + # 循环直到胜负者确定 while True: + # 新一轮参议员列表 new = [] + + # R和D参议员的数量统计 r_cnt = d_cnt = 0 + + # 遍历当前参议院成员 for s in senate: - if s == 'R': + if s == 'R': + # 增加R计数,如果已禁用则减少禁用计数,否则增加D的禁用计数并移除R r_cnt += 1 - if ban_r > 0: + if ban_r > 0: ban_r -= 1 - else: + else: ban_d += 1 d_cnt -= 1 new.append(s) elif s == 'D': + # 增加D计数,如果已禁用则减少禁用计数,否则增加R的禁用计数并移除D d_cnt += 1 - if ban_d > 0: + if ban_d > 0: ban_d -= 1 - else: + else: ban_r += 1 r_cnt -= 1 new.append(s) + + # 判断胜负条件 if d_cnt < 0 < r_cnt: return "Radiant" elif r_cnt < 0 < d_cnt: return "Dire" - senate = new \ No newline at end of file + + # 更新参议院成员列表 + senate = new diff --git a/solutions/python3/65.py b/solutions/python3/65.py index e2ed303..d3f56aa 100644 --- a/solutions/python3/65.py +++ b/solutions/python3/65.py @@ -1,23 +1,44 @@ + class Solution: - def isNumber(self, s): + def isNumber(self, s: str) -> bool: + """ + 判断字符串s是否为一个有效的数字。 + + 参数: + s (str): 输入的字符串 + + 返回: + bool: 如果s是有效数字则返回True,否则返回False + """ + + # 去除首尾空格 s = s.strip() - pointSeen = eSeen = numberSeen = False - numberAfterE = True + + # 标记位:小数点是否出现过、e是否出现过、是否有数字以及e之后是否有数字 + point_seen, e_seen, number_seen, number_after_e = False, False, False, True + for i, c in enumerate(s): - if "0" <= c <= "9": - numberSeen = numberAfterE = True - elif c == ".": - if eSeen or pointSeen: + if '0' <= c <= '9': + # 数字字符,设置number_seen和number_after_e为True + number_seen = number_after_e = True + elif c == '.': + # 小数点,检查之前是否已经出现过小数点或e + if e_seen or point_seen: return False - pointSeen = True - elif c == "e": - if eSeen or not numberSeen: + point_seen = True + elif c == 'e': + # 指数符号e,检查之前是否已经出现过e或者没有数字 + if e_seen or not number_seen: return False - numberAfterE = False - eSeen = True - elif c in "-+": - if i and s[i - 1] != "e": + number_after_e = False # e之后不再允许有小数点 + e_seen = True + elif c in '-+': + # 正负号,只能出现在首或e后第一个字符 + if i and s[i - 1] != 'e': return False else: + # 其他非法字符直接返回False return False - return numberSeen and numberAfterE \ No newline at end of file + + # 最终检查是否所有条件都满足 + return number_seen and number_after_e diff --git a/solutions/python3/650.py b/solutions/python3/650.py index 88b1a9d..0f5f808 100644 --- a/solutions/python3/650.py +++ b/solutions/python3/650.py @@ -1,10 +1,18 @@ + class Solution: - def minSteps(self, n): + # 定义一个Solution类,包含minSteps方法用于计算最小操作步数 + + def minSteps(self, n: int) -> int: + # 初始化当前数量cur、复制的数量copy以及操作步骤steps cur, copy, steps = 1, 0, 0 + + # 当当前数量不等于目标值n时,继续循环 while cur != n: - if copy < cur and not (n - cur) % cur: - copy = cur + if copy < cur and (n - cur) % cur == 0: # 判断是否可以执行粘贴操作 + copy = cur # 将当前数量复制到剪贴板中 else: - cur += copy - steps += 1 - return steps \ No newline at end of file + cur += copy # 执行复制+粘贴操作,增加当前数量 + + steps += 1 # 每次循环后操作步数加一 + + return steps # 返回最小操作步数 diff --git a/solutions/python3/651.py b/solutions/python3/651.py index 13c0c70..ede09ee 100644 --- a/solutions/python3/651.py +++ b/solutions/python3/651.py @@ -1,8 +1,34 @@ + class Solution: - def maxA(self, N): + # 定义一个类用于解决最大A值问题 + + def maxA(self, N: int) -> int: + # 初始化动态规划数组,长度为N+1 dp = [0] * (N + 1) + + # 遍历所有可能的N值 for i in range(N + 1): + # 初始设置dp[i]=i dp[i] = i - for j in range(1, i - 2): + + # 内层循环优化:只需遍历到i-3即可,因为(i-j-1)必须大于0 + for j in range(1, i - 2 + 1): # 增加1以包含i-2的情况 + # 更新dp[i]为最大值 dp[i] = max(dp[i], dp[j] * (i - j - 1)) - return dp[N] \ No newline at end of file + + # 返回最终结果 + return dp[N] + + + +class Solution: + def maxA(self, N: int) -> int: + dp = [0] * (N + 1) + + for i in range(N + 1): + dp[i] = i + + for j in range(1, i - 2 + 1): + dp[i] = max(dp[i], dp[j] * (i - j - 1)) + + return dp[N] diff --git a/solutions/python3/652.py b/solutions/python3/652.py index 28e6598..852c8c4 100644 --- a/solutions/python3/652.py +++ b/solutions/python3/652.py @@ -1,11 +1,26 @@ + class Solution: + # 寻找二叉树中的重复子树 + def findDuplicateSubtrees(self, root): + """ + :param root: TreeNode, 树的根节点 + :return: List[TreeNode], 包含所有重复子树的根节点列表 + """ + def dfs(root): - if not root: return "null" + # 如果当前节点为空,返回'null' + if not root: + return "null" + # 构建子树结构字符串 struct = "%s,%s,%s" % (str(root.val), dfs(root.left), dfs(root.right)) + # 将当前子树结构与对应的节点加入字典 nodes[struct].append(root) return struct - + + # 使用defaultdict存储子树结构及其对应的节点列表 nodes = collections.defaultdict(list) + # 从根节点开始进行深度优先搜索 dfs(root) - return [nodes[struct][0] for struct in nodes if len(nodes[struct]) > 1] \ No newline at end of file + # 返回所有出现多次的子树的首个节点 + return [nodes[struct][0] for struct in nodes if len(nodes[struct]) > 1] diff --git a/solutions/python3/653.py b/solutions/python3/653.py index 05453e4..d4cf0ca 100644 --- a/solutions/python3/653.py +++ b/solutions/python3/653.py @@ -1,14 +1,35 @@ + class Solution: def findTarget(self, root, k): """ :type root: TreeNode :type k: int :rtype: bool + + 问题描述:给定一个二叉搜索树和一个目标值 k,判断是否存在两个元素的和为 k。 + + 方法思路: + - 使用深度优先遍历(DFS)来查找满足条件的两个数。 + - 在遍历过程中,维护一个字典 dic 来记录已经访问过的节点值及其补数。 + - 如果当前节点值在字典中找到,则说明存在两个元素和为 k。 """ def traverse(node): - if not node: return False - if not node.val in dic: dic[k-node.val]=1 - else: return True + """ + 深度优先遍历二叉搜索树。 + + :param node: 当前遍历的节点 + :return: bool,表示是否找到满足条件的两个数 + """ + if not node: return False # 如果当前节点为空,则返回False + + diff = k - node.val # 计算目标值与当前节点值的差值 + if diff in dic: # 检查该差值是否存在在字典中,若存在则说明找到满足条件的两个数 + return True + else: + dic[node.val] = 1 # 将当前节点值存入字典 + + # 继续遍历左子树和右子树,只要有一个返回True即满足条件 return traverse(node.left) or traverse(node.right) - dic={} - return traverse(root) \ No newline at end of file + + dic = {} # 初始化字典用于存储已经访问过的节点值及其补数 + return traverse(root) # 开始深度优先遍历从根节点开始 diff --git a/solutions/python3/654.py b/solutions/python3/654.py index 9544c35..1946fc5 100644 --- a/solutions/python3/654.py +++ b/solutions/python3/654.py @@ -1,12 +1,17 @@ + class Solution: + # 构造最大二叉树 - 中文注释:构造一个从给定整数列表构建的最大二叉树 def constructMaximumBinaryTree(self, nums): """ - :type nums: List[int] - :rtype: TreeNode + :type nums: List[int] - 参数说明:输入的整数列表 + :rtype: TreeNode - 返回类型:根节点,构成的最大二叉树 """ if nums: + # 找到最大值及其索引 - 中文注释:找到列表中的最大值及对应的索引位置 pos = nums.index(max(nums)) - root = TreeNode(nums[pos]) - root.left = self.constructMaximumBinaryTree(nums[:pos]) + root = TreeNode(nums[pos]) # 构建当前子树的根节点 - 中文注释:以最大值构建当前子树的根节点 + # 递归调用构造左子树 - 中文注释:递归地构造根节点的左子树 + root.left = self.constructMaximumBinaryBinaryTree(nums[:pos]) + # 递归调用构造右子树 - 中文注释:递归地构造根节点的右子树 root.right = self.constructMaximumBinaryTree(nums[pos+1:]) - return root \ No newline at end of file + return root # 返回当前子树的根节点 - 中文注释:返回构建好的子树根节点 diff --git a/solutions/python3/655.py b/solutions/python3/655.py index 3e52196..5c6614f 100644 --- a/solutions/python3/655.py +++ b/solutions/python3/655.py @@ -1,24 +1,37 @@ + class Solution: def printTree(self, root): """ :type root: TreeNode :rtype: List[List[str]] """ + + # 计算树的高度(行数) def traverse(node): - if not node: return 0 + if not node: + return 0 return max(traverse(node.left), traverse(node.right)) * 2 + 1 - length = traverse(root) - stack, dic, res, padding = [root], {root : length // 2}, [], length // 2 - while any(stack): - out, tmp, padding = [""] * length, [], padding // 2 + + height = traverse(root) # 树的高度 + + # 初始化栈和字典,以及结果列表和当前填充长度 + stack, dic, res, padding = [root], {root : height // 2}, [], height // 2 + + while any(stack): # 当栈不为空时循环 + out, tmp, padding = [""] * height, [], padding // 2 + for i, node in enumerate(stack): - out[dic[node]] = str(node.val) - if node.left: + out[dic[node]] = str(node.val) # 填充当前层的节点值 + + if node.left: dic[node.left] = dic[node] - padding - 1 tmp.append(node.left) + if node.right: dic[node.right] = dic[node] + padding + 1 tmp.append(node.right) - res.append(out) + + res.append(out) # 将当前层的结果添加到结果列表中 stack = tmp - return res \ No newline at end of file + + return res # 返回最终的层次遍历结果矩阵 diff --git a/solutions/python3/656.py b/solutions/python3/656.py index bdb557d..299b3c6 100644 --- a/solutions/python3/656.py +++ b/solutions/python3/656.py @@ -1,17 +1,38 @@ + class Solution: - def cheapestJump(self, A, B): + def cheapestJump(self, A: List[int], B: int) -> List[int]: + """ + 定义一个类Solution,并在其中定义cheapestJump方法。 + 该方法接收两个参数:A为一维数组,B为正整数。 + 返回值是一个包含跳转路径的列表或空列表。 + + 英文注释: + Define a class Solution and in it define the cheapestJump method. + This method takes two parameters: A as a list of integers, B as a positive integer. + It returns a list containing the path of jumps or an empty list. + """ + n = len(A) - preMin = {n - 1:[n]} + # 初始化preMin字典,记录每个位置跳转的最小花费及其前一个位置 + preMin = {n - 1: [n]} + for i in range(n - 2, -1, -1): if A[i] == -1: continue + mn, preIndex = float("inf"), None - for ind in range(i + 1, i + B + 1 <= n and i + B + 1 or n): + # 遍历从当前位置到B步范围内,寻找最小花费及其前一个位置 + for ind in range(i + 1, min(i + B + 1, n)): if -1 < A[ind] < mn: mn, preIndex = A[ind], ind - if preIndex: + + # 如果找到了合适的前一个位置,则更新当前位置的花费和preMin字典 + if preIndex is not None: A[i] += A[preIndex] preMin[i] = preMin[preIndex] + [i + 1] else: + # 如果没有找到合适的位置,说明无法从当前位置跳跃到目标位置 A[i] = -1 - return 0 in preMin and preMin[0][::-1] or [] \ No newline at end of file + + # 返回路径列表或空列表 + return (0 in preMin and preMin[0][::-1]) or [] diff --git a/solutions/python3/657.py b/solutions/python3/657.py index 3d08980..44aa192 100644 --- a/solutions/python3/657.py +++ b/solutions/python3/657.py @@ -1,14 +1,22 @@ + class Solution: - def judgeCircle(self, moves): + def judgeCircle(self, moves: str) -> bool: """ - :type moves: str - :rtype: bool + :param moves: 包含字符 'R', 'L', 'U', 'D' 的字符串,分别代表右、左、上、下四个方向的移动 + :return: 如果最终回到原点,则返回 True;否则返回 False """ - x,y = 0, 0 + x, y = 0, 0 + # 遍历每个字符,并更新坐标 for char in moves: - if char=="R": x+=1 - if char=="L": x-=1 - if char=="U": y+=1 - if char=="D": y-=1 - return True if x==0 and y==0 else False - \ No newline at end of file + if char == "R": + x += 1 + elif char == "L": + x -= 1 + elif char == "U": + y += 1 + elif char == "D": + y -= 1 + + # 检查是否回到原点 + return (x == 0 and y == 0) + \ No newline at end of file diff --git a/solutions/python3/658.py b/solutions/python3/658.py index f55ef58..42e3bad 100644 --- a/solutions/python3/658.py +++ b/solutions/python3/658.py @@ -1,9 +1,30 @@ + class Solution: + # 定义一个类,用于解决寻找最接近目标值的k个元素问题 + def findClosestElements(self, arr, k, x): - ind, n = bisect.bisect_left(arr, x), len(arr) - if ind > 0 and x - arr[ind - 1] < arr[ind] - x: ind -= 1 - l, r = ind, ind + 1 + """ + :param arr: 列表,存储待查找的整数序列 + :type arr: List[int] + :param k: 需要返回的元素数量 + :type k: int + :param x: 目标值,寻找与该值最接近的k个元素 + :type x: int + :return: 返回包含最接近目标值x的k个整数的列表 + """ + ind, n = bisect.bisect_left(arr, x), len(arr) # 找到x在有序数组中的插入位置,同时获取数组长度 + + # 根据左右两侧与x的距离调整ind的位置 + if ind > 0 and x - arr[ind - 1] < arr[ind] - x: + ind -= 1 + + l, r = ind, ind + 1 # 初始化左右指针 + + # 寻找最接近目标值的k个元素 for _ in range(k - 1): - if r >= n or (l > 0 and x - arr[l - 1] <= arr[r] - x): l -= 1 - else: r += 1 - return arr[l:r] \ No newline at end of file + if r >= n or (l > 0 and x - arr[l - 1] <= arr[r] - x): + l -= 1 # 左指针左移 + else: + r += 1 # 右指针右移 + + return arr[l:r] # 返回结果,包含最接近x的k个元素 diff --git a/solutions/python3/659.py b/solutions/python3/659.py index 355977c..fdf5b7b 100644 --- a/solutions/python3/659.py +++ b/solutions/python3/659.py @@ -1,18 +1,33 @@ + class Solution: def isPossible(self, nums): - heap, last = [], collections.defaultdict(int) + """ + 判断给定数组是否可以分解为若干个连续子序列。 + + :param nums: List[int] - 给定的整数列表 + """ + import heapq # 引入堆模块 + + heap = [] # 初始化空堆 + last = collections.defaultdict(int) # 记录每个数字出现次数 + for num in nums: - last[num] += 1 - if heap and heap[0][0] <= num - 1: - if heap[0][0] < num - 1: + last[num] += 1 # 更新当前数字的计数 + + if heap and heap[0][0] <= num - 1: # 堆顶元素小于等于当前数字减一 + if heap[0][0] < num - 1: # 如果堆顶元素小于当前数字减一,无法形成连续子序列 return False else: - last[num - 1] -= 1 - n, l = heapq.heappop(heap) - if l == -1: - heapq.heappush(heap, (num, -2)) - elif num - 1 not in last or not last[num - 1]: - heapq.heappush(heap, (num, -1)) + last[num - 1] -= 1 # 更新前一个数字的计数 + n, l = heapq.heappop(heap) # 弹出堆顶元素 + if l == -1: # 如果该元素已被使用完 + heapq.heappush(heap, (num, -2)) # 将其更新为-2,表示已结束 + else: + heapq.heappush(heap, (n + 1, l - 1)) # 更新堆顶元素的值和计数 + + elif num - 1 not in last or not last[num - 1]: # 如果前一个数字不存在或数量为0 + heapq.heappush(heap, (num, -1)) # 将当前数字加入堆中,标记未使用状态 else: - last[num - 1] -= 1 - return not heap \ No newline at end of file + last[num - 1] -= 1 # 更新前一个数字的计数 + + return not heap # 如果最终堆为空,则表示所有元素都能形成连续子序列 diff --git a/solutions/python3/66.py b/solutions/python3/66.py index 22f4af5..894f1c3 100644 --- a/solutions/python3/66.py +++ b/solutions/python3/66.py @@ -1,3 +1,15 @@ + class Solution: - def plusOne(self, digits, add = 1): - return add and [1] or [] if not digits else self.plusOne(digits[:-1], +(digits[-1] + add > 9)) + [(digits[-1] + add) % 10] \ No newline at end of file + # 定义一个类Solution,用于处理数字加一的问题 + + def plusOne(self, digits, add=1): + # 定义一个方法plusOne,接收参数digits(数字列表)和add默认值为1 + + return [1] if not digits and add else [] # 如果digits为空且add不为0,则返回[1] + + # 递归处理剩余的数字 + return self.plusOne(digits[:-1], +(digits[-1] + add > 9)) + [(digits[-1] + add) % 10] + + # 优化:使用条件表达式简化代码逻辑 + return [1] if not digits else (self.plusOne(digits[:-1], +(digits[-1] + add > 9)) + + [(digits[-1] + add) % 10]) diff --git a/solutions/python3/660.py b/solutions/python3/660.py index 50b703f..3e7df8f 100644 --- a/solutions/python3/660.py +++ b/solutions/python3/660.py @@ -1,7 +1,16 @@ + class Solution: - def newInteger(self, n): + # 新建一个类,用于处理进制转换 + + def newInteger(self, n: int) -> int: + # 将十进制整数n转换为九进制字符串表示 + base9 = "" while n: + # 计算当前数字除以9的余数,并将其转换为字符形式添加到base9中 base9 += str(n % 9) + # 整除操作,减少当前处理的数值 n //= 9 - return int(base9[::-1]) \ No newline at end of file + + # 返回九进制字符串反转后的整数值 + return int(base9[::-1]) diff --git a/solutions/python3/661.py b/solutions/python3/661.py index f2c8232..d45535a 100644 --- a/solutions/python3/661.py +++ b/solutions/python3/661.py @@ -1,11 +1,22 @@ + class Solution: def imageSmoother(self, M: List[List[int]]) -> List[List[int]]: - m, n = len(M), len(M[0]) - grid = [[0] * n for _ in range(m)] + """ + 定义一个类来处理图像平滑操作 + + :param M: 输入的二维整数数组,表示原始图像 + :return: 返回经过平滑处理后的二维数组 + """ + + m, n = len(M), len(M[0]) # 获取矩阵的行数和列数 + grid = [[0] * n for _ in range(m)] # 初始化结果矩阵 + + # 遍历原始图像中的每一个像素点 for i in range(m): for j in range(n): - adj = [M[i + x][j + y] for x, y in ((0, 0), (-1, 0), (1, 0), (0, -1), (0, 1), (-1, -1), (-1, 1), (1, 1), (1, -1)) if 0 <= i + x < m and 0 <= j + y < n] + # 计算当前像素点及其邻域的有效像素值列表 + adj = [M[i + x][j + y] for x, y in ((0, 0), (-1, 0), (1, 0), (0, -1), (0, 1), (-1, -1), (-1, 1), (1, 1), (1, -1)) if 0 <= i + x < m and 0 <= j + y < n] + # 将邻域平均值赋给结果矩阵中的对应位置 grid[i][j] = sum(adj) // len(adj) - return grid - - \ No newline at end of file + + return grid # 返回处理后的图像矩阵 diff --git a/solutions/python3/662.py b/solutions/python3/662.py index 99954c7..8bd7060 100644 --- a/solutions/python3/662.py +++ b/solutions/python3/662.py @@ -1,15 +1,24 @@ + class Solution: def widthOfBinaryTree(self, root): """ :type root: TreeNode :rtype: int + + 英文注释:Given a binary tree, the function calculates and returns the maximum width of the tree. The width is defined as the largest number of nodes in any level of the tree. + + 中文注释:给定一个二叉树,函数计算并返回该二叉树的最大宽度。宽度定义为树中任意一层的最大节点数。 """ dic, stack, res = {root: 1}, [root], 0 + # 使用广度优先搜索遍历整棵树 while any(stack): - tmp, mn ,mx = [], float("inf"), - float("inf") + tmp, mn, mx = [], float("inf"), -float("inf") for node in stack: - res = max(res, dic[stack[-1]] - dic[stack[0]] + 1) - if node.left: tmp, dic[node.left] = tmp + [node.left], dic[node] * 2 - 1 - if node.right: tmp, dic[node.right] = tmp + [node.right], dic[node] * 2 + # 更新当前层的最大宽度 + res = max(res, dic[stack[-1]] - dic[stack[0]] + 1) + if node.left: + tmp, dic[node.left] = tmp + [node.left], dic[node] * 2 - 1 + if node.right: + tmp, dic[node.right] = tmp + [node.right], dic[node] * 2 stack = tmp - return res \ No newline at end of file + return res diff --git a/solutions/python3/663.py b/solutions/python3/663.py index 72bc855..c3063af 100644 --- a/solutions/python3/663.py +++ b/solutions/python3/663.py @@ -1,20 +1,29 @@ + # Definition for a binary tree node. -# class TreeNode: -# def __init__(self, x): -# self.val = x -# self.left = None -# self.right = None +class TreeNode: + def __init__(self, x): + self.val = x + self.left = None + self.right = None class Solution: - def checkEqualTree(self, root): + # 检查是否可以将二叉树分成两部分,使得每部分的节点值之和相等 + def checkEqualTree(self, root: TreeNode) -> bool: nodeSum = collections.defaultdict(int) + + # 深度优先搜索计算每个子树的总和,并记录在字典中 def dfs(node): - if not node: + if not node: return 0 sm = node.val + dfs(node.left) + dfs(node.right) nodeSum[sm] += 1 return sm + totalSum = dfs(root) + + # 如果总和为零,检查是否存在两个节点值之和为零的情况 if not totalSum: return nodeSum[0] > 1 - return totalSum % 2 == 0 and totalSum // 2 in nodeSum \ No newline at end of file + + # 检查总和是否能被2整除,并且半数的值在字典中存在 + return totalSum % 2 == 0 and totalSum // 2 in nodeSum diff --git a/solutions/python3/664.py b/solutions/python3/664.py index bcbf4ef..77dab8c 100644 --- a/solutions/python3/664.py +++ b/solutions/python3/664.py @@ -1,13 +1,36 @@ + class Solution: - def strangePrinter(self, s): + def strangePrinter(self, s: str) -> int: + """ + Strange Printer problem solution. + + 参数: + s (str): 输入字符串 + + 返回: + int: 打印s所需最少操作次数 + """ memo = {} - def dp(i, j): - if i > j: return 0 + + def dp(i: int, j: int) -> int: + """ + Dynamic programming function to calculate minimum operations needed. + + 参数: + i (int): 起始索引 + j (int): 结束索引 + + 返回: + int: 从i到j所需的最少操作次数 + """ + if i > j: + return 0 if (i, j) not in memo: - ans = dp(i+1, j) + 1 - for k in range(i+1, j+1): + ans = dp(i + 1, j) + 1 + for k in range(i + 1, j + 1): if s[k] == s[i]: - ans = min(ans, dp(i, k-1) + dp(k+1, j)) + ans = min(ans, dp(i, k - 1) + dp(k + 1, j)) memo[i, j] = ans return memo[i, j] - return dp(0, len(s) - 1) \ No newline at end of file + + return dp(0, len(s) - 1) diff --git a/solutions/python3/665.py b/solutions/python3/665.py index 0889b48..bcd904e 100644 --- a/solutions/python3/665.py +++ b/solutions/python3/665.py @@ -1,12 +1,28 @@ + class Solution: + # 类:Solution + def checkPossibility(self, nums): """ - :type nums: List[int] - :rtype: bool - """ + :type nums: List[int] # 输入类型:整数列表 + :rtype: bool # 返回类型:布尔值 + + 目标:检查给定的整数列表是否可以通过修改最多一个元素使其变为非递减序列。 + 策略: + - 遍历整个列表,寻找首次出现的不满足条件的位置 i 使得 nums[i] > nums[i+1] + - 尝试两种可能的修正方案:(i) 删除 nums[i] (ii) 删除 nums[i+1] + - 检查这两种修正后的序列是否为非递减 + """ + for i in range(len(nums)-1): - if nums[i]>nums[i+1]: - mod1, mod2=list(nums), list(nums) - mod1[i], mod2[i+1]=mod1[i+1], mod2[i] - if mod1!=sorted(mod1) and mod2!=sorted(mod2): return False - return True \ No newline at end of file + if nums[i] > nums[i+1]: + # 两种修正尝试 + mod1, mod2 = list(nums), list(nums) + mod1[i], mod2[i+1] = mod1[i+1], mod2[i] + + # 检查是否可以通过删除一个元素使其变为非递减序列 + if sorted(mod1) != mod1 and sorted(mod2) != mod2: + return False + + # 如果未发现违反规则的情况,返回 True + return True diff --git a/solutions/python3/666.py b/solutions/python3/666.py index 6dad0df..55eb61d 100644 --- a/solutions/python3/666.py +++ b/solutions/python3/666.py @@ -1,7 +1,20 @@ + class Solution: def pathSum(self, nums): - dp = {(0, 1) : 0} + """ + 初始化动态规划表,用于存储路径和 + :param nums: List[int] + :return: int + """ + # 使用字典dp来存储每个节点的路径和 + dp = {(0, 1): 0} + for num in nums: + # 将数字转换为元组(d, p) d, p, v = map(int, str(num)) + + # 更新当前节点的路径和 dp[(d, p)] = v + dp[(d - 1, (p + 1) // 2)] - return sum(dp[k] for k in dp if (k[0] + 1, k[1] * 2) not in dp and (k[0] + 1, k[1] * 2 - 1) not in dp) \ No newline at end of file + + # 计算符合条件的叶子节点的路径和总和 + return sum(dp[k] for k in dp if (k[0] + 1, k[1] * 2) not in dp and (k[0] + 1, k[1] * 2 - 1) not in dp) diff --git a/solutions/python3/667.py b/solutions/python3/667.py index d0337d9..5bf4528 100644 --- a/solutions/python3/667.py +++ b/solutions/python3/667.py @@ -1,19 +1,28 @@ + class Solution: - def constructArray(self, n, k): + def constructArray(self, n: int, k: int) -> list[int]: """ - :type n: int - :type k: int - :rtype: List[int] + 构造一个长度为n的数组,使得相邻元素之差尽可能大。 + + :param n: 数组长度 + :param k: 最大允许的最大差值次数 + :return: 满足条件的数组 """ left, right, res = 0, n+1, [None]*n for i in range(n): + # 如果最大差值k已经用完,填充剩余位置为递增序列 if k == 1: - if i%2 == 0: - while i int: + """ + 使用二分查找来确定满足条件的最小值。 + + Use binary search to determine the smallest value that satisfies the condition. + :param m: 行数 + :param n: 列数 + :param k: 需要找到的第k个数 + :return: 满足条件的最小整数值 + """ + + # 初始化二分查找的左右边界 l, r = 1, m * n + while l < r: mid = (l + r) // 2 + + # 计算mid在给定矩阵中的出现次数 if sum(min(mid // i, n) for i in range(1, m + 1)) < k: + # 如果总数小于k,说明mid太小了,需要增大左边界 l = mid + 1 else: + # 否则缩小右边界到mid r = mid - return l \ No newline at end of file + + return l diff --git a/solutions/python3/669.py b/solutions/python3/669.py index 2b0a591..9a2ca4f 100644 --- a/solutions/python3/669.py +++ b/solutions/python3/669.py @@ -1,20 +1,27 @@ + # Definition for a binary tree node. -# class TreeNode: -# def __init__(self, x): -# self.val = x -# self.left = None -# self.right = None +class TreeNode: + def __init__(self, x): + self.val = x + self.left = None + self.right = None class Solution: - def trimBST(self, root, L, R): - """ - :type root: TreeNode - :type L: int - :type R: int - :rtype: TreeNode - """ - if not root: return - root.left=self.trimBST(root.left,L,R) - root.right=self.trimBST(root.right,L,R) - if root.val>R or root.val 'TreeNode': + if not root: + return + + # 递归处理左子树和右子树 + root.left = self.trimBST(root.left, L, R) + root.right = self.trimBST(root.right, L, R) + + # 如果当前节点值不在[L, R]范围内,则返回其符合条件的子节点 + if root.val > R or root.val < L: + return root.left if root.left else root.right + + return root diff --git a/solutions/python3/67.py b/solutions/python3/67.py index e5a4870..4614315 100644 --- a/solutions/python3/67.py +++ b/solutions/python3/67.py @@ -1,3 +1,12 @@ + class Solution: + # 将二进制字符串a和b相加并返回结果的二进制表示形式 def addBinary(self, a: str, b: str) -> str: - return bin(int(a, 2) + int(b, 2))[2:] \ No newline at end of file + return bin(int(a, 2) + int(b, 2))[2:] # 直接转换为十进制后相加,再转回二进制去除前缀'0b' + + + +class Solution: + # 将二进制字符串a和b相加并返回结果的二进制表示形式 + def addBinary(self, a: str, b: str) -> str: + return bin(int(a, 2) + int(b, 2))[2:] # 直接转换为十进制后相加,再转回二进制去除前缀'0b' diff --git a/solutions/python3/670.py b/solutions/python3/670.py index 3a7af00..1620361 100644 --- a/solutions/python3/670.py +++ b/solutions/python3/670.py @@ -1,9 +1,19 @@ + class Solution: + # 定义一个类来解决最大交换问题 + def maximumSwap(self, num): + # 将输入数字转换为列表,方便操作 res, num = num, list(str(num)) + + # 遍历数字的每一位,寻找最大的交换机会 for i in range(len(num) - 1): for j in range(i + 1, len(num)): if int(num[j]) > int(num[i]): + # 构建新的数字,并与当前最大值比较 tmp = int("".join(num[:i] + [num[j]] + num[i + 1:j] + [num[i]] + num[j + 1:])) - if tmp > res: res = tmp - return res \ No newline at end of file + if tmp > res: + res = tmp + + return res # 返回最终的最大交换结果 + diff --git a/solutions/python3/671.py b/solutions/python3/671.py index 248695f..1ae66b8 100644 --- a/solutions/python3/671.py +++ b/solutions/python3/671.py @@ -1,18 +1,30 @@ + # Definition for a binary tree node. -# class TreeNode: -# def __init__(self, x): -# self.val = x -# self.left = None -# self.right = None +class TreeNode: + def __init__(self, x): + self.val = x + self.left = None + self.right = None class Solution: + # 寻找二叉树的第二小值 def findSecondMinimumValue(self, root: TreeNode) -> int: + # 初始化最小值为正无穷大 self.sec = float('inf') + + # 深度优先搜索函数 def dfs(node): - if not node: return + if not node: + return + # 递归遍历左右子树 dfs(node.left) dfs(node.right) + # 更新第二小值 if root.val < node.val < self.sec: self.sec = node.val + + # 开始深度优先搜索 dfs(root) - return self.sec if self.sec < float('inf') else -1 \ No newline at end of file + + # 如果没有找到更小的值,返回-1 + return self.sec if self.sec < float('inf') else -1 diff --git a/solutions/python3/672.py b/solutions/python3/672.py index 3b1d177..58ab554 100644 --- a/solutions/python3/672.py +++ b/solutions/python3/672.py @@ -1,4 +1,16 @@ + class Solution: - def flipLights(self, n, m): + # 定义解决方案类 + + def flipLights(self, n: int, m: int) -> int: + """ + :param n: 灯的数量 (最多考虑3个灯的情况) + :param m: 操作次数 + :return: 不同的开关组合数量 + """ + + # 只有当灯的数量不超过3时,才进行详细计算 n = min(n, 3) - return min(1 << n, 1 + m * n) \ No newline at end of file + + # 计算不同的开关组合数:最多2^3种组合,加上多次操作后的额外组合数(这里假设为1+m*n) + return min(1 << n, 1 + m * n) diff --git a/solutions/python3/673.py b/solutions/python3/673.py index 880494b..404092d 100644 --- a/solutions/python3/673.py +++ b/solutions/python3/673.py @@ -1,10 +1,33 @@ + class Solution: + # 寻找最长递增子序列的数量 + def findNumberOfLIS(self, nums): - dp = [[1, 1] for _ in range(len(nums))] + """ + :param nums: List[int] + :return: int + + 使用动态规划记录每个位置的最长递增子序列长度及其数量。 + 1. dp[j][0] 表示以 j 结尾的 LIS 长度 + dp[j][1] 表示以 j 结尾且长度为 dp[j][0] 的 LIS 的数量 + + 对于每一个 nums[i],遍历其后续元素 nums[j] (j > i): + - 如果 nums[j] > nums[i],说明可以构成递增子序列 + 更新 dp[j]:如果当前以 i 结尾的 LIS 长度大于等于 j 位置的,则更新长度和数量 + 如果当前以 i 结尾的 LIS 长度加一等于 j 位置的,则增加数量 + + 最后,将所有 LIS 的长度排序并返回最长递增子序列的数量 + """ + + dp = [[1, 1] for _ in range(len(nums))] # 初始化动态规划表 for i in range(len(nums) - 1): for j in range(i + 1, len(nums)): if nums[j] > nums[i]: - if dp[i][0] >= dp[j][0]: dp[j] = [dp[i][0] + 1, dp[i][1]] - elif dp[i][0] == dp[j][0] - 1: dp[j][1] += dp[i][1] + if dp[i][0] >= dp[j][0]: + dp[j] = [dp[i][0] + 1, dp[i][1]] + elif dp[i][0] == dp[j][0] - 1: + dp[j][1] += dp[i][1] + + # 排序后计算结果 dp.sort() - return dp and sum(d[1] for d in dp if d[0] == dp[-1][0]) or 0 \ No newline at end of file + return sum(d[1] for d in dp if d[0] == dp[-1][0]) or 0 diff --git a/solutions/python3/674.py b/solutions/python3/674.py index d7e64b4..f3639f2 100644 --- a/solutions/python3/674.py +++ b/solutions/python3/674.py @@ -1,12 +1,19 @@ + class Solution: def findLengthOfLCIS(self, nums): """ - :type nums: List[int] - :rtype: int + :type nums: List[int] # 输入参数,整数列表 + :rtype: int # 返回类型,最长连续递增子序列的长度 """ - if nums==[]: return 0 - curr, mx=1, 1 - for i in range(len(nums)-1): - if nums[i+1]>nums[i]: curr+=1; mx=max(mx,curr) - else: curr=1 - return mx \ No newline at end of file + if not nums: return 0 # 如果输入列表为空,返回0 + + curr, mx = 1, 1 # 初始化当前计数和最大值为1 + + for i in range(len(nums) - 1): # 遍历整个列表(除了最后一个元素) + if nums[i + 1] > nums[i]: # 如果后一个数字大于前一个数字 + curr += 1 # 当前计数加1 + mx = max(mx, curr) # 更新最大值 + else: + curr = 1 # 重置当前计数为1 + + return mx # 返回最长连续递增子序列的长度 diff --git a/solutions/python3/675.py b/solutions/python3/675.py index 72588ed..813ad17 100644 --- a/solutions/python3/675.py +++ b/solutions/python3/675.py @@ -1,29 +1,42 @@ + class Solution: + # 定义广度优先搜索函数来计算从起点到终点的最短路径(考虑障碍) + def hadlocks(self, forest, sr, sc, tr, tc): + R, C = len(forest), len(forest[0]) # 获取森林的行数和列数 + processed = set() # 已访问集合 + deque = collections.deque([(0, sr, sc)]) # 初始化队列,包含起始位置及其步数 + + while deque: + detours, r, c = deque.popleft() # 弹出最近的节点和步数 + if (r, c) not in processed: # 如果当前节点未被访问过 + processed.add((r, c)) # 标记为已访问 + + # 检查是否到达目标位置,如果是,则返回已走过的步数及剩余路径长度 + if r == tr and c == tc: + return abs(sr - tr) + abs(sc - tc) + 2 * detours + + # 遍历四个方向的邻接节点 + for nr, nc, closer in ((r-1, c, r > tr), (r+1, c, r < tr), + (r, c-1, c > tc), (r, c+1, c < tc)): + if 0 <= nr < R and 0 <= nc < C and forest[nr][nc]: # 检查边界和是否为障碍 + if closer: # 如果是更接近目标的节点 + deque.appendleft((detours, nr, nc)) + else: + deque.append((detours + 1, nr, nc)) # 否则,增加步数并加入队列 + + return -1 # 搜索未成功找到路径时返回-1 + + # 主函数用于计算砍伐所有树所需的最短时间 def cutOffTree(self, forest): - def hadlocks(forest, sr, sc, tr, tc): - R, C = len(forest), len(forest[0]) - processed = set() - deque = collections.deque([(0, sr, sc)]) - while deque: - detours, r, c = deque.popleft() - if (r, c) not in processed: - processed.add((r, c)) - if r == tr and c == tc: - return abs(sr-tr) + abs(sc-tc) + 2*detours - for nr, nc, closer in ((r-1, c, r > tr), (r+1, c, r < tr), - (r, c-1, c > tc), (r, c+1, c < tc)): - if 0 <= nr < R and 0 <= nc < C and forest[nr][nc]: - if closer: - deque.appendleft((detours, nr, nc)) - else: - deque.append((detours+1, nr, nc)) - return -1 trees = sorted((v, r, c) for r, row in enumerate(forest) - for c, v in enumerate(row) if v > 1) - sr = sc = ans = 0 - for _, tr, tc in trees: - d = hadlocks(forest, sr, sc, tr, tc) - if d < 0: return -1 - ans += d - sr, sc = tr, tc - return ans \ No newline at end of file + for c, v in enumerate(row) if v > 1) # 将所有树木的位置按高度排序 + + sr = sc = ans = 0 # 起点位置 + for _, tr, tc in trees: # 遍历每棵树的位置 + d = self.hadlocks(forest, sr, sc, tr, tc) # 计算从当前起点到该树的最短路径 + if d < 0: return -1 # 如果无法到达,则返回-1 + + ans += d # 累加路径长度 + sr, sc = tr, tc # 更新起始位置为上一棵树的位置 + + return ans # 返回总耗时 diff --git a/solutions/python3/676.py b/solutions/python3/676.py index 2a218d2..72dd6a4 100644 --- a/solutions/python3/676.py +++ b/solutions/python3/676.py @@ -1,33 +1,40 @@ + +from collections import defaultdict + class MagicDictionary: def __init__(self): """ - Initialize your data structure here. + 初始化数据结构。 """ - from collections import defaultdict + # 使用defaultdict来存储修改后的单词和其被替换的字符 self.var = defaultdict(set) def buildDict(self, dict): """ - Build a dictionary through a list of words - :type dict: List[str] - :rtype: void + 通过一个单词列表构建字典。 + :param dict: List[str] - 包含要添加到字典中的单词列表。 + :return: None """ for w in dict: - for i in range(len(w)): self.var[(i, w[:i] + w[i + 1:])].add(w[i]) - + for i in range(len(w)): + # 将每个字符替换为'_',并记录该位置的被替换单词 + self.var[(i, w[:i] + '_' + w[i + 1:])].add(w[i]) + def search(self, word): """ - Returns if there is any word in the trie that equals to the given word after modifying exactly one character - :type word: str - :rtype: bool + 检查是否可以通过修改一个字符使得单词与字典中的任何一个单词匹配。 + :param word: str - 要查找的单词 + :return: bool - 是否存在这样的单词 """ - for i in range(len(word)): - if self.var[(i, word[:i] + word[i + 1:])] - {word[i]}: return True + for i in range(len(word)): + # 替换当前字符,检查是否有其他字符可以替换它 + if self.var[(i, word[:i] + '_' + word[i + 1:])] - {word[i]}: + return True return False -# Your MagicDictionary object will be instantiated and called as such: +# 初始化MagicDictionary对象并调用相关方法 # obj = MagicDictionary() # obj.buildDict(dict) -# param_2 = obj.search(word) \ No newline at end of file +# param_2 = obj.search(word) diff --git a/solutions/python3/677.py b/solutions/python3/677.py index aef8b25..e9205c4 100644 --- a/solutions/python3/677.py +++ b/solutions/python3/677.py @@ -1,32 +1,38 @@ + class MapSum: def __init__(self): """ - Initialize your data structure here. + 初始化数据结构。 """ from collections import defaultdict self.dic = defaultdict(int) - def insert(self, key, val): + def insert(self, key: str, val: int) -> None: """ - :type key: str - :type val: int - :rtype: void + 插入键值对 (key, val)。 + + :param key: str - 要插入的键 + :param val: int - 对应的值 + :return: 无返回值 """ self.dic[key] = val - def sum(self, prefix): + def sum(self, prefix: str) -> int: """ - :type prefix: str - :rtype: int + 计算所有以给定前缀开头的键对应的值之和。 + + :param prefix: str - 给定的前缀 + :return: int - 符合条件的所有键对应的值之和 """ sm = 0 for k in self.dic: - if k[:len(prefix)] == prefix: sm += self.dic[k] + if k[:len(prefix)] == prefix: + sm += self.dic[k] return sm # Your MapSum object will be instantiated and called as such: # obj = MapSum() # obj.insert(key,val) -# param_2 = obj.sum(prefix) \ No newline at end of file +# param_2 = obj.sum(prefix) diff --git a/solutions/python3/678.py b/solutions/python3/678.py index 6712929..6cbaa3b 100644 --- a/solutions/python3/678.py +++ b/solutions/python3/678.py @@ -1,15 +1,33 @@ + class Solution: def checkValidString(self, s): """ :type s: str :rtype: bool """ + # 使用两个栈分别存储左括号和星号的位置信息,方便后续匹配 + # Chinese: 使用两个栈分别存储左括号和星号的位置信息,方便后续匹配 left, left_star = [], [] + for i in range(len(s)): - if s[i] == "(": left.append([s[i], i]) - elif s[i] == "*": left_star.append([s[i], i]) - elif left and left[-1][0] == "(": left.pop() - elif left_star: left_star.pop() - else: return False - while left and left_star and left[-1][1]< left_star[-1][1]: left.pop(); left_star.pop() - return not left \ No newline at end of file + if s[i] == "(": # 遇到左括号时记录其位置 + # Chinese: 遇到左括号时记录其位置 + left.append([s[i], i]) + elif s[i] == "*": # 遇到星号时记录其位置 + # Chinese: 遇到星号时记录其位置 + left_star.append([s[i], i]) + elif left and left[-1][0] == "(": # 如果当前是右括号且栈顶元素为左括号,匹配成功出栈 + # Chinese: 如果当前是右括号且栈顶元素为左括号,匹配成功出栈 + left.pop() + elif left_star: # 使用星号进行匹配 + # Chinese: 使用星号进行匹配 + left_star.pop() + else: + return False + + # 处理剩余未匹配的左括号和星号 + while left and left_star and left[-1][1] < left_star[-1][1]: # 确保星号在左括号之后用于填充 + # Chinese: 处理剩余未匹配的左括号和星号,确保星号在左括号之后用于填充 + left.pop(); left_star.pop() + + return not left # 如果所有左括号都被匹配,则返回True diff --git a/solutions/python3/679.py b/solutions/python3/679.py index 6d931e5..8f140c2 100644 --- a/solutions/python3/679.py +++ b/solutions/python3/679.py @@ -1,24 +1,46 @@ + class Solution: + # 判断给定的数字列表是否可以通过加、减、乘、除得到接近24的结果 + def judgePoint24(self, nums): - q = [[None, nums[i]] + nums[:i] + nums[i + 1:] for i in range(len(nums))] + from collections import deque + + # 初始化队列,每个元素是一个操作后的数对和剩余未处理的数列表 + q = deque([[None, nums[i]] + nums[:i] + nums[i + 1:] for i in range(len(nums))]) + while q: new = [] + + # 遍历当前队列中的每个元素 for group1, group2, *rest in q: - if not rest and group1: - for res in (group1 + group2, group1 - group2, group1 * group2, group2 and group1 / group2): - if 23.999 <= res <= 24.0001: return True - if not rest and not group1 and 23.999 <= group2 <= 24.0001: return True + if not rest and group1: # 如果剩余列表为空且第一个数非空,尝试四则运算 + for res in (group1 + group2, group1 - group2, group1 * group2, group2 and group1 / group2): + if 23.999 <= res <= 24.0001: + return True + + if not rest and not group1 and 23.999 <= group2 <= 24.0001: # 如果剩余列表为空且第一个数非空,直接返回True + return True + for i in range(len(rest)): + # 处理剩余列表中的每个数字与group2的四则运算 for newGroup2 in (group2 + rest[i], group2 - rest[i], rest[i] - group2, group2 * rest[i], group2 / rest[i]): new.append([group1, newGroup2] + rest[:i] + rest[i + 1:]) + if group2: + # 处理剩余列表中的每个数字与除法 new.append([group1, rest[i] / group2] + rest[:i] + rest[i + 1:]) - if group1 != None: + + if group1 is not None: for newGroup1 in (group1 + group2, group1 - group2, group1 * group2): new.append([newGroup1, rest[i]] + rest[:i] + rest[i + 1:]) + if group2: + # 处理除法 new.append([group1 / group2, rest[i]] + rest[:i] + rest[i + 1:]) + else: new.append([group2, rest[i]] + rest[:i] + rest[i + 1:]) + q = new - return False \ No newline at end of file + + return False diff --git a/solutions/python3/68.py b/solutions/python3/68.py index 6172532..d09919c 100644 --- a/solutions/python3/68.py +++ b/solutions/python3/68.py @@ -1,15 +1,30 @@ + class Solution: def fullJustify(self, words: List[str], maxWidth: int) -> List[str]: + """ + 解决方案类,包含全对齐文本的实现。 + + :param words: 一个字符串列表,表示单词列表 + :param maxWidth: 整数,表示每一行的最大宽度 + :return: 返回格式化后的字符串列表 + """ res, used, s = [], 0, [] + + # 遍历每一个单词 for i, w in enumerate(words): if not s or len(w) + used + len(s) <= maxWidth: + # 当前行还可以容纳当前单词,则添加到当前行中 used += len(w) s += [w] else: + # 如果当前行已满,处理当前行内容,并重置用于下一行 if len(s) == 1: res.append(s[0] + (maxWidth - used) * ' ') else: br = (maxWidth - used) // (len(s) - 1) + # 计算空格数,分配到各单词间 res.append(''.join((br + (i <= (maxWidth - used) % (len(s) - 1))) * ' ' + c for i, c in enumerate(s)).lstrip()) used, s = len(w), [w] - return res + [' '.join(c for c in s) + (maxWidth - used - len(s) + 1) * ' '] \ No newline at end of file + + # 处理最后一行左对齐且尾部填充空格 + return res + [' '.join(c for c in s) + (maxWidth - used - len(s) + 1) * ' '] diff --git a/solutions/python3/680.py b/solutions/python3/680.py index d39516c..3cc2d9f 100644 --- a/solutions/python3/680.py +++ b/solutions/python3/680.py @@ -1,27 +1,52 @@ + class Solution: def validPalindrome(self, s): """ :type s: str :rtype: bool """ + + # 使用字典 memo 存储已经计算过的状态,避免重复计算 memo = {} + def dfs(l, r, cnt): + """ + :param l: 当前检查的左边界索引 + :param r: 当前检查的右边界索引 + :param cnt: 已经替换的字符个数 + :return: 是否可以通过至多一次删除变成回文串 + """ + + # 如果当前状态已经计算过,直接返回结果 if (l, r, cnt) in memo: return memo[(l, r, cnt)] + + # 如果左边界已经大于等于右边界,说明已经检查完一个完整区间 if l >= r: return True + + # 当前字符不相等时,尝试删除一个字符并递归检查剩余部分 elif s[l] != s[r]: cnt += 1 + # 如果已经超过一次替换,则直接返回 False if cnt > 1: memo[(l, r, cnt)] = False return False - elif (s[l + 1] == s[r] and dfs(l + 1, r, cnt + 1)) or (s[l] == s[r - 1] and dfs(l, r - 1, cnt + 1)): + + # 尝试两种删除方式:分别从左右两边删除一个字符并递归检查 + elif (s[l + 1] == s[r] and dfs(l + 1, r, cnt)) or (s[l] == s[r - 1] and dfs(l, r - 1, cnt)): memo[(l, r, cnt)] = True return True + else: + # 如果两种删除方式都不成立,则返回 False memo[(l, r, cnt)] = False return False + + # 当前字符相等时,继续向内检查下一组字符 else: memo[(l, r, cnt)] = dfs(l + 1, r - 1, cnt) return memo[(l, r, cnt)] - return dfs(0, len(s) - 1, 0) \ No newline at end of file + + # 从整个字符串的两端开始递归判断 + return dfs(0, len(s) - 1, 0) diff --git a/solutions/python3/681.py b/solutions/python3/681.py index a2f00ff..6d67889 100644 --- a/solutions/python3/681.py +++ b/solutions/python3/681.py @@ -1,13 +1,28 @@ + class Solution: + # 定义一个解决方案类,用于解决下一个最接近的时间问题 + def nextClosestTime(self, time): - t = sorted(set(time))[:-1] + # 将时间字符串转换为字符集,并按字典序排序后去掉最后一个元素 + t = sorted(set(time))[:-1] + + # 构建一个映射字典nex,其中key为字符集中的字符,value为其后面的那个字符(如果存在) nex = {a: b for a, b in zip(t, t[1:])} + + # 从右到左遍历时间字符串 for i, d in enumerate(time[::-1]): if d in nex: + # 如果当前字符有下一个可用的字符替换 + if i == 0: + # 如果当前是秒位,则直接替换为nex[d]并返回结果 return time[:4] + nex[d] elif i == 1 and nex[d] < '6': + # 如果当前是分钟十位,且下一个可用的字符小于'6',则替换为nex[d]并补上最小的小时位 return time[:3] + nex[d] + t[0] elif i == 3 and int(time[0] + nex[d]) < 24: + # 如果当前是分钟个位且替换后的时间小于24,则替换为nex[d]并保持原小时位不变 return time[0] + nex[d] + ':' + t[0] * 2 - return t[0] * 2 + ':' + t[0] * 2 \ No newline at end of file + + # 若未找到合适替换,返回最小的合法时间 + return t[0] * 2 + ':' + t[0] * 2 diff --git a/solutions/python3/682.py b/solutions/python3/682.py index 70e0401..4739f8b 100644 --- a/solutions/python3/682.py +++ b/solutions/python3/682.py @@ -1,15 +1,26 @@ + class Solution: def calPoints(self, ops: List[str]) -> int: - arr = [] + """ + 计算得分。 + + 参数: + ops (List[str]): 操作列表,包含数字、'C'(取消最后一个操作)、'D'(双倍上一个操作)和 '+'(上两个操作之和) + + 返回: + int: 最终得分 + """ + arr = [] # 存储当前的操作结果 + for op in ops: - #print(arr) - if op.isdigit() or op[0] == '-': + # 判断当前操作是数字或者负数 + if op.isdigit() or (op[0] == '-' and len(op) > 1): arr.append(int(op)) - elif op == 'C' and arr: + elif op == 'C' and arr: # 取消最后一个操作 arr.pop() - elif op == 'D' and arr: + elif op == 'D' and arr: # 双倍上一个操作 arr.append(arr[-1] * 2) - elif len(arr) >= 2: + elif len(arr) >= 2: # 上两个操作之和 arr.append(arr[-1] + arr[-2]) - #print(arr) - return sum(arr) \ No newline at end of file + + return sum(arr) # 返回最终得分 diff --git a/solutions/python3/684.py b/solutions/python3/684.py index 8f9c905..50aa8ce 100644 --- a/solutions/python3/684.py +++ b/solutions/python3/684.py @@ -1,23 +1,31 @@ + class Solution: + # 定义并查集类 def findRedundantConnection(self, edges: List[List[int]]) -> List[int]: - parent = [0] * len(edges) + # 初始化parent数组,用于记录每个节点的父节点 + parent = [0] * len(edges) + + # 查找操作:找到某个节点的根节点 + def find(x): + if parent[x] == 0: + return x + # 路径压缩优化 + parent[x] = find(parent[x]) + return parent[x] - def find(x): - if parent[x] == 0: - return x - parent[x] = find(parent[x]) - return parent[x] + # 合并操作:将两个集合合并,返回是否成功 + def union(x, y): + rootX = find(x) + rootY = find(y) + if rootX == rootY: + return False + # 将x的根节点指向y的根节点 + parent[rootX] = rootY + return True - def union(x, y): - rootX = find(x) - rootY = find(y) - if rootX == rootY: - return False - parent[rootX] = rootY - return True - - res = [0, 0] - for x, y in edges: - if not union(x - 1, y - 1): - res = [x, y] - return res \ No newline at end of file + res = [0, 0] + for x, y in edges: + # 如果合并失败,说明存在冗余连接 + if not union(x - 1, y - 1): + res = [x, y] + return res diff --git a/solutions/python3/685.py b/solutions/python3/685.py index a1f167b..a850fe4 100644 --- a/solutions/python3/685.py +++ b/solutions/python3/685.py @@ -1,19 +1,28 @@ + class Solution: def findRedundantDirectedConnection(self, edges): + # 获取节点的根节点 def root(i): - return parent[i] == i and i or root(parent[i]) + return parent[i] if parent[i] == i else root(parent[i]) + # 初始化父节点数组、候选A、B和C边 parent, a, b, c = [0] * (len(edges) + 1), None, None, None + for i, edge in enumerate(edges): if parent[edge[1]]: - a, b, c, edges[i][0]= parent[edge[1]], edge[0], edge[1], 0 + # 如果已有指向edge[1]的父节点,记录为候选A、B和C边 + a, b, c, edges[i][0] = parent[edge[1]], edge[0], edge[1], 0 else: + # 否则设置新的指向关系 parent[edge[1]] = edge[0] + # 重置父节点数组,初始化为节点索引 parent = [i for i in range(len(edges) + 1)] + + # 构建有向图并寻找冗余边 for u, v in edges: if u: if root(u) == v: return a and [a, c] or [u, v] parent[v] = u - return [b, c] \ No newline at end of file + return [b, c] diff --git a/solutions/python3/686.py b/solutions/python3/686.py index 24eae26..9f3310f 100644 --- a/solutions/python3/686.py +++ b/solutions/python3/686.py @@ -1,5 +1,12 @@ + class Solution: + # 定义一个求解重复字符串匹配次数的方法,输入为两个字符串A和B def repeatedStringMatch(self, A: str, B: str) -> int: - for i in range(1,2+len(B)//len(A)+1): - if B in A*i: return i - return -1 \ No newline at end of file + # 遍历从1到len(B)//len(A)+2的范围(考虑到可能需要额外拼接A以包含B) + for i in range(1, 2 + len(B) // len(A) + 1): + # 检查字符串B是否在重复i次后的字符串A中 + if B in A * i: + return i # 如果找到返回当前的i值 + + # 如果没有找到合适的i,返回-1表示未找到匹配情况 + return -1 diff --git a/solutions/python3/688.py b/solutions/python3/688.py index 33446b1..249a513 100644 --- a/solutions/python3/688.py +++ b/solutions/python3/688.py @@ -1,14 +1,35 @@ + class Solution: - def knightProbability(self, N, K, r, c): + def knightProbability(self, N: int, K: int, r: int, c: int) -> float: + """ + 计算骑士在N×N棋盘上经过K步后,停留在指定位置的概率。 + + :param N: 棋盘的大小 + :param K: 骑士移动的步数 + :param r: 起始行坐标 + :param c: 起始列坐标 + :return: 骑士在K步后停留在给定位置的概率 + + 使用记忆化递归(Memoization)来加速计算过程。 + """ + memo = {} - def dfs(i, j, p, k): + + def dfs(i, j, p, k): + # 如果当前位置在棋盘内且剩余步数小于总步数 if 0 <= i < N and 0 <= j < N and k < K: sm = 0 + # 骑士的所有可能移动方向 for x, y in ((-1, -2), (-2, -1), (-2, 1), (-1, 2), (1, 2), (2, 1), (2, -1), (1, -2)): + # 如果该位置和步数组合未被计算过 if (i + x, j + y, k) not in memo: + # 记录并计算结果 memo[(i + x, j + y, k)] = dfs(i + x, j + y, p / 8, k + 1) sm += memo[(i + x, j + y, k)] return sm else: + # 如果当前位置超出棋盘边界或步数用尽,则返回0或当前位置的概率(1) return 0 <= i < N and 0 <= j < N and p or 0 - return dfs(r, c, 1, 0) \ No newline at end of file + + # 初始位置和概率为1,剩余步数为0 + return dfs(r, c, 1, 0) diff --git a/solutions/python3/689.py b/solutions/python3/689.py index 563529c..63c3eda 100644 --- a/solutions/python3/689.py +++ b/solutions/python3/689.py @@ -1,19 +1,38 @@ + class Solution: + # 定义一个类,用于解决最大子数组和的问题 + def maxSumOfThreeSubarrays(self, nums, k): + """ + :param nums: List[int] - 输入的整数列表 + :param k: int - 子数组的长度 + :return: List[int] - 三个具有最大总和的子数组的起始索引 + + 思路: + 使用滑动窗口技术,首先计算每个可能子数组的和。 + 然后遍历这些子数组来找到最优解。 + """ single, double, sm, n, cur = {}, {}, 0, len(nums), sum(nums[:k - 1]) + # 初始化单个子数组和双个子数组字典,当前窗口总和,数组长度以及初始窗口总和 + for i in range(k - 1, n): cur += nums[i] single[i - k + 1] = cur cur -= nums[i - k + 1] - cur = n - k, single[n - k] + # 遍历计算每个可能子数组的和并存储在字典中 + + cur = (n - k), single[n - k] for i in range(n - k, k * 2 - 1, -1): if single[i] >= cur[1]: cur = i, single[i] - double[i - k] = cur[1] + single[i - k], i - k, cur[0] + double[i - k] = (cur[1] + single[i - k], i - k, cur[0]) + # 遍历计算每个可能双个子数组的和并存储在字典中 + cur = double[n - 2 * k] for i in range(n - 2 * k, k - 1, -1): if double[i][0] >= cur[0]: cur = double[i] if single[i - k] + cur[0] >= sm: sm, res = single[i - k] + cur[0], [i - k, cur[1], cur[2]] - return res \ No newline at end of file + # 遍历计算最终的最优解 + return res diff --git a/solutions/python3/69.py b/solutions/python3/69.py index b95eed9..20d9828 100644 --- a/solutions/python3/69.py +++ b/solutions/python3/69.py @@ -1,10 +1,23 @@ + class Solution: + # 中文注释:实现计算非负整数x的平方根向下取整 + # English comment: Implement the calculation of the floor square root of a non-negative integer x + def mySqrt(self, x: int) -> int: + # 初始化左右指针,分别指向 0 和 x l, r = 0, x + while l <= r: + # 计算中间值 mid mid = (l + r) // 2 + + # 如果 mid 的平方小于等于 x,则说明 mid 是当前范围内的候选解之一 if mid * mid <= x: + # 尝试向右扩大搜索区间,寻找可能更大的候选解 l = mid + 1 else: + # 否则,缩小搜索区间到左半部分 r = mid - 1 - return l - 1 \ No newline at end of file + + # 最终返回右指针减一作为结果 + return l - 1 diff --git a/solutions/python3/690.py b/solutions/python3/690.py index b301ba1..02ab780 100644 --- a/solutions/python3/690.py +++ b/solutions/python3/690.py @@ -1,7 +1,8 @@ + """ # Employee info class Employee: - def __init__(self, id, importance, subordinates): + def __init__(self, id: int, importance: int, subordinates: List[int]): # It's the unique id of each node. # unique id of this employee self.id = id @@ -11,19 +12,26 @@ def __init__(self, id, importance, subordinates): self.subordinates = subordinates """ class Solution: - def getImportance(self, employees, id): + def getImportance(self, employees: List[Employee], id: int) -> int: """ :type employees: Employee :type id: int :rtype: int """ + + # 递归函数,计算当前员工及其下属的重要性总和 def dfs(id): self.val += dic[id].importance for sub in dic[id].subordinates: dfs(sub) - dic = {} - for emp in employees: - dic[emp.id] = emp + + # 构建员工字典 + dic = {emp.id: emp for emp in employees} + + # 初始化结果变量 self.val = 0 + + # 开始递归计算重要性总和 dfs(id) - return self.val \ No newline at end of file + + return self.val diff --git a/solutions/python3/691.py b/solutions/python3/691.py index ff4efb8..0f0b5c6 100644 --- a/solutions/python3/691.py +++ b/solutions/python3/691.py @@ -1,18 +1,30 @@ + class Solution: - def minStickers(self, stickers, target): - cnt, res, n = collections.Counter(target), [float("inf")], len(target) + def minStickers(self, stickers: List[str], target: str) -> int: + # 使用Counter统计目标字符串中每个字符的数量 + cnt = collections.Counter(target) + # 初始化结果为无穷大,用于记录最小贴纸数量;len(target)表示target长度 + res = [float("inf")] + def dfs(dic, used, i): - if i == n: - res[0] = min(res[0], used) - elif dic[target[i]] >= cnt[target[i]]: + """ + dic: 当前已使用的字符统计字典 + used: 已用到的贴纸数量 + i: 目标字符串中当前处理到的位置索引 + """ + if i == len(target): # 如果目标字符串遍历完成 + res[0] = min(res[0], used) # 更新最小贴纸数 + elif dic[target[i]] >= cnt[target[i]]: # 当前字符已经足够覆盖目标中需要的数量,跳过 dfs(dic, used, i + 1) - elif used < res[0] - 1: + elif used < res[0] - 1: # 如果当前已用的贴纸数量比最小值还小,则继续尝试 for sticker in stickers: - if target[i] in sticker: + if target[i] in sticker: # 当前贴纸能覆盖目标字符串中的某个字符,开始递归处理 for s in sticker: - dic[s] += 1 - dfs(dic, used + 1, i + 1) + dic[s] += 1 # 更新当前已用的字符统计字典 + dfs(dic, used + 1, i + 1) # 递归调用 for s in sticker: - dic[s] -= 1 + dic[s] -= 1 # 恢复状态,回溯 + dfs(collections.defaultdict(int), 0, 0) - return res[0] < float("inf") and res[0] or -1 \ No newline at end of file + + return res[0] < float("inf") and res[0] or -1 # 如果找到有效解返回结果,否则返回-1 diff --git a/solutions/python3/692.py b/solutions/python3/692.py index 1312f5d..353d13e 100644 --- a/solutions/python3/692.py +++ b/solutions/python3/692.py @@ -1,3 +1,10 @@ + class Solution: + # 定义一个类来解决寻找词频前k高的问题 + def topKFrequent(self, words, k): - return [w for w, v in sorted(collections.Counter(words).items(), key = lambda x: (-x[1], x[0])) [:k]] \ No newline at end of file + # 返回词频前k高且字典序较小的单词列表 + + # 使用collections.Counter计算每个单词的频率 + return [w for w, v in sorted(collections.Counter(words).items(), key=lambda x: (-x[1], x[0]))[:k]] + # 通过sorted对Counter的结果进行排序,并取前k个元素 diff --git a/solutions/python3/693.py b/solutions/python3/693.py index a22868e..adc8cff 100644 --- a/solutions/python3/693.py +++ b/solutions/python3/693.py @@ -1,4 +1,11 @@ + class Solution: + # 判断给定整数的二进制表示中是否每一位都是交替出现的不同位 + def hasAlternatingBits(self, n: int) -> bool: - return all(a != b for a, b in zip(bin(n)[2:], bin(n)[3:])) - \ No newline at end of file + # 将整数n转换为二进制字符串,并去掉前缀'0b' + binary_str = bin(n)[2:] + + # 使用zip函数将二进制字符串的相邻字符配对 + # 检查每一对是否不同,即交替位条件是否满足 + return all(a != b for a, b in zip(binary_str, binary_str[1:])) diff --git a/solutions/python3/694.py b/solutions/python3/694.py index 6041f21..7484362 100644 --- a/solutions/python3/694.py +++ b/solutions/python3/694.py @@ -1,15 +1,40 @@ + class Solution: - def numDistinctIslands(self, grid): - visited, pattern, m, n = set(), collections.defaultdict(str), len(grid), len(grid[0]) - def dfs(ri, rj, i, j, pi, pj): - visited.add((i, j)) - pattern[(ri, rj)] += str(pi) + str(pj) - for x, y in ((-1, 0), (1, 0), (0, -1), (0, 1)): - if 0 <= i + x < m and 0 <= j + y < n and grid[i + x][j + y] and (i + x, j + y) not in visited: - dfs(ri, rj, i + x, j + y, pi + x, pj + y) - + def numDistinctIslands(self, grid: list[list[int]]) -> int: + """ + 计算矩阵中不同岛屿的数量 + + 参数: + - grid: 列表列表,表示网格地图。1 表示陆地,0 表示水域。 + + 返回值: + 不同形状的岛屿数量。 + """ + + visited = set() # 已访问的位置集合 + pattern = collections.defaultdict(str) # 记录每块岛屿的形态 + m, n = len(grid), len(grid[0]) # 网格行数和列数 + + def dfs(ri: int, rj: int, i: int, j: int, pi: int, pj: int) -> None: + """ + 深度优先搜索记录岛屿形状。 + + 参数: + - ri, rj: 当前坐标相对起点的偏移量 + - i, j: 当前网格坐标 + - pi, pj: 相对于起点的位置变化量 + """ + visited.add((i, j)) # 标记当前位置已访问 + pattern[(ri, rj)] += str(pi) + str(pj) # 记录当前位置相对起点的偏移 + + for dx, dy in ((-1, 0), (1, 0), (0, -1), (0, 1)): + ni, nj = i + dx, j + dy # 目标位置坐标 + if 0 <= ni < m and 0 <= nj < n and grid[ni][nj] and (ni, nj) not in visited: + dfs(ri + dx, rj + dy, ni, nj, pi + dx, pj + dy) + for i in range(m): for j in range(n): - if grid[i][j] and (i, j) not in visited: - dfs(i, j, i, j, 0, 0) - return len(set(pattern.values())) \ No newline at end of file + if grid[i][j] and (i, j) not in visited: # 未访问且为陆地 + dfs(i, j, i, j, 0, 0) # 开始深度优先搜索 + + return len(set(pattern.values())) # 返回不同岛屿形态的数量 diff --git a/solutions/python3/695.py b/solutions/python3/695.py index 6464622..468b0a5 100644 --- a/solutions/python3/695.py +++ b/solutions/python3/695.py @@ -1,7 +1,31 @@ + class Solution: def maxAreaOfIsland(self, grid): + """ + (中文)求解岛屿的最大面积。 + + 参数: + - grid: List[List[int]] - 二维网格,1表示陆地,0表示水 + + 返回值: + 最大岛屿面积(整数) + """ + m, n = len(grid), len(grid and grid[0]) + # (英文) 获取网格的行数和列数 def explore(i, j): - grid[i][j] = 0 - return 1 + sum(explore(x,y) for x,y in ((i-1,j),(i+1,j),(i,j-1),(i,j+1)) if 0<=x int: + # 将交替的'01'和'10'替换为'#', 以分割字符串 s = s.replace("01", "0#1").replace("10", "1#0").split("#") - return sum(min(len(s[i]), len(s[i - 1])) for i in range(1, len(s))) \ No newline at end of file + + # 计算相邻子字符串长度的最小值之和作为结果 + return sum(min(len(s[i]), len(s[i - 1])) for i in range(1, len(s))) diff --git a/solutions/python3/697.py b/solutions/python3/697.py index 21d525e..5fd2fd1 100644 --- a/solutions/python3/697.py +++ b/solutions/python3/697.py @@ -1,6 +1,30 @@ + class Solution: + # 定义一个类来解决问题 + def findShortestSubArray(self, nums): - cnt, seen = collections.Counter(nums), collections.defaultdict(list) + """ + :param nums: 列表形式的整数数组 (List[int]) + :return: 返回包含最短连续子数组的长度 (int) + + 例如:输入 [1,2,2,3,1],输出为 2。 + 因为[2,2]是具有最大频率且最小长度的连续子数组 + """ + + from collections import Counter, defaultdict + + # 使用Counter计算每个元素出现的次数 + cnt = Counter(nums) + + # 使用defaultdict来存储每个元素所有索引的位置 + seen = defaultdict(list) + + # 找到数组中的最大频率 degree = max(cnt.values()) - for i, v in enumerate(nums): seen[v].append(i) - return min(seen[v][-1] - seen[v][0] + 1 for v in cnt if cnt[v] == degree) \ No newline at end of file + + # 将每个元素的所有索引位置存入seen中 + for i, v in enumerate(nums): + seen[v].append(i) + + # 返回具有最大频率的子数组最小长度 + return min(seen[v][-1] - seen[v][0] + 1 for v in cnt if cnt[v] == degree) diff --git a/solutions/python3/698.py b/solutions/python3/698.py index 83433cb..dee0c47 100644 --- a/solutions/python3/698.py +++ b/solutions/python3/698.py @@ -1,17 +1,38 @@ + class Solution: + # 判断是否可以将数组分割为k个具有相同总和的子集 + def canPartitionKSubsets(self, nums, k): + # 深度优先搜索函数,i表示当前处理的数字索引,sums记录每个子集的当前和 def dfs(i, sums): - if i == n: + if i == n: # 所有数字都已分配完毕 return True - for j in range(k): - if sums[j] + nums[i] <= target: + + for j in range(k): # 尝试将当前数字加入k个子集中任一个 + if sums[j] + nums[i] <= target: # 当前子集和加上该数不超过目标值 sums[j] += nums[i] + + # 继续递归处理下一个数字 if dfs(i + 1, sums): return True + + # 回溯,撤销当前分配决策 sums[j] -= nums[i] + return False - nums.sort(reverse = True) + + # 按降序排序数组,便于后续剪枝 + nums.sort(reverse=True) + + # 计算数组总和 sm = sum(nums) - if sm % k: return False + + # 如果总数不能被k整除,则不可能分割成功 + if sm % k: + return False + + # 目标子集的和与数字个数 target, n = sm // k, len(nums) - return dfs(0, [0] * k) \ No newline at end of file + + # 从第一个数字开始进行深度优先搜索 + return dfs(0, [0] * k) diff --git a/solutions/python3/699.py b/solutions/python3/699.py index 1523cce..81a2e30 100644 --- a/solutions/python3/699.py +++ b/solutions/python3/699.py @@ -1,15 +1,32 @@ + class Solution: def fallingSquares(self, positions: List[List[int]]) -> List[int]: - height = [0] - pos = [0] - res = [] - max_h = 0 - for left, side in positions: - i = bisect.bisect_right(pos, left) - j = bisect.bisect_left(pos, left + side) - high = max(height[i - 1:j] or [0]) + side - pos[i:j] = [left, left + side] - height[i:j] = [high, height[j - 1]] - max_h = max(max_h, high) - res.append(max_h) - return res \ No newline at end of file + """ + 解决问题:给定一系列方块的起始位置和大小,计算每个时刻的最大高度。 + + :param positions: 一个二维列表,表示每个方块的左边界和宽度 + :return: 返回一个一维列表,表示每个时间点的最大高度 + + 思路分析: + - 使用线段树来维护每个区间的最大高度 + - 对于每一个新出现的方块,找到它覆盖的所有区间,并更新这些区间的最大高度 + - 通过二分查找快速定位要处理的区间 + """ + height = [0] # 初始化高度列表 + pos = [0] # 初始化位置列表 + res = [] # 存储结果的最大高度 + max_h = 0 # 当前最大高度 + + for left, side in positions: # 遍历每个方块 + i = bisect.bisect_right(pos, left) # 找到大于等于left的第一个位置的索引 + j = bisect.bisect_left(pos, left + side) # 找到最后一个小于等于left+side-1的位置的索引 + + high = max(height[i - 1:j] or [0]) + side # 计算当前方块的最大高度 + + pos[i:j] = [left, left + side] # 更新位置列表 + height[i:j] = [high, height[j - 1]] # 更新高度列表 + + max_h = max(max_h, high) # 更新最大高度 + res.append(max_h) # 添加到结果中 + + return res # 返回结果 diff --git a/solutions/python3/7.py b/solutions/python3/7.py index 1efd77b..4853b9b 100644 --- a/solutions/python3/7.py +++ b/solutions/python3/7.py @@ -1,3 +1,13 @@ + class Solution: - def reverse(self, x): - x = int(str(x)[::-1]) if x >= 0 else int("-" + str(x)[::-1][:-1]); return -2 ** 31 <= x <= 2 ** 31 - 1 and x or 0 \ No newline at end of file + # 定义一个reverse方法,用于反转整数x的位数 + def reverse(self, x: int) -> int: + # 如果x为正数,则直接反转字符串形式的数字并转换回整数 + if x >= 0: + reversed_x = int(str(x)[::-1]) + else: + # 如果x为负数,先反转其绝对值的字符串形式,去掉最后一个字符(原符号),再添加负号 + reversed_x = -int("-" + str(x)[::-1][:-1]) + + # 检查反转后的整数值是否在32位有符号整数范围内 + return reversed_x if -2**31 <= reversed_x <= 2**31 - 1 else 0 diff --git a/solutions/python3/70.py b/solutions/python3/70.py index aec35bd..358dba8 100644 --- a/solutions/python3/70.py +++ b/solutions/python3/70.py @@ -1,9 +1,24 @@ + class Solution: + # 定义一个求解爬楼梯问题的类 + def climbStairs(self, n: int) -> int: + # 定义一个爬楼梯方法,输入n表示台阶数,返回到达第n个台阶的方法总数 + memo = {} + # 使用字典memo来存储已经计算过的子问题结果以避免重复计算 + def dfs(i): - if i >= n: return 1 if i == n else 0 + # 定义深度优先搜索辅助函数dfs + if i >= n: + return 1 if i == n else 0 + # 当i大于等于n时,返回1表示当前路径有效;否则返回0 + if i not in memo: + # 如果memo中没有保存过i的值,则递归计算并存储结果 memo[i] = dfs(i + 1) + dfs(i + 2) return memo[i] - return dfs(0) \ No newline at end of file + # 返回从起点开始爬楼梯的方法总数 + + return dfs(0) + # 调用dfs(0),表示从第0个台阶开始爬楼梯 diff --git a/solutions/python3/700.py b/solutions/python3/700.py index e91c193..f4398d1 100644 --- a/solutions/python3/700.py +++ b/solutions/python3/700.py @@ -1,5 +1,15 @@ + class Solution: + # 中文:搜索二叉树,给定节点root和目标值val,在二叉搜索树中查找等于val的节点。 + # 英文:Search a Binary Search Tree (BST), given node `root` and target value `val`. def searchBST(self, root, val): - if root and val < root.val: return self.searchBST(root.left, val) - elif root and val > root.val: return self.searchBST(root.right, val) - return root \ No newline at end of file + if root and val < root.val: # 中文:如果当前节点存在且目标值小于当前节点值,则递归搜索左子树。 + # 英文:If the current node exists and the target value is less than the current node's value, + # recursively search the left subtree. + return self.searchBST(root.left, val) + elif root and val > root.val: # 中文:如果当前节点存在且目标值大于当前节点值,则递归搜索右子树。 + # 英文:If the current node exists and the target value is greater than the current node's value, + # recursively search the right subtree. + return self.searchBST(root.right, val) + return root # 中文:如果找到等于目标值的节点或遍历到叶子节点,则返回当前节点。 + # 英文:Return the current node if a node with the target value is found or reach a leaf node. diff --git a/solutions/python3/701.py b/solutions/python3/701.py index a6024c1..3c6be80 100644 --- a/solutions/python3/701.py +++ b/solutions/python3/701.py @@ -1,5 +1,11 @@ + class Solution: - def insertIntoBST(self, root, val): - if root and root.val > val and not self.insertIntoBST(root.left, val): root.left = TreeNode(val) - elif root and root.val < val and not self.insertIntoBST(root.right, val): root.right = TreeNode(val) - return root \ No newline at end of file + # 定义一个二叉搜索树插入节点的方法,传入根节点root和要插入的值val + def insertIntoBST(self, root: TreeNode, val: int) -> TreeNode: + if root and root.val > val and not self.insertIntoBST(root.left, val): # 如果当前节点存在且其值大于val,则递归插入左子树 + # 当前节点的左子节点为新创建的TreeNode(val),表示已成功插入该节点 + root.left = TreeNode(val) + elif root and root.val < val and not self.insertIntoBST(root.right, val): # 如果当前节点存在且其值小于val,则递归插入右子树 + # 当前节点的右子节点为新创建的TreeNode(val),表示已成功插入该节点 + root.right = TreeNode(val) + return root # 返回根节点,表示操作完成 diff --git a/solutions/python3/702.py b/solutions/python3/702.py index 7109c07..c6c48bc 100644 --- a/solutions/python3/702.py +++ b/solutions/python3/702.py @@ -1,13 +1,22 @@ + class Solution(object): - def search(self, reader, target): + # 搜索目标值在给定的读取器中,返回目标值的索引;如果未找到,则返回-1。 + def search(self, reader, target: int) -> int: + # 初始化左右边界 l, r = 0, 20000 + + # 二分查找 while l <= r: - index = (l + r) // 2 - response = reader.get(index) + mid = (l + r) // 2 + response = reader.get(mid) + + # 根据比较结果调整左右边界 if response > target: - r = index - 1 + r = mid - 1 elif response < target: - l = index + 1 + l = mid + 1 else: - return index - return -1 \ No newline at end of file + return mid + + # 如果未找到目标值,返回-1 + return -1 diff --git a/solutions/python3/703.py b/solutions/python3/703.py index fb5d724..4bf266a 100644 --- a/solutions/python3/703.py +++ b/solutions/python3/703.py @@ -1,16 +1,28 @@ + class KthLargest(object): def __init__(self, k, nums): + """ + 初始化KthLargest类,使用一个小顶堆来维护前k大的元素。 + + :param k: int - 表示要找到的第k大元素的位置。 + :param nums: List[int] - 初始的数字列表。 + """ self.pool = nums self.k = k - heapq.heapify(self.pool) + heapq.heapify(self.pool) # 将列表转换为小顶堆 while len(self.pool) > k: - heapq.heappop(self.pool) + heapq.heappop(self.pool) # 弹出最小值,保持堆中只有k个元素 - def add(self, val): + """ + 添加一个新值到KthLargest对象中,并返回当前第k大元素。 + + :param val: int - 要添加的数值。 + :return: int - 当前堆中的第k大元素。 + """ if len(self.pool) < self.k: - heapq.heappush(self.pool, val) + heapq.heappush(self.pool, val) # 堆中元素小于k时直接插入 elif val > self.pool[0]: - heapq.heapreplace(self.pool, val) - return self.pool[0] \ No newline at end of file + heapq.heapreplace(self.pool, val) # 如果新值大于堆顶,用新值替换堆顶并返回旧堆顶 + return self.pool[0] diff --git a/solutions/python3/704.py b/solutions/python3/704.py index 0ed0cb5..581cb83 100644 --- a/solutions/python3/704.py +++ b/solutions/python3/704.py @@ -1,3 +1,10 @@ + class Solution: + # 搜索指定元素在排序数组中的插入位置或返回其索引,如果不存在则返回-1 + def search(self, nums: List[int], target: int) -> int: - return bisect.bisect_left(nums, target) if target in nums else -1 \ No newline at end of file + # 使用bisect_left查找目标值的位置,如果目标值不在列表中,则返回应插入的左边界索引 + # 双语注释: + # Search for the index of a target value in a sorted list or return -1 if not found. + # Use bisect_left to find the position of the target, and return the left insertion point if not present. + return bisect.bisect_left(nums, target) if target in nums else -1 diff --git a/solutions/python3/705.py b/solutions/python3/705.py index 5dfe6ca..5ede13b 100644 --- a/solutions/python3/705.py +++ b/solutions/python3/705.py @@ -1,107 +1,88 @@ - - - - +html + + - - -leetcode.com | 502: Bad gateway - - - - - - - - - - - - + + + 502 Bad Gateway Error + -
Retry for a live version

This page (https://leetcode.com/submissions/detail/163424957/) is currently offline. However, because the site uses Cloudflare's Always Online™ technology you can continue to surf a snapshot of the site. We will keep checking in the background and, as soon as the site comes back, you will automatically be served the live version. Always Online™ is powered by Cloudflare | Hide this Alert

-
- - - -
-
-

- - Error - 502 - Ray ID: 52beb9bebad1d8bd • 2019-10-26 19:09:36 UTC -

-

Bad gateway

-
- -
-
-
- -
-
- - -
- You -

Browser

- Working -
- -
-
- - -
- Amsterdam -

Cloudflare

- Working -
- -
-
- - -
- leetcode.com -

Host

- Error -
- + +
+
+

Error 502 Bad Gateway

+ Ray ID: 52beb9bebad1d8bd • 2019-10-26 19:09:36 UTC +

What happened?

+

The web server reported a bad gateway error.

+

What can I do?

+

Please try again in a few minutes.

+ +
+
+
+ + +
+ You +

Browser

+ Working
- -
-
- -
-
-
-

What happened?

-

The web server reported a bad gateway error.

+ +
+
+ + +
+ Amsterdam +

Cloudflare

+ Working
- -
-

What can I do?

-

Please try again in a few minutes.

+ +
+
+ + +
+ leetcode.com +

Host

+ Error
- -
- - - - -
-
+ + +
+
- diff --git a/solutions/python3/706.py b/solutions/python3/706.py index 47241df..aee2552 100644 --- a/solutions/python3/706.py +++ b/solutions/python3/706.py @@ -1,13 +1,18 @@ + class MyHashMap: + # 构造函数,初始化一个大小为1000001的数组,初始值均为-1 def __init__(self): self.arr = [-1] * 1000001 - def put(self, key, value): + # 向哈希表中插入或更新键值对 + def put(self, key: int, value: int) -> None: self.arr[key] = value - def get(self, key): + # 根据键获取对应的值,如果不存在则返回-1 + def get(self, key: int) -> int: return self.arr[key] - def remove(self, key): - self.arr[key] = -1 \ No newline at end of file + # 移除哈希表中指定的键及其对应的值 + def remove(self, key: int) -> None: + self.arr[key] = -1 diff --git a/solutions/python3/707.py b/solutions/python3/707.py index c5a9c17..0739984 100644 --- a/solutions/python3/707.py +++ b/solutions/python3/707.py @@ -1,40 +1,49 @@ + class Node: def __init__(self, value): + # 初始化节点,设置值和前后指针 self.val = value self.next = self.pre = None + class MyLinkedList: def __init__(self): + # 初始化链表头尾节点以及大小 self.head = self.tail = Node(-1) self.head.next = self.tail self.tail.pre = self.head self.size = 0 def add(self, preNode, val): + # 在指定节点前插入新节点 node = Node(val) node.pre = preNode node.next = preNode.next - node.pre.next = node.next.pre = node + node.next.pre = node.pre.next = node self.size += 1 def remove(self, node): + # 移除指定节点,并调整前后节点链接 node.pre.next = node.next node.next.pre = node.pre self.size -= 1 def forward(self, start, end, cur): + # 从当前节点开始向前遍历 while start != end: start += 1 cur = cur.next return cur def backward(self, start, end, cur): + # 从当前节点开始向后遍历 while start != end: start -= 1 cur = cur.pre return cur def get(self, index): + # 获取指定索引位置的值,分前半部分和后半部分处理 if 0 <= index <= self.size // 2: return self.forward(0, index, self.head.next).val elif self.size // 2 < index < self.size: @@ -42,19 +51,23 @@ def get(self, index): return -1 def addAtHead(self, val): + # 在链表头部添加节点 self.add(self.head, val) def addAtTail(self, val): + # 在链表尾部添加节点 self.add(self.tail.pre, val) def addAtIndex(self, index, val): + # 在指定索引位置插入新节点,分前半部分和后半部分处理 if 0 <= index <= self.size // 2: self.add(self.forward(0, index, self.head.next).pre, val) elif self.size // 2 < index <= self.size: self.add(self.backward(self.size, index, self.tail).pre, val) def deleteAtIndex(self, index): + # 删除指定索引位置的节点 if 0 <= index <= self.size // 2: self.remove(self.forward(0, index, self.head.next)) elif self.size // 2 < index < self.size: - self.remove(self.backward(self.size - 1, index, self.tail.pre)) \ No newline at end of file + self.remove(self.backward(self.size - 1, index, self.tail.pre)) diff --git a/solutions/python3/709.py b/solutions/python3/709.py index 9268bf6..1cdc3d5 100644 --- a/solutions/python3/709.py +++ b/solutions/python3/709.py @@ -1,3 +1,5 @@ + class Solution: - def toLowerCase(self, str): - return "".join(chr(ord(c) + 32) if 65 <= ord(c) <= 90 else c for c in str) \ No newline at end of file + # 将字符串中的大写字母转换为小写,保持其他字符不变 + def toLowerCase(self, str): + return "".join(chr(ord(c) + 32) if 65 <= ord(c) <= 90 else c for c in str) diff --git a/solutions/python3/71.py b/solutions/python3/71.py index e5cbf95..55f1d94 100644 --- a/solutions/python3/71.py +++ b/solutions/python3/71.py @@ -1,6 +1,19 @@ + class Solution: + # 定义一个简化路径的方法 def simplifyPath(self, path): - stack = [] + # 使用栈来存储路径中的有效部分 + stack = [] + + # 遍历分割后的路径字符串列表 for c in path.split("/"): - stack = stack[:-1] if c== ".." else stack + [c] if c and c != "." else stack - return "/" + "/".join(stack) \ No newline at end of file + # 如果遇到'..'且栈非空,弹出栈顶元素 + if c == "..": + if stack: + stack.pop() + # 如果当前字符有效(不为空且不是'.'),则压入栈中 + elif c and c != ".": + stack.append(c) + + # 最终的简化路径为栈内所有元素拼接而成,并以'/'开头 + return "/" + "/".join(stack) diff --git a/solutions/python3/710.py b/solutions/python3/710.py index 8204924..282966b 100644 --- a/solutions/python3/710.py +++ b/solutions/python3/710.py @@ -1,10 +1,32 @@ + class Solution: def __init__(self, N, blacklist): - self.forbidden, self.n, self.used, self.cur = set(blacklist), N, set(), 0 + """ + 初始化解决方案,设置禁止列表和相关参数 + + :param N: 整数,表示范围的上限 + :param blacklist: 列表,包含禁止使用的数字 + """ + self.forbidden = set(blacklist) # 将黑名单转换为集合以提高查找效率 + self.n = N # 总范围大小 + self.used = set() # 已使用过的合法数字集合 + self.cur = 0 # 当前尝试的数字 + def pick(self): - while self.cur in self.forbidden: self.cur += 1 - if self.cur < self.n: num, self.cur = self.cur, self.cur + 1 - else: num = self.used.pop() - self.used.add(num) - return num \ No newline at end of file + """ + 从允许范围内随机选择一个数字 + + :return: 一个未被禁止且未使用的合法数字 + """ + while self.cur in self.forbidden: + self.cur += 1 # 跳过禁止的数字 + + if self.cur < self.n: + num, self.cur = self.cur, self.cur + 1 # 选择当前合法的数并增加计数 + else: + num = self.used.pop() # 使用已使用过的合法数(若存在) + + self.used.add(num) # 将选中的数字加入已使用集合 + + return num diff --git a/solutions/python3/711.py b/solutions/python3/711.py index 06fc23d..ee14ff2 100644 --- a/solutions/python3/711.py +++ b/solutions/python3/711.py @@ -1,49 +1,75 @@ + class Solution: def numDistinctIslands2(self, grid: List[List[int]]) -> int: - if not grid or not grid[0]: return 0 - m,n=len(grid),len(grid[0]) - - # augment matrix to void length check - grid.append([0]*n) - for row in grid: row.append(0) - - self.pool=set() - self.res=0 - - def bfs(i0,j0): - grid[i0][j0]=-1 - q=[(i0,j0)] - for i,j in q: - for I,J in (i-1,j),(i+1,j),(i,j-1),(i,j+1): - if grid[I][J]==1: - grid[I][J]=-1 - q.append([I,J]) + """ + 给定一个二维网格,计算不同的岛屿数量。 + 1. 判断矩阵是否为空或行数、列数为0,为空则返回0. + 2. 扩展矩阵边界以避免越界检查. + 3. 初始化集合存储已经遇到的岛屿形态,并计数器记录不同岛屿的数量. + + 使用广度优先搜索遍历每个陆地块并标记访问过的陆地。将当前岛屿形态添加到结果集中,计算不同的形态数量。 + """ + if not grid or not grid[0]: + return 0 + m, n = len(grid), len(grid[0]) + + # 扩展矩阵边界以避免越界检查 + grid.append([0] * n) + for row in grid: + row.append(0) + + self.pool = set() + self.res = 0 + + def bfs(i0, j0): + """ + 广度优先搜索,从起点i0,j0开始,标记访问过的陆地并扩展岛屿边界。 + 将形态存储到结果集中,并计算不同岛屿的总数。 + """ + grid[i0][j0] = -1 + q = [(i0, j0)] + for i, j in q: + for I, J in (i-1,j),(i+1,j),(i,j-1),(i,j+1): + if grid[I][J] == 1: + grid[I][J] = -1 + q.append((I,J)) self.addisland(q) - + for i in range(m): for j in range(n): - if grid[i][j]==1: bfs(i,j) - + if grid[i][j] == 1: + bfs(i, j) + return self.res - def addisland(self,q): - Imin=min(x for x,y in q) - Jmin=min(y for x,y in q) - island1=tuple(sorted((x-Imin,y-Jmin) for x,y in q)) # original island - - if island1 in self.pool: return None - self.res+=1 + def addisland(self, q): + """ + 将当前岛屿形态添加到结果集,计算不同岛屿的总数。 + 通过旋转和镜像操作对岛屿进行标准化处理,避免重复计数。 + """ + Imin = min(x for x,y in q) + Jmin = min(y for x,y in q) + + # 对岛屿进行坐标偏移,原点移到左下角 + island1 = tuple(sorted((x-Imin, y-Jmin) for x,y in q)) + + if island1 in self.pool: + return None + + self.res += 1 - Imax=max(x for x,y in island1) - Jmax=max(y for x,y in island1) + Imax = max(x for x,y in island1) + Jmax = max(y for x,y in island1) - island2=tuple(sorted((-x+Imax,y) for x,y in island1)) # x axis mirror - island3=tuple(sorted((x,-y+Jmax) for x,y in island1)) # y axis mirror - island4=tuple(sorted((-x+Imax,-y+Jmax) for x,y in island1)) # origin mirror + # 镜像变换 + island2 = tuple(sorted((-x+Imax, y) for x,y in island1)) + island3 = tuple(sorted((x,-y+Jmax) for x,y in island1)) + island4 = tuple(sorted((-x+Imax,-y+Jmax) for x,y in island1)) - island5=tuple(sorted((y,x) for x,y in island1)) # diagonal mirror - island6=tuple(sorted((-x+Jmax,y) for x,y in island5)) - island7=tuple(sorted((x,-y+Imax) for x,y in island5)) - island8=tuple(sorted((-x+Jmax,-y+Imax) for x,y in island5)) + # 对角线变换 + island5 = tuple(sorted((y, x) for x,y in island1)) + island6 = tuple(sorted((-x+Jmax, y) for x,y in island5)) + island7 = tuple(sorted((x,-y+Imax) for x,y in island5)) + island8 = tuple(sorted((-x+Jmax,-y+Imax) for x,y in island5)) - self.pool |= set([island1,island2,island3,island4,island5,island6,island7,island8]) \ No newline at end of file + self.pool |= set([island1, island2, island3, island4, island5, island6, island7, island8]) diff --git a/solutions/python3/712.py b/solutions/python3/712.py index 0a2609f..7995f1d 100644 --- a/solutions/python3/712.py +++ b/solutions/python3/712.py @@ -1,14 +1,30 @@ + class Solution: - def minimumDeleteSum(self, s1, s2): + # 定义一个解决方案类 + + def minimumDeleteSum(self, s1: str, s2: str) -> int: + # 计算字符串s1和s2的长度,分别加1方便处理边界情况 l1, l2 = len(s1) + 1, len(s2) + 1 - d = [[0] * l2 for i in range(l1)] - for i in range(l1): - for j in range(l2): + + # 初始化动态规划表d,大小为(l1, l2),初始值为0 + d = [[0] * l2 for _ in range(l1)] + + # 遍历动态规划表填充值 + for i in range(1, l1): + for j in range(1, l2): c1, c2 = ord(s1[i - 1]), ord(s2[j - 1]) - if not i * j: + + # 如果i或j为0,初始化当前dp值 + if not (i and j): d[i][j] = d[i - 1][j] + c1 if i else d[i][j - 1] + c2 if j else 0 + + # 当字符匹配时,继承左上角的dp值 elif s1[i - 1] == s2[j - 1]: d[i][j] = d[i - 1][j - 1] + + # 字符不匹配时,取三种删除方式中的最小值 else: d[i][j] = min(d[i - 1][j] + c1, d[i][j - 1] + c2, d[i - 1][j - 1] + c1 + c2) - return d[-1][-1] \ No newline at end of file + + # 返回右下角的dp值,即最小删除代价 + return d[-1][-1] diff --git a/solutions/python3/713.py b/solutions/python3/713.py index b3ae431..6c965b5 100644 --- a/solutions/python3/713.py +++ b/solutions/python3/713.py @@ -1,8 +1,22 @@ + class Solution: def numSubarrayProductLessThanK(self, nums, k): - l, res, cur = 0, 0, 1 + """ + :param nums: List[int] - 输入数组 + :param k: int - 乘积限制值 + :return: int - 满足条件的子数组数量 + """ + + l, res, cur = 0, 0, 1 # 初始化左边界,结果计数器和当前乘积累积 + for i in range(len(nums)): - cur *= nums[i] - while cur >= k and l < i: l, cur = l + 1, cur // nums[l] - if cur < k: res += i - l + 1 - return res \ No newline at end of file + cur *= nums[i] # 将当前元素加入累积乘积 + + while cur >= k and l < i: # 当累积乘积大于等于k且左边界未到右边界时 + cur //= nums[l] # 移除左边界元素,更新累积乘积 + l += 1 # 左边界右移 + + if cur < k: # 如果当前累积乘积仍小于k + res += i - l + 1 # 更新结果计数器 + + return res # 返回满足条件的子数组数量 diff --git a/solutions/python3/714.py b/solutions/python3/714.py index 7b823e7..aeaffef 100644 --- a/solutions/python3/714.py +++ b/solutions/python3/714.py @@ -1,8 +1,21 @@ + class Solution: + # 定义一个解决方案类 + def maxProfit(self, prices, fee): - pre = [0, -float("inf")] + # prices: 价格列表,代表每天的股票价格 + # fee: 每次交易的手续费 + + pre = [0, -float("inf")] # 初始化前一个状态:持有现金(p0)和持有股票(p1) + for p in prices: + # 更新当前状态 p0, p1 = pre[1] + p - fee, pre[0] - p - if p0 > pre[0]: pre[0] = p0 - if p1 > pre[1]: pre[1] = p1 - return pre[0] \ No newline at end of file + + if p0 > pre[0]: # 如果卖出并扣除手续费后获得的现金更多,则更新持有现金的状态 + pre[0] = p0 + + if p1 > pre[1]: # 如果买入股票获得更多,更新持有股票的状态 + pre[1] = p1 + + return pre[0] # 返回最终持有的最大现金量 diff --git a/solutions/python3/715.py b/solutions/python3/715.py index fafdbdb..274739d 100644 --- a/solutions/python3/715.py +++ b/solutions/python3/715.py @@ -1,18 +1,90 @@ + from bisect import bisect_left as bl, bisect_right as br class RangeModule: + """ + 该类用于处理范围操作,支持添加、查询和移除范围。 + """ def __init__(self): + """ + 初始化一个空的存储列表 _X 以存储标记点。 + """ self._X = [] def addRange(self, left, right): + """ + 添加指定范围内的所有整数。具体逻辑为:在满足条件的位置插入边界值。 + + :param left: 范围起始位置 + :param right: 范围结束位置(不包括) + """ i, j = bl(self._X, left), br(self._X, right) - self._X[i:j] = [left]*(i%2 == 0) + [right]*(j%2 == 0) + self._X[i:j] = [left]*(i % 2 == 0) + [right]*(j % 2 == 0) def queryRange(self, left, right): + """ + 查询指定范围内是否有标记。如果在该范围内的标记位置数量为奇数,则认为有标记。 + + :param left: 范围起始位置 + :param right: 范围结束位置(不包括) + :return: 如果范围内包含标记点返回 True,否则 False。 + """ i, j = br(self._X, left), bl(self._X, right) - return i == j and i%2 == 1 + return i == j and i % 2 == 1 def removeRange(self, left, right): + """ + 移除指定范围内的所有整数。具体逻辑为:在满足条件的位置插入边界值。 + + :param left: 范围起始位置 + :param right: 范围结束位置(不包括) + """ + i, j = bl(self._X, left), br(self._X, right) + self._X[i:j] = [left]*(i % 2 == 1) + [right]*(j % 2 == 1) + + + +from bisect import bisect_left as bl, bisect_right as br + +class RangeModule: + """ + 该类用于处理范围操作,支持添加、查询和移除范围。 + """ + + def __init__(self): + """ + 初始化一个空的存储列表 _X 以存储标记点。 + """ + self._X = [] + + def addRange(self, left, right): + """ + 添加指定范围内的所有整数。具体逻辑为:在满足条件的位置插入边界值。 + + :param left: 范围起始位置 + :param right: 范围结束位置(不包括) + """ + i, j = bl(self._X, left), br(self._X, right) + self._X[i:j] = [left]*(i % 2 == 0) + [right]*(j % 2 == 0) + + def queryRange(self, left, right): + """ + 查询指定范围内是否有标记。如果在该范围内的标记位置数量为奇数,则认为有标记。 + + :param left: 范围起始位置 + :param right: 范围结束位置(不包括) + :return: 如果范围内包含标记点返回 True,否则 False。 + """ + i, j = br(self._X, left), bl(self._X, right) + return i == j and i % 2 == 1 + + def removeRange(self, left, right): + """ + 移除指定范围内的所有整数。具体逻辑为:在满足条件的位置插入边界值。 + + :param left: 范围起始位置 + :param right: 范围结束位置(不包括) + """ i, j = bl(self._X, left), br(self._X, right) - self._X[i:j] = [left]*(i%2 == 1) + [right]*(j%2 == 1) \ No newline at end of file + self._X[i:j] = [left]*(i % 2 == 1) + [right]*(j % 2 == 1) diff --git a/solutions/python3/716.py b/solutions/python3/716.py index e308696..cc3ad27 100644 --- a/solutions/python3/716.py +++ b/solutions/python3/716.py @@ -1,25 +1,30 @@ + class Node: + # 节点类,用于存储值和索引,并提供指向前驱和后继节点的引用 def __init__(self, value, index): - self.val = value - self.i = index - self.pre = self.next = None -class MaxStack: + self.val = value # 值 + self.i = index # 索引 + self.pre = None # 前驱节点 + self.next = None # 后继节点 +class MaxStack: + def __init__(self): """ - initialize your data structure here. + 初始化数据结构。 """ - self.heap = [] - self.Nodes = {} - self.head = self.tail = Node(0, -1) - self.head.next = self.tail + self.heap = [] # 最大堆,用于快速获取最大值 + self.Nodes = {} # 字典,存储节点以快速查找 + self.head = Node(0, -1) # 头节点 + self.tail = Node(0, -2) # 尾节点 + self.head.next = self.tail # 链表连接 self.tail.pre = self.head - def push(self, x): """ :type x: int :rtype: void + 在链表尾部插入新节点,并在堆中插入对应元组 (-x, -i)。 """ newNode = Node(x, self.tail.pre.i + 1) newNode.pre = self.tail.pre @@ -31,6 +36,7 @@ def push(self, x): def pop(self): """ :rtype: int + 删除尾部节点,并在堆中移除对应元组。 """ node = self.tail.pre node.pre.next = self.tail @@ -43,12 +49,14 @@ def pop(self): def top(self): """ :rtype: int + 返回尾部节点的值。 """ return self.tail.pre.val def peekMax(self): """ :rtype: int + 调整堆以确保最大值在堆顶,返回最大值(若无效则抛出异常)。 """ while -self.heap[0][1] not in self.Nodes or self.Nodes[-self.heap[0][1]].val != -self.heap[0][0]: heapq.heappop(self.heap) @@ -57,6 +65,8 @@ def peekMax(self): def popMax(self): """ :rtype: int + 移除堆顶元素对应的节点,并调整链表以移除该节点。 + 返回最大值(若无效则抛出异常)。 """ while -self.heap[0][1] not in self.Nodes or self.Nodes[-self.heap[0][1]].val != -self.heap[0][0]: heapq.heappop(self.heap) @@ -64,12 +74,3 @@ def popMax(self): node.pre.next = node.next node.next.pre = node.pre return -heapq.heappop(self.heap)[0] - - -# Your MaxStack object will be instantiated and called as such: -# obj = MaxStack() -# obj.push(x) -# param_2 = obj.pop() -# param_3 = obj.top() -# param_4 = obj.peekMax() -# param_5 = obj.popMax() \ No newline at end of file diff --git a/solutions/python3/717.py b/solutions/python3/717.py index 5ba7942..221753e 100644 --- a/solutions/python3/717.py +++ b/solutions/python3/717.py @@ -1,10 +1,17 @@ + class Solution: def isOneBitCharacter(self, bits): """ - :type bits: List[int] - :rtype: bool + 判断最后一个字符是否为1位字符 + + 英文注释: + Determine whether the last character is a 1-bit character. """ while bits: - last=bits.pop(0) - if last==1:bits.pop(0) - return True if last==0 else False \ No newline at end of file + # 弹出第一个元素,若为1,则再弹出一个 + first = bits.pop(0) + if first == 1: + bits.pop(0) + + # 判断最后一个剩余的字符是否为0 + return last == 0 if len(bits) > 0 else True diff --git a/solutions/python3/718.py b/solutions/python3/718.py index 35b7bc5..45f4b4b 100644 --- a/solutions/python3/718.py +++ b/solutions/python3/718.py @@ -1,8 +1,22 @@ + class Solution: + # 定义一个类来解决寻找两个数组最长相同子数组的问题 + def findLength(self, A, B): + # 在A和B的开始和结束添加特殊字符,方便匹配 A, res, sub = "X%sX" % "X".join(map(str, A)), 0, "X" + for num in B: + # 将当前数字追加到子字符串中,并在后面加上特殊字符 sub += str(num) + "X" - if sub in A: res += 1 - else: sub = sub[sub[1:].index("X") + 1:] - return res \ No newline at end of file + + # 如果新的子字符串存在于A中,说明找到了一个匹配的子数组 + if sub in A: + res += 1 + + # 否则,从子字符串中去掉最旧的一个数字,继续寻找 + else: + sub = sub[sub[1:].index("X") + 1:] + + return res # 返回找到的最长相同子数组的数量 + diff --git a/solutions/python3/719.py b/solutions/python3/719.py index c1e922f..80be42b 100644 --- a/solutions/python3/719.py +++ b/solutions/python3/719.py @@ -1,14 +1,27 @@ + class Solution(object): + # 计算数组中差值不超过给定值的对数 def countPairsLTE(self, array, value): - return sum(bisect.bisect_right(array, array[i] + value, lo = i) - i - 1 for i in range(len(array))) - + # 使用bisect_right查找大于array[i] + value的第一个位置,减去i和1得到满足条件的对数 + return sum(bisect.bisect_right(array, array[i] + value, lo=i) - i - 1 for i in range(len(array))) + + # 找到差值小于等于k的第k个最小值 def smallestDistancePair(self, nums, k): + # 对数组进行排序,方便后续二分查找 nums.sort() + + # 初始化low和high,分别为相邻元素最大差值和整个数组的最大差值 low, high = min([nums[i + 1] - nums[i] for i in range(len(nums) - 1)]), nums[-1] - nums[0] + + # 二分查找过程 while low < high: mid = (low + high) // 2 + + # 判断mid是否满足条件:差值不超过mid的对数是否大于等于k if self.countPairsLTE(nums, mid) < k: low = mid + 1 else: high = mid - return low \ No newline at end of file + + # 返回最终结果 + return low diff --git a/solutions/python3/72.py b/solutions/python3/72.py index 30a4a90..f22f734 100644 --- a/solutions/python3/72.py +++ b/solutions/python3/72.py @@ -1,12 +1,31 @@ + class Solution: def minDistance(self, w1: str, w2: str) -> int: + """ + 计算两个字符串的最小编辑距离。 + + 参数: + w1 (str): 第一个源字符串 + w2 (str): 第二个目标字符串 + + 返回: + int: 最小编辑距离 + """ + # 初始化动态规划表 dp = [[0] * (len(w2) + 1) for i in range(len(w1) + 1)] + + # 填充第一行和第一列 for i in range(len(w1) + 1): - for j in range(len(w2) + 1): - if not (i and j): - dp[i][j] = i or j - elif w1[i - 1] == w2[j - 1]: - dp[i][j] += dp[i - 1][j - 1] + dp[i][0] = i + for j in range(len(w2) + 1): + dp[0][j] = j + + # 动态规划计算最小编辑距离 + for i in range(1, len(w1) + 1): + for j in range(1, len(w2) + 1): + if w1[i - 1] == w2[j - 1]: + dp[i][j] = dp[i - 1][j - 1] else: - dp[i][j] += min(dp[i - 1][j], dp[i][j - 1], dp[i - 1][j - 1]) + 1 - return dp[-1][-1] \ No newline at end of file + dp[i][j] = min(dp[i - 1][j], dp[i][j - 1], dp[i - 1][j - 1]) + 1 + + return dp[-1][-1] diff --git a/solutions/python3/720.py b/solutions/python3/720.py index 697d27d..4b2a820 100644 --- a/solutions/python3/720.py +++ b/solutions/python3/720.py @@ -1,9 +1,22 @@ + class Solution: def longestWord(self, words): """ :type words: List[str] :rtype: str + + 英文注释:Given a list of strings, find the longest string that is composed only of + valid prefixes present in the input list. If there are multiple such + strings of the same length, return any one of them. + + 中文注释:给定一个字符串列表,找出由输入列表中的有效前缀组成的最长字符串。如果有多个相同长度的符合要求的字符串, + 返回任意一个即可。 """ - for w in sorted(words, key = lambda x: (-len(x), x)): - if all([True if w[:i] in set(words) - {w} else False for i in range(1, len(w))]): return w - return "" \ No newline at end of file + # 优化:使用集合存储words以提高查找速度 + word_set = set(words) + + for w in sorted(words, key=lambda x: (-len(x), x)): + # 检查w的所有前缀是否都在word_set中(除了w本身) + if all(w[:i] in word_set - {w} for i in range(1, len(w))): + return w + return "" diff --git a/solutions/python3/721.py b/solutions/python3/721.py index 899ea68..55a9158 100644 --- a/solutions/python3/721.py +++ b/solutions/python3/721.py @@ -1,18 +1,29 @@ + class Solution: def accountsMerge(self, accounts): + # 使用字典存储每个邮件地址的邻接关系,并记录所有邮箱的所有者 def explore(mail, q): q += mail, visited.add(mail) for v in edges[mail]: - if v not in visited: explore(v, q) + if v not in visited: + explore(v, q) # 深度优先搜索,将未访问过的邻居加入队列 return q + + # 初始化邻接关系表、邮箱所有者字典以及已访问集合和结果列表 edges, owner, visited, res = collections.defaultdict(list), {}, set(), [] + for acc in accounts: + # 记录每个账户的首个元素作为所有者信息,其余元素表示联系人邮件地址 owner[acc[1]] = acc[0] - for i in range(1, len(acc) - 1): + for i in range(1, len(acc) - 1): if acc[i] != acc[i + 1]: - edges[acc[i]] += acc[i + 1], + edges[acc[i]] += acc[i + 1], # 添加邻接关系,确保对称性 edges[acc[i + 1]] += acc[i], + for acc in accounts: - if acc[1] not in visited: res += [acc[0]] + sorted(explore(acc[1], [])), - return res \ No newline at end of file + # 如果当前账户的所有者还未被访问过,则执行深度优先搜索 + if acc[1] not in visited: + res += [acc[0]] + sorted(explore(acc[1], [])), # 将所有者的名称和按顺序的邮件地址添加到结果列表 + + return res diff --git a/solutions/python3/722.py b/solutions/python3/722.py index 27daf0e..0b64e52 100644 --- a/solutions/python3/722.py +++ b/solutions/python3/722.py @@ -1,17 +1,32 @@ + class Solution: def removeComments(self, source): + # 初始化结果列表,块注释标志,当前行是否在注释中以及块注释开始位置 res, block, cont, blockStart = [], False, False, -1 - for line in source: - if not cont: cache = "" - for i, c in enumerate(line): - if not block: cache += c - if cache[-2:] == "//": - cache = cache[:-2] + + for line in source: # 遍历每一行代码 + if not cont: cache = "" # 如果当前行不是在多行字符串中,则初始化缓存 + + for i, c in enumerate(line): # 遍历当前行中的每个字符 + if not block: + cache += c # 当前不在块注释中,将字符添加到缓存 + + if cache[-2:] == "//": # 如果缓存的最后两个字符是单行注释 + cache = cache[:-2] # 去掉注释部分并跳出循环 break - elif cache[-2:] == "/*": blockStart, cache, block = i, cache[:-2], True - elif line[i - 1:i + 1] == "*/" and blockStart < i - 1: block = False - if not block: + + elif cache[-2:] == "/*": + blockStart, cache, block = i, cache[:-2], True # 找到块注释开始位置,更新缓存和块注释标志 + + elif line[i - 1:i + 1] == "*/" and blockStart < i - 1: + # 如果找到块注释结束符且起始位置已确定 + block = False # 结束块注释状态 + + if not block: + # 当前行没有在多行字符串中,将缓存添加到结果列表中 if cache: res += cache, - cont = False - else: cont, blockStart = True, -1 - return res \ No newline at end of file + + else: # 如果当前行在多行字符串中,则保持状态并重置块注释开始位置 + cont, blockStart = True, -1 + + return res # 返回处理后的代码列表 diff --git a/solutions/python3/723.py b/solutions/python3/723.py index 025f5d7..d7c6a34 100644 --- a/solutions/python3/723.py +++ b/solutions/python3/723.py @@ -1,23 +1,52 @@ + class Solution: def candyCrush(self, board): + """ + 解决糖果粉碎问题的类方法 + + :param board: 游戏棋盘,二维列表表示 + :return: 经过一系列操作后的最终状态的棋盘 + """ + m, n = len(board), len(board[0]) + def gravity(): + """ + 重力作用:将每列中零元素填充到下部空位 + + 遍历每一列,从底部开始取非零值,并将其存入栈。再从顶部开始填充值至该列。 + """ for j in range(n): stack = [board[i][j] for i in range(m - 1, -1, -1) if board[i][j] > 0] - stack += [0] * (m - len(stack)) - for i in range(m): board[i][j] = stack.pop() + stack += [0] * (m - len(stack)) + for i in range(m): + board[i][j] = stack.pop() + def crush(): + """ + 粉碎操作:检查并标记可以粉碎的糖果 + + 遍历每一行和列,寻找连续相等绝对值的三个糖果进行标记。 + 如果有多个位置被标记,则返回True表示需要执行一次gravity()操作;否则返回False表示无需进一步操作。 + """ crush = False for i in range(m): for j in range(n): - if j > 1 and board[i][j] > 0 and board[i][j] == abs(board[i][j - 1]) == abs(board[i][j - 2]): + # 检查水平方向是否有连续相等的三个糖果 + if j > 1 and board[i][j] > 0 and abs(board[i][j]) == abs(board[i][j - 1]) == abs(board[i][j - 2]): board[i][j - 2:j + 1] = [-abs(board[i][j]) for _ in range(3)] crush = True - if i > 1 and board[i][j] != 0 and abs(board[i][j]) == abs(board[i - 1][j]) == abs(board[i - 2][j]): - if board[i][j] > 0: board[i][j] *= -1 - if board[i - 1][j] > 0: board[i - 1][j] *= -1 - if board[i - 2][j] > 0: board[i - 2][j] *= -1 + # 检查垂直方向是否有连续相等的三个糖果 + if i > 1 and abs(board[i][j]) != 0 and abs(board[i][j]) == abs(board[i - 1][j]) == abs(board[i - 2][j]): + board[i][j] *= -1 # 粉碎当前及下方两行的正数糖果 + if j > 0: + board[i - 1][j] *= -1 # 同上,处理右侧相邻列 + if i > 0: + board[i - 2][j] *= -1 # 同上,处理左侧相邻列 crush = True - return crush - while crush(): gravity() - return board \ No newline at end of file + return crush + + while crush(): + gravity() + + return board diff --git a/solutions/python3/724.py b/solutions/python3/724.py index 189e21b..e680bba 100644 --- a/solutions/python3/724.py +++ b/solutions/python3/724.py @@ -1,9 +1,20 @@ + class Solution: + # 定义一个类来解决寻找数组的“平衡索引”问题 + def pivotIndex(self, nums: List[int]) -> int: + # 计算整个数组元素之和 sm = sum(nums) - cur = 0 + + cur = 0 # 当前累积和 + for i in range(len(nums)): + # 如果当前累积和等于剩余部分的总和,返回索引i if cur == sm - cur - nums[i]: return i + + # 更新当前累积和 cur += nums[i] - return -1 \ No newline at end of file + + # 如果没有找到平衡索引,则返回-1 + return -1 diff --git a/solutions/python3/725.py b/solutions/python3/725.py index b7dd08f..96cf0e7 100644 --- a/solutions/python3/725.py +++ b/solutions/python3/725.py @@ -1,29 +1,46 @@ + class Solution: def splitListToParts(self, root: ListNode, k: int) -> List[ListNode]: + """ + 计算链表节点总数并确定每部分的长度和剩余节点数。 + + :param root: 链表头节点 + :param k: 分割后的最大数量 + :return: 返回分割后的链表头节点列表 + """ n = 0 node = root + # 计算链表总长度 while node: n += 1 node = node.next - count = n // k - residual = n % k + + count = n // k # 每部分的基本长度 + residual = n % k # 剩余节点数,用于分配到前几部分 i = 0 - ret = [[] for _ in range(k)] + ret = [[] for _ in range(k)] # 初始化结果列表,大小为k的空列表 prev = root while prev and k > 0: - node = prev - leftover = count - ret[i] = node + node = prev # 当前部分的起始节点 + leftover = count # 每个部分的基本长度计数器 + + ret[i] = node # 将当前部分的头节点添加到结果列表中 i += 1 - while node and leftover > 1: + + while node and leftover > 1: # 遍历当前部分,直到达到基本长度减一 node = node.next leftover -= 1 + if node and count != 0 and residual: + # 如果还有剩余节点且当前部分还未满,则继续分配一个节点 node = node.next residual -= 1 - prev = node.next if node else None - if node: + + prev = node.next if node else None # 更新prev指针,指向下一个部分的起始位置或None + if node: # 断开当前部分与后续链表的连接 node.next = None - k -= 1 - return ret + + k -= 1 # 减少剩余的部分数量 + + return ret # 返回分割后的链表头节点列表 diff --git a/solutions/python3/726.py b/solutions/python3/726.py index 47630d9..87ef5b9 100644 --- a/solutions/python3/726.py +++ b/solutions/python3/726.py @@ -1,22 +1,32 @@ + class Solution: - def countOfAtoms(self, formula): - dic, coeff, stack, elem, cnt, i = collections.defaultdict(int), 1, [], "", 0, 0 + def countOfAtoms(self, formula: str) -> str: + # 使用collections.defaultdict来存储元素及其个数,初始化系数为1 + dic, coeff, stack, elem, cnt, i = collections.defaultdict(int), 1, [], "", 0, 0 + for c in formula[::-1]: if c.isdigit(): + # 如果是数字,则计算当前数字并加到计数中 cnt += int(c) * (10 ** i) i += 1 elif c == ")": + # 如果是右括号,将系数压入栈,并更新当前系数为栈顶元素 stack.append(cnt) coeff *= cnt i = cnt = 0 elif c == "(": + # 如果是左括号,弹出栈顶元素作为当前系数的除数 coeff //= stack.pop() i = cnt = 0 elif c.isupper(): + # 如果是大写字母,则初始化或更新元素名称,并将之前累积的元素个数存储到字典中 elem += c dic[elem[::-1]] += (cnt or 1) * coeff elem = "" i = cnt = 0 elif c.islower(): + # 如果是小写字母,则继续构建当前元素名称 elem += c - return "".join(k + str(v > 1 and v or "") for k, v in sorted(dic.items())) \ No newline at end of file + + # 将字典中的元素及其个数按照字母顺序输出,处理单个元素的情况 + return "".join(k + (str(v > 1 and v or "") or "") for k, v in sorted(dic.items())) diff --git a/solutions/python3/727.py b/solutions/python3/727.py index 948cad2..410bc58 100644 --- a/solutions/python3/727.py +++ b/solutions/python3/727.py @@ -1,16 +1,32 @@ + class Solution: + # 定义一个解决方案类 + def minWindow(self, S: str, T: str) -> str: + # 寻找字符串S中包含子串T的最小子串 + def dfs(i, j): - if j == len(T): return i + """ + 深度优先搜索,用于查找从索引i开始匹配T[j]及其之后的所有字符的最小起始位置 + :param i: 当前搜索起始索引 + :param j: 匹配模式字符串T中当前匹配到的位置 + :return: 从S中找到的第一个匹配子串起点索引 + """ + if j == len(T): + return i if (i, j) not in memo: ind = S.find(T[j], i + 1) + # 如果找不到,设置一个非常大的值;否则递归调用dfs继续查找下一个匹配字符的位置 memo[(i, j)] = float('inf') if ind == -1 else dfs(ind, j + 1) return memo[(i, j)] - + l, res, memo = float('inf'), '', {} + # 初始化结果长度l为无穷大,结果res为空字符串,memo用于记忆化搜索 for i, s in enumerate(S): if s == T[0]: + # 如果当前字符与T的第一个字符匹配,则尝试从该位置开始查找最小子串 j = dfs(i, 1) if j - i < l: + # 更新结果,如果找到更短的子串则替换 l, res = j - i, S[i:j + 1] - return res \ No newline at end of file + return res # 返回最小窗口子串 diff --git a/solutions/python3/728.py b/solutions/python3/728.py index 2e4d4ac..5a7f1cf 100644 --- a/solutions/python3/728.py +++ b/solutions/python3/728.py @@ -1,8 +1,14 @@ + class Solution: - def selfDividingNumbers(self, left, right): + def selfDividingNumbers(self, left: int, right: int) -> list[int]: """ - :type left: int - :type right: int - :rtype: List[int] + :param left: 左边界(整数) + :param right: 右边界(整数) + :return: 在左闭右闭区间 [left, right] 内的所有自除数 + 自除数是指可以被它包含的每一位数整除的数。 + + :example: + left = 1, right = 22 + 返回值:[1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 15, 22] """ - return [num for num in range(left,right+1) if len([char for char in str(num) if int(char)!=0 and num%int(char)==0])==len(str(num)) ] \ No newline at end of file + return [num for num in range(left, right + 1) if len([char for char in str(num) if int(char) != 0 and num % int(char) == 0]) == len(str(num))] diff --git a/solutions/python3/729.py b/solutions/python3/729.py index 1166a02..3a6eeb2 100644 --- a/solutions/python3/729.py +++ b/solutions/python3/729.py @@ -1,38 +1,72 @@ + class Node: - def __init__(self,s,e): - self.e = e - self.s = s - self.left = None - self.right = None + def __init__(self, s, e): + """ + 初始化节点类,用于二叉树结构。 + + :param s: 起始时间 + :param e: 结束时间 + """ + self.e = e # 结束时间 + self.s = s # 开始时间 + self.left = None # 左子节点 + self.right = None # 右子节点 + class MyCalendar: def __init__(self): + """ + 初始化日历类。 + + :param root: 根节点,初始为空 + """ self.root = None - def book_helper(self,s,e,node): - if s>=node.e: - if node.right: return self.book_helper(s,e,node.right) + def book_helper(self, s, e, node): + """ + 辅助函数用于递归地在二叉树中预定时间。 + + :param s: 起始时间 + :param e: 结束时间 + :param node: 当前节点 + :return: 是否成功预定,True表示成功,False表示失败 + """ + if s >= node.e: + # 如果新预定的结束时间在当前节点开始时间之后 + if node.right: + # 有右子节点则递归检查右子树 + return self.book_helper(s, e, node.right) else: - node.right = Node(s,e) + # 没有右子节点,创建一个并返回成功标志 + node.right = Node(s, e) return True - elif e<=node.s: - if node.left: return self.book_helper(s,e,node.left) + elif e <= node.s: + # 如果新预定的开始时间在当前节点结束时间之前 + if node.left: + # 有左子节点则递归检查左子树 + return self.book_helper(s, e, node.left) else: - node.left = Node(s,e) + # 没有左子节点,创建一个并返回成功标志 + node.left = Node(s, e) return True - else: return False + else: + return False # 时间冲突 + def book(self, start, end): """ - :type start: int - :type end: int - :rtype: bool + 预定时间。 + + :type start: int 起始时间 + :type end: int 结束时间 + :rtype: bool 返回是否成功预定 """ if not self.root: - self.root = Node(start,end) + # 如果根节点为空,初始化树并返回成功标志 + self.root = Node(start, end) return True - return self.book_helper(start,end,self.root) + return self.book_helper(start, end, self.root) -# Your MyCalendar object will be instantiated and called as such: +# 示例用法: # obj = MyCalendar() -# param_1 = obj.book(start,end) \ No newline at end of file +# param_1 = obj.book(start, end) # 预定时间 diff --git a/solutions/python3/73.py b/solutions/python3/73.py index f7b1296..2858eb9 100644 --- a/solutions/python3/73.py +++ b/solutions/python3/73.py @@ -1,16 +1,28 @@ + class Solution: + # 解决矩阵置零问题,将值为0的元素所在行和列全部置为0 def setZeroes(self, matrix): - m, n, x = len(matrix), len(matrix and matrix[0]), 0 - for i in range(m): + m, n, x = len(matrix), len(matrix[0] if matrix else []), 0 + + # 向下传播0的影响 + for i in range(m - 1): for j in range(n): - if i < m - 1 and not matrix[i][j] and matrix[i + 1][j]: matrix[i + 1][j] = None - for i in range(m - 1, -1, -1): + if not matrix[i][j] and matrix[i + 1][j]: + matrix[i + 1][j] = None + + # 向上传播0的影响 + for i in range(m - 2, -1, -1): for j in range(n - 1, -1, -1): - if i > 0 and not matrix[i][j] and matrix[i - 1][j]: matrix[i - 1][j] = None + if not matrix[i][j] and matrix[i + 1][j]: + matrix[i][j] = None + + # 确定0的具体位置并置零 while x < m: y = 0 while y < n: - if matrix[x][y] == 0: matrix[x], y = [0] * n, n - elif not matrix[x][y]: matrix[x][y] = 0 + if matrix[x][y] == 0: + matrix[x] = [0] * n + elif not matrix[x][y]: + matrix[x][y] = 0 y += 1 - x += 1 \ No newline at end of file + x += 1 diff --git a/solutions/python3/730.py b/solutions/python3/730.py index b2c9512..2393f4e 100644 --- a/solutions/python3/730.py +++ b/solutions/python3/730.py @@ -1,13 +1,36 @@ + class Solution: - def countPalindromicSubsequences(self, S): + # 定义一个解决类,用于计数回文子序列 + + def countPalindromicSubsequences(self, S: str) -> int: + # 设置模数和缓存字典以避免重复计算 mod, memo = 10 ** 9 + 7, {} - def dfs(i, j): + + def dfs(i: int, j: int) -> int: + # 如果子问题已经解决过,则直接返回结果 if (i, j) not in memo: cnt = 0 + + # 遍历'a', 'b', 'c', 'd'四个字符,尝试找到它们在当前子串中的位置 for x in "abcd": - try: l, r = S[i:j + 1].index(x) + i, S[i:j + 1].rindex(x) + i - except: continue - cnt += l != r and dfs(l + 1, r - 1) + 2 or 1 + try: + # 找到第一个和最后一个x的位置 + l, r = S[i:j + 1].index(x) + i, S[i:j + 1].rindex(x) + i + + # 如果左右边界不同,说明有内部子序列,则递归计算中间部分的回文数并加2(包含边界) + if l != r: + cnt += dfs(l + 1, r - 1) + 2 + else: + # 如果左右边界相同,直接计数+1 + cnt += 1 + + except ValueError: + # 没有找到对应字符时跳过此次迭代 + continue + memo[(i, j)] = cnt % mod + return memo[(i, j)] - return dfs(0, len(S) - 1) \ No newline at end of file + + # 从整个字符串的两端开始递归计算回文子序列数 + return dfs(0, len(S) - 1) diff --git a/solutions/python3/731.py b/solutions/python3/731.py index 1300c22..c120bc8 100644 --- a/solutions/python3/731.py +++ b/solutions/python3/731.py @@ -1,14 +1,33 @@ + class MyCalendarTwo: + """ + MyCalendarTwo 类用于管理两个重叠区间,实现日程安排功能。 + 中文说明:MyCalendarTwo 类用于管理和处理双重预订的时间段,支持日程预约功能。 + """ + def __init__(self): - self.overlaps = [] - self.calendar = [] + """ + 初始化时创建空的重叠区间列表和日程安排列表。 + 中文说明:初始化对象时,创建一个空的重叠区间列表和一个空的日程安排列表。 + """ + self.overlaps = [] + self.calendar = [] - def book(self, start, end): + def book(self, start: int, end: int) -> bool: + """ + 预约一个新的日程,并检查是否有与现有日程冲突的部分,若有,则加入重叠区间列表中; + 如果没有冲突,则添加到日程安排列表中。 + 中文说明:预约一个新时间段,并检查是否存在与其他已预订时间段的重叠。若存在重叠, + 则将重叠部分添加到重叠区间列表中;否则将其添加到日程安排列表中。 + """ for i, j in self.overlaps: - if start < j and end > i: + if start < j and end > i: # 检查是否有新的重叠 return False + for i, j in self.calendar: - if start < j and end > i: - self.overlaps.append((max(start, i), min(end, j))) - self.calendar.append((start, end)) - return True \ No newline at end of file + if start < j and end > i: # 确认新预定是否与现有日程有冲突 + self.overlaps.append((max(start, i), min(end, j))) # 记录重叠区间 + + self.calendar.append((start, end)) # 添加新的日程安排 + return True + \ No newline at end of file diff --git a/solutions/python3/732.py b/solutions/python3/732.py index bd8d007..1195cba 100644 --- a/solutions/python3/732.py +++ b/solutions/python3/732.py @@ -1,13 +1,28 @@ + class MyCalendarThree: def __init__(self): + """ + 初始化日历对象。 + Initialize the calendar object. + """ self.times = [] - def book(self, start, end): - bisect.insort(self.times, (start, 1)) - bisect.insort(self.times, (end, -1)) + def book(self, start: int, end: int) -> int: + """ + 为给定的 'start' 和 'end' 添加一个预订。 + Add a booking for given 'start' and 'end'. + + :param start: 预订开始时间 + :param end: 预订结束时间 + :return: 返回当前最大重叠次数 + """ + bisect.insort(self.times, (start, 1)) # 插入开始时间,权重为1(表示增加一个活动) + bisect.insort(self.times, (end, -1)) # 插入结束时间,权重为-1(表示减少一个活动) + res = cur = 0 for _, x in self.times: - cur += x - res = max(res, cur) - return res \ No newline at end of file + cur += x # 累加当前活动数 + res = max(res, cur) # 更新最大重叠次数 + + return res diff --git a/solutions/python3/733.py b/solutions/python3/733.py index 9f7c028..410c34b 100644 --- a/solutions/python3/733.py +++ b/solutions/python3/733.py @@ -1,12 +1,17 @@ + class Solution: def floodFill(self, image, sr, sc, newColor): + # 获取初始颜色和图片尺寸 - Initial color and dimensions of the image old, m, n = image[sr][sc], len(image), len(image[0]) - if old != newColor: - q = collections.deque([(sr, sc)]) - while q: - i, j = q.popleft() - image[i][j] = newColor - for x, y in ((i - 1, j), (i + 1, j), (i, j - 1), (i, j + 1)): - if 0 <= x < m and 0 <= y < n and image[x][y] == old: - q.append((x, y)) - return image \ No newline at end of file + + if old != newColor: # 如果初始颜色不等于新颜色,进行填充操作 - If initial color is not equal to new color, perform filling operation + q = collections.deque([(sr, sc)]) # 初始化队列 - Initialize queue with starting position + while q: # 当队列不为空时循环 - While the queue is not empty + i, j = q.popleft() # 弹出队列中的元素 - Pop an element from the queue + image[i][j] = newColor # 将当前位置的颜色更新为新颜色 - Update current position's color to new color + + for x, y in ((i - 1, j), (i + 1, j), (i, j - 1), (i, j + 1)): # 遍历四个方向 - Traverse four directions + if 0 <= x < m and 0 <= y < n and image[x][y] == old: # 检查边界条件和颜色是否匹配 - Check boundary conditions and color match + q.append((x, y)) # 将符合条件的位置加入队列 - Append valid positions to the queue + + return image # 返回填充后的图像 - Return the filled image diff --git a/solutions/python3/734.py b/solutions/python3/734.py index 9e7e09f..94a4b1d 100644 --- a/solutions/python3/734.py +++ b/solutions/python3/734.py @@ -1,7 +1,23 @@ + class Solution: def areSentencesSimilar(self, words1: List[str], words2: List[str], pairs: List[List[str]]) -> bool: + """ + 判断两个句子是否相似。如果一个词组与另一个词组相同或者在给定的词对中出现,则认为两个句子相似。 + + 参数: + - words1: 第一个句子,由多个单词组成 + - words2: 第二个句子,由多个单词组成 + - pairs: 词对列表,表示可互换的词语 + + 返回值: + 如果两个句子相似则返回 True,否则返回 False + """ + + # 使用字典存储每个词出现的所有相似词(双向关系) sim = collections.defaultdict(set) for a, b in pairs: - sim[a].add(b) - sim[b].add(a) - return len(words1) == len(words2) and all(w1 == w2 or w2 in sim[w1] for w1, w2 in zip(words1, words2)) \ No newline at end of file + sim[a].add(b) # 将a添加到b的相似词集合中 + sim[b].add(a) # 将b添加到a的相似词集合中 + + # 检查两个句子长度是否相同,且每个单词对是否满足相似条件 + return len(words1) == len(words2) and all(w1 == w2 or w2 in sim[w1] for w1, w2 in zip(words1, words2)) diff --git a/solutions/python3/735.py b/solutions/python3/735.py index 2296703..c8a8663 100644 --- a/solutions/python3/735.py +++ b/solutions/python3/735.py @@ -1,14 +1,29 @@ + class Solution: def asteroidCollision(self, asteroids): """ :type asteroids: List[int] :rtype: List[int] """ + # 使用栈来模拟碰撞过程 + # 中文:使用栈来模拟小行星碰撞的过程 stack = [] + for asteroid in asteroids: + # 将当前小行星加入栈中 stack.append(asteroid) + + # 只要栈中有两个元素且满足左正右负的情况,就进行碰撞检查 while len(stack) > 1 and stack[-2] > 0 and stack[-1] < 0: - if stack[-2] < abs(stack[-1]): stack[-2] = stack[-1] - elif stack[-2] == abs(stack[-1]): stack.pop() - stack.pop() - return stack \ No newline at end of file + # 中文:如果右侧小行星的绝对值大于左侧,则右侧存活 + if abs(stack[-1]) > stack[-2]: + stack.pop(-2) + # 如果左侧小行星完全吸收右侧,移除左侧 + elif abs(stack[-1]) == stack[-2]: + stack.pop(-2) + stack.pop() + # 否则左侧小行星被摧毁 + else: + stack.pop() + + return stack diff --git a/solutions/python3/736.py b/solutions/python3/736.py index 6ae6d8e..91d04a1 100644 --- a/solutions/python3/736.py +++ b/solutions/python3/736.py @@ -1,13 +1,19 @@ + class Solution: def evaluate(self, expression): + # 初始化作用域和表达式项列表,根节点默认为"root" scopes, items = [{}], [["root"]] + for item in expression.replace(")", " )").split(): if item[0] == "(": + # 遇到新的表达式块,添加新项并判断当前操作类型 items.append([item[1:]]) if item[1:] == "let": scopes.append(dict(scopes[-1])) continue + elif item == ")": + # 结束一个表达式块,根据块的类型进行计算或返回结果,并更新作用域和项列表 if items[-1][0] == "add": item = str(int(items[-1][1]) + int(items[-1][-1])) elif items[-1][0] == "mult": @@ -18,9 +24,17 @@ def evaluate(self, expression): item = scopes[-1][item] scopes.pop() items.pop() + + # 判断当前项是否已在作用域中,并根据情况进行值替换或更新 if item in scopes[-1] and (items[-1][0] != "let" or len(items[-1]) % 2 == 0): item = scopes[-1][item] + + # 处理"let"表达式,记录变量名和对应值 if items[-1][0] == "let" and item.lstrip("-").isdigit(): scopes[-1][items[-1][-1]] = item + + # 将当前项添加到当前操作的末尾 items[-1].append(item) - return int(items[-1][-1]) \ No newline at end of file + + # 返回最终结果 + return int(items[-1][-1]) diff --git a/solutions/python3/737.py b/solutions/python3/737.py index 8a6c98f..566a8d4 100644 --- a/solutions/python3/737.py +++ b/solutions/python3/737.py @@ -1,23 +1,44 @@ + class Solution: - def areSentencesSimilarTwo(self, words1, words2, pairs): + def areSentencesSimilarTwo(self, words1: list[str], words2: list[str], pairs: list[tuple[str, str]]) -> bool: + """ + 判断两个句子是否相似。句子的相似性由单词对定义,如果两个单词在任何一个对中,则它们是相似的。 + + :param words1: 第一个句子的单词列表 + :param words2: 第二个句子的单词列表 + :param pairs: 一系列单词对的集合 + :return: 如果两句话通过给定的规则可以互换则返回 True,否则返回 False + """ + def dfs(node, Id): + """深度优先搜索函数,用于标记节点所属连通分量""" cc[node] = Id for v in adj[node]: if v not in cc: dfs(v, Id) + l1, l2, adj, cc = len(words1), len(words2), collections.defaultdict(set), {} + + # 如果两个句子长度不同,直接返回 False if l1 != l2: return False + + # 构建图的邻接表表示形式 for a, b in pairs: adj[a].add(b) adj[b].add(a) + + # 使用 DFS 标记每个单词所在的连通分量 for Id, k in enumerate(adj): if k not in cc: dfs(k, Id) + + # 检查两个句子的对应位置上的单词是否相似 for w1, w2 in zip(words1, words2): if w1 not in cc or w2 not in cc: if w1 != w2: return False elif cc[w1] != cc[w2]: return False - return True \ No newline at end of file + + return True diff --git a/solutions/python3/738.py b/solutions/python3/738.py index a3f94d4..b7a797b 100644 --- a/solutions/python3/738.py +++ b/solutions/python3/738.py @@ -1,11 +1,20 @@ + class Solution: - def monotoneIncreasingDigits(self, N): + def monotoneIncreasingDigits(self, N: int) -> int: """ - :type N: int - :rtype: int + :type N: int # 输入整数N + :rtype: int # 返回一个整数 + + 解题思路:从右向左遍历数字的每一位,一旦发现某位比前一位小,则将该位置及其右边的所有位减一, + 直到找到第一个不满足单调递增的位置,然后将其左边所有位保持不变(减1操作),右边全部变为9。 """ n, pos = str(N), 0 for i, char in enumerate(n): - if i>0 and int(n[i])1 else int("9"*(len(n)-1-pos)) - elif i>0 and n[i] != n[i-1]: pos = i - return N \ No newline at end of file + # 如果当前位比前一位小,则需要调整数字使其单调递增 + if i > 0 and int(char) < int(n[i-1]): + return int("".join(n[:pos]) + str(int(n[pos])-1) + "9" * (len(n)-1-pos)) \ + if int(n[pos]) > 1 else int("9" * (len(n)-1-pos)) + # 记录第一个不满足单调递增的位置 + elif i > 0 and char != n[i-1]: + pos = i + return N diff --git a/solutions/python3/739.py b/solutions/python3/739.py index c0f1f0d..108578b 100644 --- a/solutions/python3/739.py +++ b/solutions/python3/739.py @@ -1,11 +1,23 @@ + class Solution: def dailyTemperatures(self, T: List[int]) -> List[int]: - res = [0] * len(T) - heap = [] - for j, t in enumerate(T): - while heap and heap[0][0] < t: - temp, i = heapq.heappop(heap) - res[i] = j - i - heapq.heappush(heap, (t, j)) - return res - \ No newline at end of file + """ + 定义一个解决方案类,用于解决每日气温问题。 + + 参数: + T (List[int]): 一维整数列表,表示每天的温度 + + 返回值: + res (List[int]): 一维整数列表,表示等待升温天数 + """ + res = [0] * len(T) # 初始化结果数组,长度与输入T相同,默认为0 + heap = [] # 初始化最小堆 + + for j, t in enumerate(T): # 遍历温度列表 + while heap and heap[0][0] < t: # 当堆顶元素小于当前温度时进行弹出操作 + temp, i = heapq.heappop(heap) # 弹出堆顶元素,并获取其索引和值 + res[i] = j - i # 计算等待天数并存储在结果数组中 + + heapq.heappush(heap, (t, j)) # 将当前温度及索引压入堆中 + + return res # 返回最终的结果数组 diff --git a/solutions/python3/74.py b/solutions/python3/74.py index 9a3bd66..16f59ed 100644 --- a/solutions/python3/74.py +++ b/solutions/python3/74.py @@ -1,4 +1,13 @@ + class Solution: - def searchMatrix(self, matrix, target): - ls = list(itertools.chain(*matrix)) - return ls and ls[bisect.bisect(ls, target) - 1] == target or False \ No newline at end of file + """定义一个Solution类,包含searchMatrix方法用于在矩阵中查找目标值""" + + def searchMatrix(self, matrix: list[list[int]], target: int) -> bool: + # 将二维列表展平为一维列表,并使用二分法查找目标值 + flat_list = list(itertools.chain(*matrix)) + + # 使用bisect模块的bisect函数进行二分查找,返回插入点索引减1的位置 + index = bisect.bisect(flat_list, target) - 1 + + # 判断找到的目标值是否等于目标值,并返回结果 + return flat_list[index] == target if index < len(flat_list) else False diff --git a/solutions/python3/740.py b/solutions/python3/740.py index 7584ef7..5861a4b 100644 --- a/solutions/python3/740.py +++ b/solutions/python3/740.py @@ -1,21 +1,36 @@ + class Solution: + # 定义一个类来解决删除并获得最大值的问题 + def deleteAndEarn(self, nums): - cnt, dp, maxs = collections.Counter(nums), {}, {} - nums = sorted(set(nums)) + """ + :type nums: List[int] + :rtype: int + """ + from collections import Counter + + cnt, dp, maxs = Counter(nums), {}, {} # 统计每个数字的出现次数,初始化动态规划字典dp和最大值字典maxs + nums = sorted(set(nums)) # 对nums去重并排序 + if len(nums) < 2: - return nums and nums[0] * cnt[nums[0]] or 0 + return nums and nums[0] * cnt[nums[0]] or 0 # 如果数字少于两个,直接返回第一个数的累积值 + for i in range(len(nums)): - dp[i] = nums[i] * cnt[nums[i]] + dp[i] = nums[i] * cnt[nums[i]] # 计算当前数字累积值并存入dp + if i >= 2: - if nums[i - 1] < nums[i] - 1: + if nums[i - 1] < nums[i] - 1: # 检查是否可以累加 dp[i] += maxs[i - 1] else: dp[i] += maxs[i - 2] - maxs[i] = max(dp[i], maxs[i - 1]) + maxs[i] = max(dp[i], maxs[i - 1]) # 更新最大值字典 + elif i: - if nums[i - 1] < nums[i] - 1: + if nums[i - 1] < nums[i] - 1: # 检查是否可以累加 dp[i] += dp[i - 1] - maxs[i] = max(dp[i], dp[i - 1]) + maxs[i] = max(dp[i], dp[i - 1]) # 更新最大值字典 + else: - maxs[i] = dp[i] - return max(dp[len(nums) - 1], dp[len(nums) - 2]) \ No newline at end of file + maxs[i] = dp[i] # 初始化第一个位置的最大值 + + return max(dp[len(nums) - 1], dp[len(nums) - 2]) # 返回最后两个累积值中的较大者 diff --git a/solutions/python3/741.py b/solutions/python3/741.py index a543ba5..294ad35 100644 --- a/solutions/python3/741.py +++ b/solutions/python3/741.py @@ -1,15 +1,44 @@ + class Solution(object): + # 定义一个解决方案类 + def cherryPickup(self, grid): - if grid[-1][-1] == -1: return 0 + # 检查右下角是否为-1,如果是则返回0 + if grid[-1][-1] == -1: + return 0 + memo, n = {}, len(grid) + # 使用字典memo存储已经计算过的结果以避免重复计算 + def dp(i1, j1, i2, j2): - if (i1, j1, i2, j2) in memo: return memo[(i1, j1, i2, j2)] - if n in (i1, j1, i2, j2) or -1 in (grid[i1][j1], grid[i2][j2]): return -1 - if i1 == i2 == j1 == j2 == n - 1: return grid[-1][-1] - mx = max(dp(i1+1, j1, i2+1, j2), dp(i1+1, j1, i2, j2+1), dp(i1, j1+1, i2+1, j2), dp(i1, j1+1, i2, j2+1)) - if mx == - 1: out = -1 - elif i1 == i2 and j1 == j2: out = mx + grid[i1][j1] - else: out = mx + grid[i1][j1] + grid[i2][j2] + # 检查状态是否已在memo中,如果是则直接返回 + if (i1, j1, i2, j2) in memo: + return memo[(i1, j1, i2, j2)] + + # 判断当前坐标是否越界或遇到-1 + if n in (i1, j1, i2, j2) or -1 in (grid[i1][j1], grid[i2][j2]): + return -1 + + # 如果两个机器人同时到达最后一个位置,直接返回其樱桃数量 + if i1 == i2 == j1 == j2 == n - 1: + return grid[-1][-1] + + # 计算四种移动方式的最大值 + mx = max(dp(i1+1, j1, i2+1, j2), dp(i1+1, j1, i2, j2+1), + dp(i1, j1+1, i2+1, j2), dp(i1, j1+1, i2, j2+1)) + + # 处理越界或遇到-1的情况 + if mx == -1: + out = -1 + elif i1 == i2 and j1 == j2: # 如果两个机器人在同一位置 + out = mx + grid[i1][j1] + else: + out = mx + grid[i1][j1] + grid[i2][j2] + + # 将结果存入memo以备后续使用 memo[(i1, j1, i2, j2)] = out + return out - return max(0, dp(0, 0, 0, 0)) \ No newline at end of file + + # 从起始点开始递归搜索最大樱桃数量 + return max(0, dp(0, 0, 0, 0)) diff --git a/solutions/python3/742.py b/solutions/python3/742.py index f565587..5f614ae 100644 --- a/solutions/python3/742.py +++ b/solutions/python3/742.py @@ -1,14 +1,29 @@ + # Definition for a binary tree node. -# class TreeNode: -# def __init__(self, x): -# self.val = x -# self.left = None -# self.right = None +class TreeNode: + def __init__(self, x): + self.val = x + self.left = None + self.right = None class Solution: - def findClosestLeaf(self, root, k): - adj, q, visited = collections.defaultdict(list), [], collections.defaultdict(int) + """ + 定义一个Solution类来解决寻找最接近叶子节点的问题。 + + 解题思路:使用深度优先搜索(DFS)构建图结构,然后使用广度优先搜索(BFS)从k开始寻找最近的叶子结点。 + """ + + def findClosestLeaf(self, root: TreeNode, k: int) -> int: + # 使用defaultdict存储节点之间的邻接关系 + adj = collections.defaultdict(list) + q = [] # 初始化队列用于BFS遍历 + visited = collections.defaultdict(int) # 记录已经访问过的节点 + def dfs(node): + """ + 深度优先搜索构建图结构,从root开始。 + 如果遇到目标节点k,将其加入队列q,并标记为已访问;对于每个子节点,建立双向连接并递归处理。 + """ if node: if node.val == k: q.append(node) @@ -21,14 +36,19 @@ def dfs(node): adj[node].append(node.right) adj[node.right].append(node) dfs(node.right) + + # 调用DFS初始化图结构 dfs(root) + while q: new = [] for node in q: + # 如果当前节点是叶子节点,直接返回其值 if not node.left and not node.right: return node.val + # 遍历邻接表中的所有连接节点 for v in adj[node]: if not visited[v.val]: visited[v.val] = 1 new.append(v) - q = new \ No newline at end of file + q = new # 更新队列 diff --git a/solutions/python3/743.py b/solutions/python3/743.py index c41b7f8..031edbd 100644 --- a/solutions/python3/743.py +++ b/solutions/python3/743.py @@ -1,12 +1,22 @@ + class Solution: + # 定义一个解决方案类 + def networkDelayTime(self, times, N, K): + # 初始化队列,时间字典和邻接表 q, t, adj = [(0, K)], {}, collections.defaultdict(list) + + # 构建邻接表 for u, v, w in times: adj[u].append((v, w)) + + # 使用优先队列进行Dijkstra算法 while q: time, node = heapq.heappop(q) if node not in t: - t[node] = time + t[node] = time # 记录当前节点最短时间 for v, w in adj[node]: - heapq.heappush(q, (time + w, v)) - return max(t.values()) if len(t) == N else -1 \ No newline at end of file + heapq.heappush(q, (time + w, v)) # 更新邻接节点入队 + + # 返回所有节点中最长的时间,即整个网络的延迟时间 + return max(t.values()) if len(t) == N else -1 diff --git a/solutions/python3/744.py b/solutions/python3/744.py index 8a28600..98a83e9 100644 --- a/solutions/python3/744.py +++ b/solutions/python3/744.py @@ -1,3 +1,7 @@ + class Solution: - def nextGreatestLetter(self, letters, target): - return letters[bisect.bisect(letters, target) % len(letters)] \ No newline at end of file + # 定义一个名为nextGreatestLetter的方法,接收两个参数:letters(有序字符列表)和target(目标字符) + def nextGreatestLetter(self, letters: list[str], target: str) -> str: + # 使用bisect模块的bisect函数在letters中查找大于等于target的第一个位置 + # 通过取模操作确保索引不会超出范围,返回该位置对应的字符 + return letters[bisect.bisect(letters, target) % len(letters)] diff --git a/solutions/python3/745.py b/solutions/python3/745.py index e691acc..1287301 100644 --- a/solutions/python3/745.py +++ b/solutions/python3/745.py @@ -1,11 +1,52 @@ + class WordFilter: + # 初始化字典树结构,用于存储前缀和后缀信息 def __init__(self, words): - self.p, self.s, self.ind = collections.defaultdict(set), collections.defaultdict(set), {} + from collections import defaultdict + self.prefixes, self.suffixes, self.index_map = defaultdict(set), defaultdict(set), {} + for i, w in enumerate(words): - self.ind[w] = i - self.p[""].add(w) - self.s[""].add(w) + # 记录每个单词的索引 + self.index_map[w] = i + + # 初始化根节点,添加当前词作为前缀和后缀 + self.prefixes[""].add(w) + self.suffixes[""].add(w) + + # 遍历每个可能的前缀并记录在字典中 for i in range(1, len(w) + 1): - self.p[w[:i]].add(w) - self.s[w[-i:]].add(w) - def f(self, prefix, suffix): return max((self.ind[c] for c in self.p[prefix] & self.s[suffix]), default = -1) \ No newline at end of file + self.prefixes[w[:i]].add(w) + + # 记录每个可能的后缀 + self.suffixes[w[-i:]].add(w) + + # 根据前缀和后缀查找最匹配的单词索引 + def f(self, prefix, suffix): + return max((self.index_map[c] for c in self.prefixes[prefix] & self.suffixes[suffix]), default = -1) + + + +class WordFilter: + # 初始化字典树结构,用于存储前缀和后缀信息 + def __init__(self, words): + from collections import defaultdict + self.prefixes, self.suffixes, self.index_map = defaultdict(set), defaultdict(set), {} + + for i, w in enumerate(words): + # 记录每个单词的索引 + self.index_map[w] = i + + # 初始化根节点,添加当前词作为前缀和后缀 + self.prefixes[""].add(w) + self.suffixes[""].add(w) + + # 遍历每个可能的前缀并记录在字典中 + for i in range(1, len(w) + 1): + self.prefixes[w[:i]].add(w) + + # 记录每个可能的后缀 + self.suffixes[w[-i:]].add(w) + + # 根据前缀和后缀查找最匹配的单词索引 + def f(self, prefix, suffix): + return max((self.index_map[c] for c in self.prefixes[prefix] & self.suffixes[suffix]), default = -1) diff --git a/solutions/python3/746.py b/solutions/python3/746.py index dfe2842..3c585d7 100644 --- a/solutions/python3/746.py +++ b/solutions/python3/746.py @@ -1,8 +1,19 @@ + class Solution: + # 定义一个解决方案类 + def minCostClimbingStairs(self, cost): """ - :type cost: List[int] - :rtype: int + :param cost: List[int] - 代表每个台阶的成本列表 + :return: int - 到达最后一级台阶的最小成本 + + 思路:通过动态规划,从第三个台阶开始计算到当前台阶的最小成本 + 更新cost数组以减少空间复杂度 """ - for i in range(2,len(cost)): cost[i]+=min(cost[i-1],cost[i-2]) - return min(cost[-1],cost[-2]) \ No newline at end of file + + for i in range(2, len(cost)): + # 从第三个台阶开始更新每个台阶的成本为到达该台阶的最小代价 + cost[i] += min(cost[i - 1], cost[i - 2]) + + # 返回最后两个台阶中的较小值,因为可以从倒数第一个或倒数第二个台阶跳到最后一个台阶 + return min(cost[-1], cost[-2]) diff --git a/solutions/python3/747.py b/solutions/python3/747.py index 7f816ed..b6388b7 100644 --- a/solutions/python3/747.py +++ b/solutions/python3/747.py @@ -1,4 +1,15 @@ + class Solution: + # 定义一个Solution类,用于解决主要逻辑 + def dominantIndex(self, nums: List[int]) -> int: + # 寻找数组nums中的最大值mx mx = max(nums) - return nums.index(mx) if all(num * 2 <= mx for num in nums if num < mx) else -1 \ No newline at end of file + + # 检查除了最大值外的所有元素是否都小于等于最大值的一半 + if all(num * 2 <= mx for num in nums if num < mx): + # 如果满足条件,则返回最大值的索引 + return nums.index(mx) + else: + # 否则返回-1 + return -1 diff --git a/solutions/python3/748.py b/solutions/python3/748.py index ec1ea82..0657787 100644 --- a/solutions/python3/748.py +++ b/solutions/python3/748.py @@ -1,8 +1,27 @@ + class Solution: def shortestCompletingWord(self, lp, words): - cntr_lp, res = {k: v for k, v in collections.Counter(lp.lower()).items() if k.isalpha()}, [None, None] + """ + :param lp: 字符串,待匹配的字符序列(英文) + :param words: 列表,包含多个字符串,寻找最短完成词(英文) + :return: 最短完成词(英文) + """ + + # 统计lp中的字母频率,并过滤非字母字符 + cntr_lp = {k: v for k, v in collections.Counter(lp.lower()).items() if k.isalpha()} + + # 初始化结果,存放最短的完成词及其长度 + res = [None, None] + + # 遍历words中的每个单词 for word in words: + # 统计当前word的小写形式的字母频率 check = collections.Counter(word.lower()) + + # 判断check是否包含cntr_lp中所有字符且数量足够,利用all和生成器表达式实现 if all(True if k in check and v <= check[k] else False for k, v in cntr_lp.items()): - if not any(res) or len(word) < res[1]: res = [word, len(word)] - return res[0] \ No newline at end of file + # 更新结果:如果当前word比记录的短或首次找到有效词时更新 + if not any(res) or len(word) < res[1]: + res = [word, len(word)] + + return res[0] diff --git a/solutions/python3/749.py b/solutions/python3/749.py index 11aa81e..98b2d14 100644 --- a/solutions/python3/749.py +++ b/solutions/python3/749.py @@ -1,85 +1,112 @@ + class Solution(object): def containVirus(self, grid): """ :type grid: List[List[int]] :rtype: int """ - if not grid: return None - N,M=len(grid),len(grid[0]) - - def around(r,c,t=None): - # all cells 1-step away from (r,c) - # optionally, if t!=None, target value must be t - for d in (-1,1): - for (rr,cc) in ((r+d,c), (r,c+d)): - if 0<=rr List[str]: - s = ''.join(bin(int(num))[2:].zfill(8) for num in ip.split('.')) - res = [] - while n: - for i in range(31 - s.rindex('1'), -1, -1): - if 2 ** i <= n: - res.append('.'.join(str(int(s[i:i + 8], 2)) for i in range(0, 32, 8)) + '/' + str(32 - i)) - n -= 2 ** i - s = bin(int(s, 2) + 2 ** i)[2:].zfill(32) + """ + 将IP地址转换为二进制形式,处理连续的网络前缀直到分配完n个IP。 + + 中文注释:将IP地址转换为二进制表示,并计算连续的网络前缀以分配给n个IP。 + """ + s = ''.join(bin(int(num))[2:].zfill(8) for num in ip.split('.')) # 将IP地址每部分转换为8位二进制字符串 + res = [] # 存储结果列表 + + while n: # 当剩余要分配的IP数量大于0时循环处理 + for i in range(31 - s.rindex('1'), -1, -1): # 从最右边第一个1开始,向左找连续的网络前缀长度 + if 2 ** i <= n: # 检查当前网络前缀是否小于剩余要分配的IP数量 + res.append( + '.'.join(str(int(s[i:i + 8], 2)) for i in range(0, 32, 8)) + '/' + str(32 - i) # 构建CIDR地址并添加到结果列表中 + ) + n -= 2 ** i # 减少剩余要分配的IP数量 + s = bin(int(s, 2) + 2 ** i)[2:].zfill(32) # 更新二进制字符串表示,为下一个网络前缀做准备 break + return res - \ No newline at end of file diff --git a/solutions/python3/752.py b/solutions/python3/752.py index dad7806..8bc5735 100644 --- a/solutions/python3/752.py +++ b/solutions/python3/752.py @@ -1,18 +1,43 @@ + class Solution: def openLock(self, deadends, target): + """ + 中文注释:定义一个解决方案类,包含openLock方法。 + + 英文注释: Define a solution class with an openLock method. + """ + + # 初始化移动集合、队列、计数器和转盘状态映射 moved, q, cnt, move = set(deadends), ["0000"], 0, {str(i): [str((i + 1) % 10), str((i - 1) % 10)] for i in range(10)} + + # 检查起始状态是否在禁用列表中 if "0000" in moved: return -1 + + # 广度优先搜索遍历所有可能的转盘状态 while q: new = [] + + # 增加当前步数计数器 cnt += 1 + + # 遍历队列中的每个字符串(当前状态) for s in q: + # 遍历字符串的每一位字符 for i, c in enumerate(s): + # 尝试向上和向下翻转转盘 for cur in (s[:i] + move[c][0] + s[i + 1:], s[:i] + move[c][1] + s[i + 1:]): + # 如果当前状态不在禁用列表中 if cur not in moved: + # 判断是否为目标状态,如果是则返回步数计数器值 if cur == target: return cnt + # 否则将新状态加入队列并标记为已访问 new.append(cur) moved.add(cur) + + # 更新队列为当前的新的转盘状态列表 q = new - return -1 \ No newline at end of file + + # 如果无法到达目标状态,返回-1 + return -1 diff --git a/solutions/python3/753.py b/solutions/python3/753.py index 7f54c78..3b9fedd 100644 --- a/solutions/python3/753.py +++ b/solutions/python3/753.py @@ -1,7 +1,24 @@ + class Solution: - def crackSafe(self, n, k): + # 定义一个解决方案类 + + def crackSafe(self, n: int, k: int) -> str: + # n:字符串的长度,k:每个位置上的字符数 + s = '0' * (n - 1) + # 初始化字符串s为n-1个'0' + D = '9876543210'[-k:] + # 获取用于构建组合的字符集合D + # 通过切片获取长度为k的数字字符 + for _ in range(k**n): - s += next(d for d in D if (s + d)[-n:] not in s) - return s \ No newline at end of file + # 遍历所有可能的组合数,即k^n次 + next_d = next(d for d in D if (s + d)[-n:] not in s) + # 选择一个未出现过的子串d作为下一个字符 + + s += next_d + # 将选择的字符添加到字符串s中 + + return s + # 返回最终构建的字符串s diff --git a/solutions/python3/754.py b/solutions/python3/754.py index 87250d3..e7f317c 100644 --- a/solutions/python3/754.py +++ b/solutions/python3/754.py @@ -1,7 +1,14 @@ + class Solution: + # 定义一个类,用于解决达到目标位置的问题 + def reachNumber(self, target): + # 初始化当前位置、步数和目标值(取绝对值) pos, step, target = 0, 0, abs(target) + + # 当当前位置小于目标值或者当前位置与目标值的差为奇数时,继续移动 while pos < target or (pos - target) % 2: - step += 1 - pos += step - return step \ No newline at end of file + step += 1 # 增加步数 + pos += step # 移动到新位置 + + return step # 返回所需的最小步数 diff --git a/solutions/python3/755.py b/solutions/python3/755.py index 53a278f..c2138b0 100644 --- a/solutions/python3/755.py +++ b/solutions/python3/755.py @@ -1,12 +1,21 @@ + class Solution: - def pourWater(self, heights, V, K): + def pourWater(self, heights: list[int], V: int, K: int) -> list[int]: + """ + 模拟水滴落入高度数组的过程。 + + English: + Simulate the process of water droplets falling into an array of heights. + """ for drop in range(V): - l = r = K + l = r = K # 初始化左右指针为K位置 + # 向左寻找较低的洼地 for i in range(K - 1, -1, -1): if heights[i] > heights[l]: break elif heights[i] < heights[l]: l = i + # 如果左侧存在更低的位置,则将水滴加在左侧;否则向右寻找较低的洼地 if l < K: heights[l] += 1 else: @@ -15,8 +24,9 @@ def pourWater(self, heights, V, K): break elif heights[j] < heights[r]: r = j + # 如果左右都未找到更低洼地,则加在原位置K上 if l == r == K: heights[K] += 1 - elif r > K: + elif r > K: # 将水滴加在右侧较低洼地的位置 heights[r] += 1 - return heights \ No newline at end of file + return heights diff --git a/solutions/python3/756.py b/solutions/python3/756.py index 29aef32..ffd05c0 100644 --- a/solutions/python3/756.py +++ b/solutions/python3/756.py @@ -1,10 +1,28 @@ + class Solution: + # Python 解决方案类 + def pyramidTransition(self, bottom, allowed): - chars, allowed = 'ABCDEFG', set(allowed) + # 初始化字符集和允许的组合集合 + chars = 'ABCDEFG' + allowed = set(allowed) + def dfs(r, q, i): - if len(r) == 1: + """ + :param r: 当前行字符串 + :param q: 下一行构建的字符串 + :param i: 当前行索引 + """ + # 如果当前行长度为1,表示已成功构建金字塔,返回True + if len(r) == 1: return True + for c in chars: - if r[i:i+2]+c in allowed and (i==len(r)-2 and dfs(q+c,"",0) or dfs(r,q+c,i+1)): return True + # 检查当前字符组合是否在允许的集合中 + if r[i:i+2] + c in allowed and \ + (i == len(r)-2 and dfs(q+c, "", 0) or dfs(r, q+c, i+1)): + return True return False - return dfs(bottom, "", 0) \ No newline at end of file + + # 开始深度优先搜索,返回是否可以成功构建金字塔 + return dfs(bottom, "", 0) diff --git a/solutions/python3/757.py b/solutions/python3/757.py index aad03df..0c547ed 100644 --- a/solutions/python3/757.py +++ b/solutions/python3/757.py @@ -1,11 +1,28 @@ + class Solution(object): + # 定义一个类,用于解决区间问题 + def intersectionSizeTwo(self, intervals): - intervals.sort(key = lambda k: k[1]) + """ + :type intervals: List[List[int]] + :rtype: int + """ + # 按照区间的结束位置进行排序 + intervals.sort(key=lambda k: k[1]) + + # 用于存储最终的结果集 solution = [] + for start, end in intervals: + # 如果结果集中为空或者最后一个元素不小于当前区间的起始位置 if not len(solution) or solution[-1] < start: + # 添加两个满足条件的数到结果集中 solution.append(end - 1) solution.append(end) + # 如果结果集中的倒数第二个元素不小于当前区间的起始位置 elif solution[-2] < start: + # 只添加一个满足条件的数到结果集中 solution.append(end) - return len(solution) \ No newline at end of file + + # 返回结果集的长度,即满足条件的最小整数对的数量 + return len(solution) diff --git a/solutions/python3/758.py b/solutions/python3/758.py index fc63da1..8ceef78 100644 --- a/solutions/python3/758.py +++ b/solutions/python3/758.py @@ -1,13 +1,21 @@ + class Solution: + # 初始化解决方案类 + def boldWords(self, words, S): + # 构建Trie树,存储单词列表,并标记以#结束的单词 trie, n, mask, res = {}, len(S), set(), "" + for w in words: cur = trie for c in w: if c not in cur: cur[c] = {} cur = cur[c] + # 使用集合进行标记,避免重复添加相同的单词 cur["#"] = cur.get("#", set()) | {w} + + # 遍历字符串S,并构建mask集合,记录需要加粗的位置 for i in range(n): cur, j = trie, i while j < n and S[j] in cur: @@ -15,10 +23,13 @@ def boldWords(self, words, S): if "#" in cur: mask |= {ind for ind in range(i, j + 1)} j += 1 + + # 根据mask集合生成最终结果字符串,加粗指定位置的字符 for i in range(n): if i in mask and (not i or i - 1 not in mask): res += "" res += S[i] if i in mask and (i == n - 1 or i + 1 not in mask): res += "" - return res \ No newline at end of file + + return res diff --git a/solutions/python3/759.py b/solutions/python3/759.py index ff5e1e3..ed46484 100644 --- a/solutions/python3/759.py +++ b/solutions/python3/759.py @@ -1,3 +1,4 @@ + # Definition for an interval. # class Interval: # def __init__(self, s=0, e=0): @@ -5,15 +6,25 @@ # self.end = e class Solution: + # 初始化员工的时间段列表,按开始时间排序 def employeeFreeTime(self, schedule): - intervals = sorted(((intr.start, intr.end) for emp in schedule for intr in emp), key = lambda x: x[0]) + # 将所有时间段按开始时间排序 + intervals = sorted(((intr.start, intr.end) for emp in schedule for intr in emp), key=lambda x: x[0]) + + # 结果列表和栈的初始化 res, stack = [], [] + + # 遍历排序后的所有时间段 for s, e in intervals: if not stack: + # 如果栈为空,直接将当前时间段加入栈 stack.append((s, e)) elif s <= stack[-1][-1]: + # 当前时间段与栈顶时间段重叠或相邻,合并它们 stack.append((s, max(e, stack.pop()[1]))) else: + # 找到一个空闲时段,记录并更新栈 res.append([stack[-1][1], s]) stack.append((s, e)) - return res \ No newline at end of file + + return res diff --git a/solutions/python3/76.py b/solutions/python3/76.py index 3216e18..a21d2e7 100644 --- a/solutions/python3/76.py +++ b/solutions/python3/76.py @@ -1,24 +1,36 @@ + class Solution: - def minWindow(self, s, t): + # 定义一个类,用于解决最小窗口子串问题 + + def minWindow(self, s: str, t: str) -> str: + # 初始化字符计数器、目标字符串的集合、s的长度以及left标志变量 cnt_s, cnt_t, n, left, r = {}, {}, len(s), set(t), -1 + + # 计算t中每个字符出现次数 for c in t: cnt_t[c] = cnt_t.get(c, 0) + 1 + L = l = 0 - while left: + while left < 0: # 循环直到找到目标子串的左边界 r += 1 - if r >= n: + if r >= n: # 超出s长度时结束循环 return "" cnt_s[s[r]] = cnt_s.get(s[r], 0) + 1 if s[r] in cnt_t and cnt_s[s[r]] == cnt_t[s[r]]: - left.discard(s[r]) + left += 1 # 当字符匹配且数量满足要求时,更新left + R = r cnt_s[s[r]] -= 1 + + # 寻找最小覆盖子串的右边界 while l < r < n: cnt_s[s[r]] = cnt_s.get(s[r], 0) + 1 while s[l] not in cnt_t or cnt_s[s[l]] > cnt_t[s[l]]: cnt_s[s[l]] -= 1 l += 1 if r - l < R - L: - L, R = l, r - r += 1 - return s[L: R + 1] \ No newline at end of file + L, R = l, r # 更新最小覆盖子串的边界 + + r += 1 + + return s[L:R + 1] # 返回结果 diff --git a/solutions/python3/760.py b/solutions/python3/760.py index 20c5b59..024a850 100644 --- a/solutions/python3/760.py +++ b/solutions/python3/760.py @@ -1,4 +1,11 @@ + class Solution: + # 定义一个类Solution,用于解决同构映射问题 + def anagramMappings(self, A, B): + # 创建一个字典 ind,将B中的每个元素及其索引存储起来 ind = {num: j for j, num in enumerate(B)} - return [ind[num] for num in A] \ No newline at end of file + + # 遍历A中的每一个元素,在ind中查找对应的索引并返回结果列表 + return [ind[num] for num in A] + # 中文注释:遍历数组A,通过字典ind快速获取B中对应值的索引,并构建结果列表 diff --git a/solutions/python3/761.py b/solutions/python3/761.py index aa861fb..f69ad30 100644 --- a/solutions/python3/761.py +++ b/solutions/python3/761.py @@ -1,10 +1,31 @@ + class Solution: def makeLargestSpecial(self, S: str) -> str: + """ + 构造给定字符串S中最大值的特殊序列。 + + 参数: + S (str): 输入的原始字符串,只包含'0'和'1' + + 返回: + str: 通过递归构造的最大化后的特殊序列 + """ count = i = 0 + # 初始化结果列表 res = [] + for j, v in enumerate(S): - count = count + 1 if v=='1' else count - 1 + # 更新括号计数器 + if v == '1': + count += 1 + else: + count -= 1 + + # 当计数器归零时,表示找到一个子序列 if count == 0: + # 递归构造内部子序列,并将其添加到结果列表中 res.append('1' + self.makeLargestSpecial(S[i + 1:j]) + '0') i = j + 1 - return ''.join(sorted(res)[::-1]) \ No newline at end of file + + # 对所有子序列排序(升序),然后反转,以获得最大值 + return ''.join(sorted(res)[::-1]) diff --git a/solutions/python3/762.py b/solutions/python3/762.py index c382476..24aeccc 100644 --- a/solutions/python3/762.py +++ b/solutions/python3/762.py @@ -1,16 +1,27 @@ + class Solution: def countPrimeSetBits(self, L, R): """ - :type L: int - :type R: int - :rtype: int + :type L: int # 输入左边界 + :type R: int # 输入右边界 + :rtype: int # 返回满足条件的数字个数 + + 计算区间[L, R]内二进制表示中1的数量为素数的整数个数。 """ - count=0 - while L<=R: - if str(bin(L)[2:]).count("1") in [2,3,5,7,11,13,17,19]: count+=1 - if str(bin(R)[2:]).count("1") in [2,3,5,7,11,13,17,19]: - count+=1 - if L==R: count-=1 - L+=1 - R-=1 - return count \ No newline at end of file + + prime_set_bits = {2, 3, 5, 7, 11, 13, 17, 19} # 素数集合 + count = 0 + + while L <= R: + bit_count_L = bin(L).count('1') # 计算L的二进制表示中1的数量 + if bit_count_L in prime_set_bits: # 判断该数量是否为素数 + count += 1 + + bit_count_R = bin(R).count('1') # 同上,计算R的二进制表示中1的数量 + if bit_count_R in prime_set_bits: + count += 1 + + L += 1 + R -= 1 + + return count diff --git a/solutions/python3/763.py b/solutions/python3/763.py index 9595376..e7d4906 100644 --- a/solutions/python3/763.py +++ b/solutions/python3/763.py @@ -1,14 +1,26 @@ + class Solution: def partitionLabels(self, S): """ :type S: str :rtype: List[int] """ + # 初始化结果列表来存储分割片段的大小 sizes = [] + + # 当字符串S不为空时,继续循环 while S: i = 1 + + # 寻找使当前子串和剩余部分没有重复字符的最小i值 while set(S[:i]) & set(S[i:]): i += 1 + + # 将找到的分割点长度加入结果列表 sizes.append(i) + + # 移除已处理的部分,继续处理剩余字符串 S = S[i:] - return sizes \ No newline at end of file + + # 返回所有分割片段的大小 + return sizes diff --git a/solutions/python3/764.py b/solutions/python3/764.py index 6d0f042..627a3d0 100644 --- a/solutions/python3/764.py +++ b/solutions/python3/764.py @@ -1,7 +1,18 @@ + class Solution: - def orderOfLargestPlusSign(self, N, mines): - #up, left, down, right - dp, res, mines = [[[0, 0, 0, 0] for j in range(N)] for i in range(N)], 0, {(i, j) for i, j in mines} + def orderOfLargestPlusSign(self, N: int, mines: list[tuple[int]]) -> int: + """ + N: 地图的大小,正方形网格。 + mines: 矿点的位置列表,矿点不能被覆盖。 + + 返回:可以放置“+”的最大长度(边长)。 + """ + + # 初始化动态规划表 dp 和结果 res + # mines 转换为集合便于快速查找 + dp, res, mines = [[[0, 0, 0, 0] for _ in range(N)] for _ in range(N)], 0, {(i, j) for i, j in mines} + + # 计算每个位置的上、左方向的最大覆盖长度 for i in range(N): for j in range(N): if (i, j) not in mines: @@ -13,6 +24,8 @@ def orderOfLargestPlusSign(self, N, mines): dp[i][j][1] = dp[i][j - 1][1] + 1 except: dp[i][j][1] = 1 + + # 计算每个位置的下、右方向的最大覆盖长度,并更新最大结果 res for i in range(N - 1, -1, -1): for j in range(N - 1, -1, -1): if (i, j) not in mines: @@ -25,4 +38,5 @@ def orderOfLargestPlusSign(self, N, mines): except: dp[i][j][3] = 1 res = max(res, min(dp[i][j])) - return res \ No newline at end of file + + return res diff --git a/solutions/python3/765.py b/solutions/python3/765.py index f5b0f00..2e68650 100644 --- a/solutions/python3/765.py +++ b/solutions/python3/765.py @@ -1,15 +1,32 @@ + class Solution: + # 定义一个类来解决情侣座位交换问题 + def minSwapsCouples(self, row): - res, index = 0, {num: i for i, num in enumerate(row)} - for i in range(0, len(row), 2): - if row[i] % 2 == 0 and row[i + 1] != row[i] + 1: + """ + :param row: 初始的座位排列列表,表示每个座位编号 + :return: 最少需要交换的次数以使所有情侣成为邻居 + + 1. 初始化结果计数器 res 和索引字典 index + 2. 遍历座位数组 row 的偶数下标位置 + - 如果当前偶数编号的情侣不在正确的位置,进行以下操作: + a) 找到需要交换的目标编号 f + b) 交换当前情侣和目标情侣的座位,并更新索引字典 + c) 结果计数器 res 加一 + """ + res, index = 0, {num: i for i, num in enumerate(row)} # 初始化结果计数器和索引字典 + + for i in range(0, len(row), 2): # 遍历偶数下标位置,确保每次处理两个座位 + if row[i] % 2 == 0 and row[i + 1] != row[i] + 1: # 偶数编号的情侣不在正确的位置 f = row[i + 1] - row[i + 1], row[index[row[i] + 1]] = row[i] + 1, row[i + 1] - index[row[i] + 1], index[f] = i + 1, index[row[i] + 1] - res += 1 - elif row[i] % 2 != 0 and row[i + 1] != row[i] - 1: + row[i + 1], row[index[row[i] + 1]] = row[i] + 1, row[i + 1] # 交换座位 + index[row[i] + 1], index[f] = i + 1, index[row[i] + 1] # 更新索引字典 + res += 1 # 结果计数器加一 + + elif row[i] % 2 != 0 and row[i + 1] != row[i] - 1: # 奇数编号的情侣不在正确的位置 f = row[i + 1] - row[i + 1], row[index[row[i] - 1]], index[row[i + 1]] = row[i] - 1, row[i + 1], index[row[i] - 1] + row[i + 1], row[index[row[i] - 1]], index[row[i + 1]] = row[i] - 1, row[i + 1], index[row[i] - 1] # 交换座位并更新索引字典 index[row[i] - 1], index[f] = i + 1, index[row[i] - 1] res += 1 - return res \ No newline at end of file + + return res # 返回最少交换次数 diff --git a/solutions/python3/766.py b/solutions/python3/766.py index fc8c10f..2974ae9 100644 --- a/solutions/python3/766.py +++ b/solutions/python3/766.py @@ -1,3 +1,6 @@ + class Solution: + # 判断给定矩阵是否为托普利茨矩阵,即除了主对角线元素外的每个元素都等于其左上方元素 def isToeplitzMatrix(self, matrix): - return all(matrix[i][j] == matrix[i - 1][j - 1] for i in range(1, len(matrix)) for j in range(1, len(matrix[0]))) \ No newline at end of file + # 使用all函数和生成器表达式来检查矩阵中每个元素是否满足托普利茨矩阵条件 + return all(matrix[i][j] == matrix[i - 1][j - 1] for i in range(1, len(matrix)) for j in range(1, len(matrix[0]))) diff --git a/solutions/python3/767.py b/solutions/python3/767.py index b74b9a4..dd04e30 100644 --- a/solutions/python3/767.py +++ b/solutions/python3/767.py @@ -1,9 +1,29 @@ + +from collections import Counter + class Solution: def reorganizeString(self, S): - cnt, res = collections.Counter(S), "" + """ + 使用Counter统计字符出现次数,重新组织字符串。 + :param S: str, 输入的原始字符串 + :return: str, 重新组织后的字符串或空串(无法重组时) + """ + + cnt, res = Counter(S), "" while len(res) < len(S): + # 获取当前剩余字符中出现次数最多的字符及其频次 c, i = cnt.most_common()[0], 0 - while i + 1 < len(cnt) and (res and res[-1] == c[0] or cnt[c[0]] == 0): c, i = cnt.most_common()[i + 1], i + 1 - if not cnt[c[0]] or res and res[-1] == c[0]: return "" - else: res, cnt[c[0]] = res + c[0], cnt[c[0]] - 1 - return res \ No newline at end of file + + # 如果连续相同字符超过1个或该字符计数为0,则寻找下一个最常见字符 + while i + 1 < len(cnt) and (res and res[-1] == c[0] or cnt[c[0]] == 0): + c, i = cnt.most_common()[i + 1], i + 1 + + # 如果找到的字符无法再用或其前一个也是相同字符,返回空串 + if not cnt[c[0]] or res and res[-1] == c[0]: + return "" + + else: + # 将选中的字符添加到结果字符串中,并减少该字符计数 + res, cnt[c[0]] = res + c[0], cnt[c[0]] - 1 + + return res diff --git a/solutions/python3/768.py b/solutions/python3/768.py index 80de3f5..81322a8 100644 --- a/solutions/python3/768.py +++ b/solutions/python3/768.py @@ -1,12 +1,28 @@ + class Solution: + # 定义一个类来解决最大分块排序问题 + def maxChunksToSorted(self, arr): - mx, mn, res, check = 0, 10 ** 9, 0, [[0, 0] for _ in range(len(arr))] + # 初始化最大值、最小值和结果计数器 + mx, mn = 0, 10 ** 9 # mx: 最大值, mn: 最小值 + res = 0 # 结果计数器 + + # 遍历数组,确定每个分块的最大值 for i in range(len(arr)): - if arr[i] > mx: mx = arr[i] - check[i][0] = mx - for i in range(len(arr) -1, -1, -1): - check[i][1] = mn - if arr[i] < mn: mn = arr[i] + if arr[i] > mx: + mx = arr[i] + check[i][0] = mx # 记录以i结尾的子数组的最大值 + + # 反向遍历数组,确定每个分块的最小值 + mn = 10 ** 9 # 重置最小值 + for i in range(len(arr) - 1, -1, -1): + check[i][1] = mn # 记录以i开始的子数组的最小值 + if arr[i] < mn: + mn = arr[i] + + # 统计满足条件的最大分块数量 for c in check: - if c[0] <= c[1]: res += 1 - return res \ No newline at end of file + if c[0] <= c[1]: + res += 1 # 如果当前分块的最大值小于等于最小值,增加结果计数器 + + return res # 返回最大分块的数量 diff --git a/solutions/python3/769.py b/solutions/python3/769.py index c94f34d..e55ae40 100644 --- a/solutions/python3/769.py +++ b/solutions/python3/769.py @@ -1,13 +1,20 @@ + class Solution: def maxChunksToSorted(self, arr): """ - :type arr: List[int] - :rtype: int + :type arr: List[int] # 输入类型:整数列表 + :rtype: int # 返回值类型:整数 + + 思路: + - 遍历数组,维护已遍历最大值和计数器。 + - 当当前最大值等于已遍历元素数量减一时,表示可以分割一个有序块。 """ max_seen, total_seen, res_count = 0, 0, 0 for num in arr: - max_seen = max(max_seen, num) - total_seen += 1 - if max_seen == total_seen - 1: - res_count += 1 - return res_count \ No newline at end of file + max_seen = max(max_seen, num) # 更新已遍历中的最大值 + total_seen += 1 # 增加已遍历元素计数器 + + if max_seen == total_seen - 1: # 判断是否可以分割一个有序块 + res_count += 1 # 分割计数器加一 + + return res_count # 返回可分块的数量 diff --git a/solutions/python3/77.py b/solutions/python3/77.py index c452199..ef20683 100644 --- a/solutions/python3/77.py +++ b/solutions/python3/77.py @@ -1,6 +1,15 @@ + class Solution: + # 定义一个类来解决组合问题 + def combine(self, n: int, k: int) -> List[List[int]]: + # 初始化一个列表,存储当前的组合路径 bfs = [[]] + + # 对于1到n中的每一个数字num for num in range(1, n + 1): + # 将当前数字添加到满足长度要求的已有组合中 bfs += [arr + [num] for arr in bfs if len(arr) < k] - return [arr for arr in bfs if len(arr) == k] \ No newline at end of file + + # 返回所有满足长度k的完整组合 + return [arr for arr in bfs if len(arr) == k] diff --git a/solutions/python3/770.py b/solutions/python3/770.py index 26f0a7c..1dfefed 100644 --- a/solutions/python3/770.py +++ b/solutions/python3/770.py @@ -1,11 +1,30 @@ + class Solution(object): - def basicCalculatorIV(self, s, evalvars, evalints): + def basicCalculatorIV(self, s: str, evalvars: list[str], evalints: list[int]) -> list[str]: + """ + :param s: 字符串表达式 + :param evalvars: 用于替换的变量名列表 + :param evalints: 对应evalvars中的整数值列表 + :return: 计算结果后的字符串表示形式 + """ + + # 移除空格并初始化字典 s.strip() d = dict(zip(evalvars, evalints)) s = s.replace(' ', '') + + # 使用正则表达式拆分字符串 ts = re.findall('\u005Cd+|[-()+*]|[^-()+*]+', s) - - def add(p, q): + + # 向量加法函数 + def add(p: list[tuple[list[str], int]], q: list[tuple[list[str], int]]) -> list[tuple[list[str], int]]: + """ + 合并两个向量表达式,并进行必要的合并操作 + + :param p: 第一个向量表达式 + :param q: 第二个向量表达式 + :return: 一个新的合并后的向量表达式列表 + """ i, j = 0, 0 r = [] while i < len(p) and j < len(q): @@ -16,38 +35,82 @@ def add(p, q): r.append((v, c + c2)) i += 1 j += 1 - elif len(v) > len(v2) or len(v) == len(v2) and v < v2: + elif len(v) > len(v2) or (len(v) == len(v2) and v < v2): r.append(p[i]) i += 1 else: r.append(q[j]) j += 1 - + + # 合并剩余部分 r += p[i:] r += q[j:] return r - def neg(p): + # 向量取负函数 + def neg(p: list[tuple[list[str], int]]) -> list[tuple[list[str], int]]: + """ + 对向量表达式的系数取负数 + + :param p: 输入的向量表达式列表 + :return: 取负后的向量表达式列表 + """ r = [] for v, c in p: r.append((v, -c)) return r - def sub(p, q): + # 向量减法函数 + def sub(p: list[tuple[list[str], int]], q: list[tuple[list[str], int]]) -> list[tuple[list[str], int]]: + """ + 两个向量表达式的差值 + + :param p: 第一个向量表达式列表 + :param q: 第二个向量表达式列表 + :return: 计算后的向量表达式列表 + """ return add(p, neg(q)) - def mult(p, q): + # 向量乘法函数 + def mult(p: list[tuple[list[str], int]], q: list[tuple[list[str], int]]) -> list[tuple[list[str], int]]: + """ + 两个向量表达式的乘积 + + :param p: 第一个向量表达式列表 + :param q: 第二个向量表达式列表 + :return: 计算后的向量表达式列表 + """ r = [] for v, c in p: for v2, c2 in q: r = add(r, [(sorted(v + v2), c * c2)]) return r - - def prec(c): - return 0 if c in [')'] else 1 if c in ['+', '-'] else 2 - - i = 0 - def expr(p): + + # 运算符优先级函数 + def prec(c: str) -> int: + """ + 根据运算符确定其优先级 + + :param c: 一个字符,代表运算符 + :return: 该运算符的优先级 + """ + if c in [')']: + return 0 + elif c in ['+', '-']: + return 1 + else: + return 2 + + i = 0 + + # 解析表达式函数 + def expr(p: int) -> list[tuple[list[str], int]]: + """ + 对表达式的解析和计算 + + :param p: 当前的运算优先级 + :return: 计算后的向量表达式列表 + """ nonlocal i, ts if ts[i] == '(': i += 1 @@ -69,6 +132,7 @@ def expr(p): v = [] else: v = [([ts[i]], 1)] + while i < len(ts) - 2 and prec(ts[i+1]) > p: op = ts[i+1] i += 2 @@ -79,13 +143,20 @@ def expr(p): return v - def tostrings(p): + # 将向量表达式转换为字符串形式 + def tostrings(p: list[tuple[list[str], int]]) -> list[str]: + """ + 将向量表达式列表转换成对应的字符串表示形式 + + :param p: 向量表达式的列表 + :return: 对应的字符串列表 + """ r = [] for v, c in p: - if v == []: - r.append(str(c)) - else: - r.append(str(c) + '*' + '*'.join(v)) - return r - - return tostrings(expr(0)) \ No newline at end of file + term = ' + '.join(['*'.join(v[::-1]) if len(v) > 0 else '' for v in [v]]) + r.append(f'{c} * {term}') + + return [''.join(r).strip('+ ')] + + # 返回最终计算结果 + return tostrings(expr(3)) diff --git a/solutions/python3/771.py b/solutions/python3/771.py index 1207177..2a40dfa 100644 --- a/solutions/python3/771.py +++ b/solutions/python3/771.py @@ -1,4 +1,9 @@ + class Solution: - def numJewelsInStones(self, J, S): + # 这个方法用于统计字符串 S 中作为宝石的字符数量,这些字符在字符串 J 中被定义为宝石 + def numJewelsInStones(self, J: str, S: str) -> int: + # 将字符串 J 转换为集合 sj 以提高查找效率 sj = set(J) - return sum(s in sj for s in S) \ No newline at end of file + + # 使用生成器表达式遍历字符串 S,对于每个字符 s,检查其是否在集合 sj 中,并求和统计 + return sum(s in sj for s in S) diff --git a/solutions/python3/772.py b/solutions/python3/772.py index 1c57a8e..c259783 100644 --- a/solutions/python3/772.py +++ b/solutions/python3/772.py @@ -1,7 +1,12 @@ + class Solution: + # 计算器函数,用于进行基本运算 def calculate(self, s: str) -> int: + # 辅助函数:执行两个数字的计算 def calc(n2, op, n1): return n1 * n2 if op == '*' else n1 // n2 if op == '/' else n1 + n2 if op == '+' else n1 - n2 + + # 辅助函数:处理数组中的运算,进行计算 def calc2(arr): if len(arr) == 1: return arr.pop() @@ -9,20 +14,29 @@ def calc2(arr): for j in range(2, len(arr), 2): res = calc(arr[j], arr[j - 1], res) return res + + # 初始化栈和索引 stack, i, num = [], 0, 0 + while i < len(s): j = i + # 解析数字部分 while j < len(s) and s[j].isdigit(): num, j = num * 10 + int(s[j]), j + 1 + if i != j: + # 如果有运算符,进行计算并入栈 stack.append(calc(num, stack.pop(), stack.pop()) if stack and stack[-1] in "*/" else num) num, j = 0, j - 1 elif s[i] == ")": + # 处理括号 ind = len(stack) - stack[::-1].index('(') - 1 stack[ind:] = [calc2(stack[ind + 1:])] if len(stack) > 1 and stack[-2] in '*/': stack.append(calc(stack.pop(), stack.pop(), stack.pop())) elif s[i] != ' ': + # 将非空格字符入栈 stack.append(s[i]) i = j + 1 - return calc2(stack) \ No newline at end of file + + return calc2(stack) diff --git a/solutions/python3/773.py b/solutions/python3/773.py index 4eae0b1..fb48e0a 100644 --- a/solutions/python3/773.py +++ b/solutions/python3/773.py @@ -1,21 +1,26 @@ + class Solution: + # 定义移动规则字典,用于记录每个位置可以移动到的位置 def slidingPuzzle(self, board): moves, used, cnt = {0: {1, 3}, 1:{0, 2, 4}, 2:{1, 5}, 3:{0, 4}, 4:{1, 3, 5}, 5:{2, 4}}, set(), 0 + # 将初始状态转换为字符串形式便于比较和存储 s = "".join(str(c) for row in board for c in row) - q = [(s, s.index("0"))] + q = [(s, s.index("0"))] # 初始化队列,包含当前状态及其0的位置索引 + while q: new = [] for s, i in q: - used.add(s) + used.add(s) # 记录已访问的状态 if s == "123450": - return cnt - arr = [c for c in s] - for move in moves[i]: - new_arr = arr[:] - new_arr[i], new_arr[move] = new_arr[move], new_arr[i] - new_s = "".join(new_arr) - if new_s not in used: + return cnt # 如果达到目标状态,返回移动次数 + arr = [c for c in s] # 将当前字符串状态转换为列表形式便于修改 + for move in moves[i]: # 遍历当前索引可以到达的位置 + new_arr = arr[:] # 复制原数组 + new_arr[i], new_arr[move] = new_arr[move], new_arr[i] # 进行交换操作 + new_s = "".join(new_arr) # 将新列表转换回字符串形式 + if new_s not in used: # 如果未访问过该状态,则加入队列 new.append((new_s, move)) - cnt += 1 - q = new - return -1 \ No newline at end of file + cnt += 1 # 移动次数加一 + q = new # 更新队列为新的可能状态 + + return -1 # 如果无法达到目标状态,返回-1 diff --git a/solutions/python3/774.py b/solutions/python3/774.py index a97a950..77640c3 100644 --- a/solutions/python3/774.py +++ b/solutions/python3/774.py @@ -1,13 +1,25 @@ + class Solution: def minmaxGasDist(self, st, K): + """ + 初始化左右边界,寻找最小的最大间隔。 + + 中文注释:初始化左右边界,寻找最小的最大间隔。 + """ left, right = 1e-6, st[-1] - st[0] + # 使用二分查找法来逼近最小的最大间隔 while left + 1e-6 < right: mid = (left + right) / 2 count = 0 + """ + 计算在给定的mid值下需要的最少分割次数,如果超过了K,则说明当前mid过小。 + + 中文注释:计算在给定的mid值下需要的最少分割次数,如果超过了K,则说明当前mid过小。 + """ for a, b in zip(st, st[1:]): count += math.ceil((b - a) / mid) - 1 if count > K: left = mid else: right = mid - return right \ No newline at end of file + return right diff --git a/solutions/python3/775.py b/solutions/python3/775.py index 02fd0a5..6257137 100644 --- a/solutions/python3/775.py +++ b/solutions/python3/775.py @@ -1,5 +1,11 @@ + class Solution: + # 判断给定数组是否为理想排列,即每个元素与它的索引差的绝对值不超过1 def isIdealPermutation(self, A): + # 遍历数组中的每一个元素及其索引 for i, num in enumerate(A): - if not (i - 1 <= num <= i + 1): return False - return True \ No newline at end of file + # 检查当前元素与索引的差异是否在-1到1之间,否则返回False + if not (i - 1 <= num <= i + 1): + return False + # 如果所有检查都通过,则返回True + return True diff --git a/solutions/python3/776.py b/solutions/python3/776.py index 9546e45..3b2efef 100644 --- a/solutions/python3/776.py +++ b/solutions/python3/776.py @@ -1,16 +1,38 @@ + class Solution: + # 定义一个类来解决二叉搜索树的分割问题 + def splitBST(self, root, V): + """ + :param root: 二叉搜索树的根节点 + :param V: 分割值 + :return: 返回两个二叉搜索树,第一个是小于等于V的子树,第二个是大于V的子树 + """ + + # 如果当前节点为空,则返回两个空子树 if not root: return [None, None] + + # 当前节点值等于分割值的情况 if root.val == V: + # 将当前节点的右子树分离出来作为大于部分 a = root.right + # 清除当前节点的右子树指针 root.right = None return [root, a] + + # 当前节点值小于分割值的情况 elif root.val < V: + # 递归处理右子树 small, large = self.splitBST(root.right, V) + # 将当前节点的右子树指针指向小于部分 root.right = small return [root, large] + + # 当前节点值大于分割值的情况 else: + # 递归处理左子树 small, large = self.splitBST(root.left, V) + # 将当前节点的左子树指针指向大于部分 root.left = large - return [small, root] \ No newline at end of file + return [small, root] diff --git a/solutions/python3/777.py b/solutions/python3/777.py index 8aa14dc..ec5c7c2 100644 --- a/solutions/python3/777.py +++ b/solutions/python3/777.py @@ -1,13 +1,32 @@ + class Solution: - def canTransform(self, start, end): + def canTransform(self, start: str, end: str) -> bool: + """ + 判断是否可以通过平移'L'和'R'字符来使start变为end。 + + 通过字典记录L和R在start和end中的位置,然后进行比较验证。 + """ + + # 使用defaultdict存储L和R的位置 s, e = collections.defaultdict(list), collections.defaultdict(list) + + # 将不含空格的字符分别存入s和e中 newS, newE = [c for c in start if c != "X"], [c for c in end if c != "X"] + + # 记录L和R在start中的位置 for i in range(len(start)): if start[i] != "X": s[start[i]].append(i) + + # 记录L和R在end中的位置 + for i in range(len(end)): if end[i] != "X": e[end[i]].append(i) + + # 检查字符数量是否一致,以及L和R的位置关系 if newS == newE and len(s["L"]) == len(e["L"]) and len(s["R"]) == len(e["R"]): + # L只能向左移动,R只能向右移动,验证位置合法性 if all(s["R"][i] <= e["R"][i] for i in range(len(s["R"]))) and all(s["L"][i] >= e["L"][i] for i in range(len(s["L"]))): return True - return False \ No newline at end of file + + return False diff --git a/solutions/python3/778.py b/solutions/python3/778.py index 855f39c..c2de61c 100644 --- a/solutions/python3/778.py +++ b/solutions/python3/778.py @@ -1,11 +1,29 @@ + class Solution: def swimInWater(self, grid): + """ + Chinese: + 使用最小堆来解决游泳问题。从起点开始,每次选择当前高度最小且未访问过的格子。 + + English: + Solve the swimming problem using a minimum heap. Start from the origin and each time choose the unvisited cell with the smallest height. + """ + import heapq + # 初始化堆、结果变量、网格大小及已访问集合 heap, res, n, visited = [(grid[0][0], 0, 0)], 0, len(grid), set() + while True: d, i, j = heapq.heappop(heap) - if d > res: res = d - if i == j == n - 1: return res + # 更新最大高度 + if d > res: + res = d + + # 判断是否到达终点 + if i == j == n - 1: + return res + + # 遍历相邻格子,加入堆中(未访问且在网格范围内) for x, y in ((i - 1, j), (i + 1, j), (i, j - 1), (i, j + 1)): if 0 <= x < n and 0 <= y < n and (x, y) not in visited: visited.add((x, y)) - heapq.heappush(heap, (grid[x][y], x, y)) \ No newline at end of file + heapq.heappush(heap, (grid[x][y], x, y)) diff --git a/solutions/python3/779.py b/solutions/python3/779.py index 4e3353a..23c733b 100644 --- a/solutions/python3/779.py +++ b/solutions/python3/779.py @@ -1,3 +1,6 @@ + class Solution: + # 定义一个求第N行第K列格子值的方法 def kthGrammar(self, N: int, K: int) -> int: - return N > 1 and self.kthGrammar(N - 1, (K + 1) // 2) ^ ((K -1) % 2) or 0 \ No newline at end of file + # 如果N大于1,递归计算前一层的值,并根据K的位置进行异或运算 + return N > 1 and self.kthGrammar(N - 1, (K + 1) // 2) ^ ((K - 1) % 2) or 0 diff --git a/solutions/python3/78.py b/solutions/python3/78.py index 82c4466..5b11bd7 100644 --- a/solutions/python3/78.py +++ b/solutions/python3/78.py @@ -1,10 +1,21 @@ + class Solution: def subsets(self, nums): """ :type nums: List[int] :rtype: List[List[int]] """ + # 初始化结果集,包含空集 + # Initialize result set with an empty subset res = [[]] - for num in nums: - res += [item+[num] for item in res] - return res \ No newline at end of file + + # 遍历每个元素,在当前结果集中添加该元素 + # Iterate over each element and add it to existing subsets in the result set + for num in nums: + # 通过列表推导式,将当前结果集中的每个子集与新元素组合成新的子集 + # Use list comprehension to combine current subsets with new elements to form new subsets + res += [item + [num] for item in res] + + # 返回所有可能的子集 + # Return all possible subsets + return res diff --git a/solutions/python3/780.py b/solutions/python3/780.py index b86c612..aaaca70 100644 --- a/solutions/python3/780.py +++ b/solutions/python3/780.py @@ -1,4 +1,19 @@ + class Solution: - def reachingPoints(self, sx, sy, tx, ty): - while sx bool: + # 中文注释:当 sx 小于 tx 且 sy 小于 ty 时,通过取模操作逐步缩小 tx 和 ty 的值。 + # English comment: When sx is less than tx and sy is less than ty, reduce tx and ty by using modulo operation. + + while sx < tx and sy < ty: + # 中文注释:通过取余操作更新 tx 和 ty,确保 tx 保持大于等于 sx 且 ty 保持大于等于 sy。 + # English comment: Update tx and ty with modulo operations to ensure tx >= sx and ty >= sy. + + if tx > ty: + tx %= ty + else: + ty %= tx + + # 中文注释:检查最终的 tx 和 ty 是否满足条件,即 tx 是否等于 sx 且 (ty - sy) 能被 sx 整除,或者 ty 等于 sy 且 (tx - sx) 能被 sy 整除。 + # English comment: Check if the final tx and ty satisfy the conditions, i.e., tx equals sx and (ty - sy) is divisible by sx, or ty equals sy and (tx - sx) is divisible by sy. + + return sx == tx and (ty - sy) % sx == 0 or sy == ty and (tx - sx) % sy == 0 diff --git a/solutions/python3/781.py b/solutions/python3/781.py index 89de6eb..b08b3b7 100644 --- a/solutions/python3/781.py +++ b/solutions/python3/781.py @@ -1,6 +1,18 @@ + class Solution: + # 定义一个类来解决问题 + def numRabbits(self, answers): + # 初始化字典和结果计数器 dic, res = {}, 0 + for ans in answers: - (dic[ans], res) = (1, res + ans + 1) if ans not in dic or dic[ans] > ans else (dic[ans] + 1, res) - return res \ No newline at end of file + # 如果答案不在字典中,或者字典中的值大于当前答案,则更新字典并增加结果计数值 + if ans not in dic or dic[ans] > ans: + dic[ans] = 1 + res += ans + 1 + else: + # 否则,只增加字典对应的值 + dic[ans] += 1 + + return res # 返回最终结果 diff --git a/solutions/python3/782.py b/solutions/python3/782.py index b7112b4..2d6e658 100644 --- a/solutions/python3/782.py +++ b/solutions/python3/782.py @@ -1,15 +1,37 @@ + class Solution: def movesToChessboard(self, b): + """ + :param b: List[List[int]] - 棋盘状态,0表示空位,1表示棋子 + :return: int - 将棋盘变为标准国际象棋排列所需的最少移动次数,-1表示无法完成 + + 1. 首先检查每行和每列的初始状态是否满足要求。 + 中文:首先检查每一行和每一列的初始状态是否满足要求。 + """ N = len(b) - if any(b[0][0] ^ b[i][0] ^ b[0][j] ^ b[i][j] for i in range(N) for j in range(N)): return -1 - if not N // 2 <= sum(b[0]) <= (N + 1) // 2: return -1 - if not N // 2 <= sum(b[i][0] for i in range(N)) <= (N + 1) // 2: return -1 + + # 检查对角线元素,确保不冲突 + if any(b[0][0] ^ b[i][0] ^ b[0][j] ^ b[i][j] for i in range(N) for j in range(N)): + return -1 + + # 检查每行和每列棋子数量是否满足要求,不超过总数的一半 + if not N // 2 <= sum(b[0]) <= (N + 1) // 2: + return -1 + if not N // 2 <= sum(b[i][0] for i in range(N)) <= (N + 1) // 2: + return -1 + + # 统计第0行和第0列满足标准排列的元素个数 col = sum(b[0][i] == i % 2 for i in range(N)) row = sum(b[i][0] == i % 2 for i in range(N)) + + # 如果棋盘大小为奇数,调整col和row使其满足标准排列的条件 if N % 2: - if col % 2: col = [col, N - col][col % 2] - if row % 2: row = N - row - else: + if col % 2: + col = N - col + if row % 2: + row = N - row + else: # 棋盘大小为偶数时的情况 col = min(N - col, col) row = min(N - row, row) - return (col + row) // 2 \ No newline at end of file + + return (col + row) // 2 diff --git a/solutions/python3/783.py b/solutions/python3/783.py index 5deab43..d159228 100644 --- a/solutions/python3/783.py +++ b/solutions/python3/783.py @@ -1,8 +1,19 @@ + class Solution: + # 定义一个递归函数进行深度优先搜索,用于遍历二叉查找树的每个节点 def minDiffInBST(self, root): + # 递归终止条件:如果当前节点为空,则返回无穷大表示不存在差值,以及左右边界值 def dfs(node): - if not node: return float("inf"), float("inf"), -float("inf") + if not node: + return float("inf"), float("inf"), -float("inf") + + # 对左子树进行递归调用,获取最小最大值和左右边界 l, lMn, lMx = dfs(node.left) + # 对右子树进行递归调用,获取最小最大值和左右边界 r, rMn, rMx = dfs(node.right) + + # 计算当前节点与左子树的最大值的差值、当前节点与右子树的最小值的差值,以及左子树中的最小值、右子树中的最大值 return min(l, node.val - lMx, r, rMn - node.val), min(lMn, node.val), max(rMx, node.val) - return dfs(root)[0] \ No newline at end of file + + # 调用dfs函数开始遍历,并返回二叉查找树中节点间最小差值 + return dfs(root)[0] diff --git a/solutions/python3/784.py b/solutions/python3/784.py index d63910f..ba74aa4 100644 --- a/solutions/python3/784.py +++ b/solutions/python3/784.py @@ -1,9 +1,17 @@ + class Solution: def letterCasePermutation(self, S: str) -> List[str]: + # 初始化一个队列,用于存储当前生成的所有可能的字母变化组合 bfs = [''] + + # 遍历输入字符串S中的每一个字符c for c in S: + # 如果字符c是数字,则直接将其添加到所有已有组合之后 if c.isdigit(): bfs = [s + c for s in bfs] else: + # 如果字符c是字母,则生成其大小写两种可能,并分别添加到已有组合之后 bfs = [s + c.lower() for s in bfs] + [s + c.upper() for s in bfs] - return bfs \ No newline at end of file + + # 返回所有可能的字母变化组合 + return bfs diff --git a/solutions/python3/785.py b/solutions/python3/785.py index e42ab39..ec9cf03 100644 --- a/solutions/python3/785.py +++ b/solutions/python3/785.py @@ -1,15 +1,31 @@ + class Solution: + # 定义判断图是否为二分图的方法 def isBipartite(self, graph): + # 初始化每个节点所属的"侧",0表示未访问 side = [0] * len(graph) + + # 深度优先搜索辅助函数 def dfs(node): + # 遍历当前节点的所有邻接节点 for v in graph[node]: if side[v] == 0: + # 如果未被访问,分配不同的"侧" side[v] = -side[node] - if not dfs(v): return False - elif side[v] == side[node]: return False + # 继续递归检查该邻接节点 + if not dfs(v): + return False + elif side[v] == side[node]: + # 若邻接节点与当前节点同"侧",返回False + return False return True + + # 遍历图中每个节点 for i in range(len(graph)): + # 如果未被访问,则标记为1并进行深度优先搜索 if side[i] == 0: side[i] = 1 - if not dfs(i): return False - return True \ No newline at end of file + if not dfs(i): + return False + + return True diff --git a/solutions/python3/786.py b/solutions/python3/786.py index 3bd3d7e..6d5346d 100644 --- a/solutions/python3/786.py +++ b/solutions/python3/786.py @@ -1,16 +1,29 @@ + class Solution: + # 定义一个解决方案类,用于寻找第K小的质分数 + def kthSmallestPrimeFraction(self, A, K): + # 使用最小堆来存储当前未访问的分母和分子对及其对应的值 heap, used = [(A[0] / A[-1], 0, len(A) - 1)], {(0, len(A) - 1)} + for i in range(K): try: + # 弹出堆顶元素,并将其对应的分母和分子对添加到已访问集合中 cur, l, r = heapq.heappop(heap) used.add((l, r)) + + # 如果左侧的下一个分数组合未被访问过,那么就将它加入堆中并标记为已访问 if (l + 1, r) not in used: heapq.heappush(heap, (A[l + 1] / A[r], l + 1, r)) used.add((l + 1, r)) + + # 如果右侧的上一个分数组合未被访问过,那么就将它加入堆中并标记为已访问 if (l, r - 1) not in used: heapq.heappush(heap, (A[l] / A[r - 1], l, r - 1)) used.add((l, r - 1)) except: + # 如果堆为空,则跳出循环,结束处理 break - return [A[l], A[r]] \ No newline at end of file + + # 返回第K小的质分数对应的分子和分母 + return [A[l], A[r]] diff --git a/solutions/python3/787.py b/solutions/python3/787.py index fee8802..1e1ab37 100644 --- a/solutions/python3/787.py +++ b/solutions/python3/787.py @@ -1,14 +1,26 @@ + class Solution: + # 初始化航班信息字典,键为出发地,值为列表,包含目的地和价格元组 def findCheapestPrice(self, n, flights, src, dst, K): - flight = collections.defaultdict(list) + from collections import defaultdict + import heapq + + flight = defaultdict(list) for s, e, p in flights: flight[s].append((e, p)) + + # 使用优先队列存储价格、城市和剩余中转次数,初始时为起点城市和K+1次中转机会的价格0 heap = [(0, src, K + 1)] + while heap: price, city, stop = heapq.heappop(heap) if city == dst: + # 如果到达目的地,则返回当前价格 return price elif stop > 0: + # 对于每个邻居城市,更新剩余中转次数并加入优先队列 for c, p in flight[city]: heapq.heappush(heap, (price + p, c, stop - 1)) - return -1 \ No newline at end of file + + # 如果未找到符合条件的路径,则返回-1 + return -1 diff --git a/solutions/python3/788.py b/solutions/python3/788.py index 8e2d942..6281a98 100644 --- a/solutions/python3/788.py +++ b/solutions/python3/788.py @@ -1,27 +1,44 @@ + class Solution: - def rotatedDigits(self, N): + def rotatedDigits(self, N: int) -> int: """ :type N: int :rtype: int """ + # 初始化结果计数器 res = 0 + + # 遍历范围[1, N] for i in range(1, N + 1): - i = str(i) - tmp = [] - check = True - for char in i: + # 将数字转换为字符串形式 + i_str = str(i) + tmp_list = [] + check_flag = True + + # 遍历每个字符,检查并转换可旋转数字 + for char in i_str: if char in ("3", "4", "7"): - check = False + # 发现不可旋转的数字,设置标志位结束循环 + check_flag = False break - if char in ("0", "1", "8"): - tmp.append(char) - if char == "2": - tmp.append("5") - if char == "5": - tmp.append("2") - if char == "6": - tmp.append("9") - if char == "9": - tmp.append("6") - if check and i != "".join(tmp): res += 1 - return res \ No newline at end of file + elif char in ("0", "1", "8"): + # 可保持不变的数字直接加入临时列表 + tmp_list.append(char) + elif char == "2": + # 旋转2到5 + tmp_list.append("5") + elif char == "5": + # 旋转5到2 + tmp_list.append("2") + elif char == "6": + # 旋转6到9 + tmp_list.append("9") + elif char == "9": + # 旋转9到6 + tmp_list.append("6") + + # 检查转换后与原数字是否不同且没有不可旋转的数字 + if check_flag and i != "".join(tmp_list): + res += 1 + + return res diff --git a/solutions/python3/789.py b/solutions/python3/789.py index b96e4d9..bd2d631 100644 --- a/solutions/python3/789.py +++ b/solutions/python3/789.py @@ -1,6 +1,15 @@ + class Solution: + # 定义一个Solution类,包含escapeGhosts方法用于判断是否能成功逃脱幽灵 + def escapeGhosts(self, ghosts, target): + # 计算目标位置到原点的距离 d = abs(target[0]) + abs(target[1]) + for ghost in ghosts: - if abs(ghost[0] - target[0]) + abs(ghost[1] - target[1]) <= d: return False - return True \ No newline at end of file + # 检查每个幽灵的位置,判断是否存在一条路径可以比幽灵更快到达目标 + if abs(ghost[0] - target[0]) + abs(ghost[1] - target[1]) <= d: + return False + + # 如果所有幽灵都无法在更短时间内达到目标,则返回True + return True diff --git a/solutions/python3/79.py b/solutions/python3/79.py index ed1a570..9cd80c9 100644 --- a/solutions/python3/79.py +++ b/solutions/python3/79.py @@ -1,11 +1,31 @@ + class Solution: def exist(self, board, word): + """ + 判断是否可以在棋盘中找到给定单词。 + + :param board: 二维列表,表示游戏棋盘 + :param word: 字符串,要查找的单词 + """ m, n, o = len(board), len(board and board[0]), len(word) + def explore(i, j, k, q): + """ + 深度优先搜索辅助函数 + + :param i: 当前行索引 + :param j: 当前列索引 + :param k: 当前单词索引 + :param q: 已访问过的坐标集合 + """ for x, y in ((i - 1, j), (i, j - 1), (i + 1, j), (i, j + 1)): - if k>=o or (0<=x= o or (0 <= x < m and 0 <= y < n and board[x][y] == word[k] + and (x, y) not in q and explore(x, y, k + 1, q | {(x, y)})): + return True return False + for i in range(m): for j in range(n): - if board[i][j] == word[0] and explore(i, j, 1, {(i, j)}): return True - return False \ No newline at end of file + if board[i][j] == word[0] and explore(i, j, 1, {(i, j)}): + return True + return False diff --git a/solutions/python3/791.py b/solutions/python3/791.py index 3d4864a..2c44c5d 100644 --- a/solutions/python3/791.py +++ b/solutions/python3/791.py @@ -1,14 +1,26 @@ + class Solution: - def customSortString(self, S, T): + def customSortString(self, S: str, T: str) -> str: """ - :type S: str - :type T: str - :rtype: str + :param S: 字符串S,表示排序顺序 + :param T: 字符串T,需要按S的顺序进行排序 + :return: 按照S中的顺序重新排列字符串T的结果 """ + + # 使用集合t保存字符串T中的所有字符,使用集合t2保存字符串S中的所有字符 t = set(T) t2 = set(S) + from collections import Counter as ct + + # 计算字符串T中每个字符的出现次数 c = ct(T) + + # 根据S中的字符和它们在T中的出现次数生成按顺序排列的部分 s = [char * c[char] for char in S if char in t] + + # 从T未出现在S中的字符中生成剩余部分 add = [char * c[char] for char in t - t2] - return "".join(s + add) \ No newline at end of file + + # 返回最终结果,即排序后的字符串 + return "".join(s + add) diff --git a/solutions/python3/792.py b/solutions/python3/792.py index f561521..97c71fb 100644 --- a/solutions/python3/792.py +++ b/solutions/python3/792.py @@ -1,8 +1,19 @@ + class Solution: + # 检查字符串s是否是word的子序列 + def check_subsequence(self, s, word): + index = 0 + # 遍历word中的每个字符 + for char in word: + # 在s中查找char,从当前index开始 + index = s.find(char, index) + 1 + # 如果找不到,则不是子序列 + if not index: + return False + # 所有字符都匹配上了 + return True + + # 计算words中有多少字符串是S的子序列 def numMatchingSubseq(self, S, words): - def check(s, i): - for c in s: - i = S.find(c, i) + 1 - if not i: return False - return True - return sum((check(word, 0) for word in words)) \ No newline at end of file + # 对每个word,调用check_subsequence检查是否是子序列 + return sum((self.check_subsequence(S, word) for word in words)) diff --git a/solutions/python3/793.py b/solutions/python3/793.py index 477832b..7102136 100644 --- a/solutions/python3/793.py +++ b/solutions/python3/793.py @@ -1,13 +1,16 @@ + class Solution: - - def count(self, num): + + # 计算给定数在阶乘中因子5的数量 + def count(self, num: int) -> int: cnt = 0 while num: cnt += num // 5 num //= 5 - return cnt + return cnt - def preimageSizeFZF(self, K): + # 查找预定义大小的最小整数,使其阶乘因子5的数量等于给定值K + def preimageSizeFZF(self, K: int) -> int: l, r = 0, 2 ** 63 - 1 while l < r: mid = (l + r) // 2 @@ -15,4 +18,4 @@ def preimageSizeFZF(self, K): l = mid + 1 else: r = mid - return 5 - (l % 5) if self.count(l) == K else 0 \ No newline at end of file + return 5 - (l % 5) if self.count(l) == K else 0 diff --git a/solutions/python3/794.py b/solutions/python3/794.py index d8e285c..f169cf6 100644 --- a/solutions/python3/794.py +++ b/solutions/python3/794.py @@ -1,26 +1,27 @@ + class Solution(object): def check_win_positions(self, board, player): """ - Check if the given player has a win position. - Return True if there is a win position. Else return False. + 检查给定玩家是否有胜利位置。 + 如果有胜利位置返回True,否则返回False。 """ - #Check the rows + # 检查行 for i in range(len(board)): if board[i][0] == board[i][1] == board[i][2] == player: - return True + return True - #Check the columns + # 检查列 for i in range(len(board)): if board[0][i] == board[1][i] == board[2][i] == player: - return True - - #Check the diagonals - if board[0][0] == board[1][1] == board[2][2] == player or \u005C - board[0][2] == board[1][1] == board[2][0] == player: + return True + + # 检查对角线 + if (board[0][0] == board[1][1] == board[2][2] == player or + board[0][2] == board[1][1] == board[2][0] == player): return True - + return False - + def validTicTacToe(self, board): """ :type board: List[str] @@ -32,18 +33,20 @@ def validTicTacToe(self, board): for j in range(len(board[0])): if board[i][j] == "X": x_count += 1 - elif board[i][j] == "O": + elif board[i][j] == "O": o_count += 1 - - if o_count > x_count or x_count-o_count>1: + + # 检查棋子数量是否合理 + if o_count > x_count or x_count - o_count > 1: return False - + + # 检查胜利条件是否合理 if self.check_win_positions(board, 'O'): if self.check_win_positions(board, 'X'): return False return o_count == x_count - if self.check_win_positions(board, 'X') and x_count!=o_count+1: + if self.check_win_positions(board, 'X') and x_count != o_count + 1: return False - return True \ No newline at end of file + return True diff --git a/solutions/python3/795.py b/solutions/python3/795.py index 64ae34b..be0dd3e 100644 --- a/solutions/python3/795.py +++ b/solutions/python3/795.py @@ -1,3 +1,4 @@ + class Solution: def numSubarrayBoundedMax(self, A, L, R): """ @@ -6,9 +7,18 @@ def numSubarrayBoundedMax(self, A, L, R): :type R: int :rtype: int """ + # 初始化结果、起始位置和连续有效子数组长度计数器 res, start, diff = 0, -1, 0 - for i in range (len(A)): - if L <= A[i] <= R: diff, res = i - start, res + i - start - elif A[i] > R: diff, start = 0, i - else: res += diff - return res \ No newline at end of file + + for i in range(len(A)): + if L <= A[i] <= R: + # 当前元素在范围内,更新连续有效子数组长度并累加结果 + diff, res = i - start, res + i - start + elif A[i] > R: + # 当前元素超过范围,重置起始位置和连续有效子数组长度计数器 + diff, start = 0, i + else: + # 当前元素在范围内但还未达到最大值,累加当前的连续有效子数组长度 + res += diff + + return res diff --git a/solutions/python3/797.py b/solutions/python3/797.py index 02ab867..5dd14f6 100644 --- a/solutions/python3/797.py +++ b/solutions/python3/797.py @@ -1,10 +1,23 @@ + class Solution: - def allPathsSourceTarget(self, graph, i = 0, q = [0]): - if i == 0: - global res - res = [] - if i == len(graph) - 1: - res.append(q) - for index in graph[i]: + def allPathsSourceTarget(self, graph, i=0, q=[0]): + """ + :param graph: 邻接表表示的图 (graph) + :param i: 当前处理节点索引 (i) + :param q: 从源点到当前节点的路径列表 (q) + :return: 所有可能的从源点到目标点的路径列表 (res) + """ + + if i == 0: + # 如果是起始节点,初始化结果列表 + self.res = [] + + if i == len(graph) - 1: + # 当到达目标节点时,将当前路径添加到结果中 + self.res.append(q) + + for index in graph[i]: + # 对于当前节点的所有邻居,递归寻找路径 self.allPathsSourceTarget(graph, index, q + [index]) - return res \ No newline at end of file + + return self.res diff --git a/solutions/python3/819.py b/solutions/python3/819.py index 3b85360..ef25e54 100644 --- a/solutions/python3/819.py +++ b/solutions/python3/819.py @@ -1,19 +1,35 @@ + +import re + class Solution: - def mostCommonWord(self, paragraph, banned): + def mostCommonWord(self, paragraph: str, banned: List[str]) -> str: """ :type paragraph: str :type banned: List[str] :rtype: str """ - paragraph = re.findall(r"\u005Cw+", paragraph) + + # 使用正则表达式提取所有单词,\w+ 表示一个或多个字母数字字符 + paragraph = re.findall(r"\w+", paragraph) + + # 初始化字典和最大频率记录 dic = {} mx = [0, 0] + + # 遍历每个单词并处理 for char in paragraph: - char = char.lower() - if char not in banned: - if char not in dic: dic[char] = 1 - else: dic[char] += 1 + char = char.lower() # 转换为小写以忽略大小写差异 + + if char not in banned: # 如果该单词不在禁止列表中 + if char not in dic: + dic[char] = 1 # 记录首次出现的频率 + else: + dic[char] += 1 # 增加已存在的单词计数 + + # 更新最大频率记录 mx[0] = max(mx[0], dic[char]) - if mx[0] == dic[char]: mx[1] = char - return mx[1] - \ No newline at end of file + + if mx[0] == dic[char]: + mx[1] = char # 当出现新最高频单词时更新结果 + + return mx[1] # 返回最频繁的非禁止单词 diff --git a/solutions/python3/82.py b/solutions/python3/82.py index 8d9b58b..f2b9d84 100644 --- a/solutions/python3/82.py +++ b/solutions/python3/82.py @@ -1,3 +1,4 @@ + # Definition for singly-linked list. # class ListNode: # def __init__(self, x): @@ -5,18 +6,25 @@ # self.next = None class Solution: - def deleteDuplicates(self, head): - dummy_left, dummy_left.next = ListNode(0), head - prev, prev_num = None, dummy_left - while head: + # 删除链表中的重复元素,返回新的无重复节点的链表头结点 + def deleteDuplicates(self, head: ListNode) -> ListNode: + dummy_left = ListNode(0) # 哑节点 + dummy_left.next = head # 将哑节点指向原链表头结点 + + prev, prev_num = None, dummy_left # 初始化前一个节点和前一个节点的前驱节点 + + while head: # 遍历整个链表 if prev and prev.val != head.val: - prev_num = prev + prev_num = prev # 更新前驱节点 + if prev and prev.val == head.val: while head and head.next and head.next.val == head.val: - head = head.next + head = head.next # 跳过重复节点 head = head.next - prev_num.next = head - prev = head + prev_num.next = head # 调整指针,跳过重复节点 + + prev = head # 更新前一个节点 if head: - head = head.next - return dummy_left.next \ No newline at end of file + head = head.next # 向后移动当前节点 + + return dummy_left.next # 返回新链表的头结点 diff --git a/solutions/python3/820.py b/solutions/python3/820.py index 73baedd..c3c1e28 100644 --- a/solutions/python3/820.py +++ b/solutions/python3/820.py @@ -1,10 +1,21 @@ + class Solution: + # 定义一个解决方案类,用于解决最小编码长度问题 + def minimumLengthEncoding(self, words): """ - :type words: List[str] - :rtype: int + :type words: List[str] - 输入单词列表 + :rtype: int - 返回最短的编码长度 + + 思路:使用集合去重,并通过遍历每个单词的所有子串来进一步去除冗余,最终计算剩余字符串的总长度加一。 """ s = set(words) - for word in words: - for i in range(1, len(word)): s.discard(word[i:]) - return sum(len(w) + 1 for w in s) \ No newline at end of file + # 将输入的单词列表转换为一个集合以移除重复项 + + for word in words: + for i in range(1, len(word)): + # 遍历每个单词的所有子串(从第二个字符开始) + s.discard(word[i:]) + # 从当前单词的子串在集合中删除,确保没有冗余 + return sum(len(w) + 1 for w in s) + # 返回剩余字符串总长度加一之和 diff --git a/solutions/python3/821.py b/solutions/python3/821.py index 3f3e43a..b3812b4 100644 --- a/solutions/python3/821.py +++ b/solutions/python3/821.py @@ -1,14 +1,23 @@ + class Solution: - def shortestToChar(self, S, C): + def shortestToChar(self, S: str, C: str) -> List[int]: """ - :type S: str - :type C: str - :rtype: List[int] + :type S: str # 输入字符串S + :type C: str # 目标字符C + :rtype: List[int] # 返回列表,表示每个位置到最近的字符C的距离 """ - char1, char2, diff1, diff2, res = False, False, 0, 0, [None]* len(S) + char1, char2, diff1, diff2, res = False, False, 0, 0, [None] * len(S) + for i in range(len(S)): - if char1: res[i], diff1 = min(res[i], diff1 + 1) if res[i] else diff1 + 1, diff1 + 1 - if S[i] == C: diff1, res[i], char1 = 0, 0, True - if char2: res[len(S) - 1 - i], diff2 = min(res[len(S) - 1 - i], diff2 + 1) if res[len(S) - 1 - i] else diff2 + 1, diff2 + 1 - if S[len(S) - 1 - i] == C: diff2, res[len(S) - 1 - i], char2 = 0, 0, True - return res \ No newline at end of file + if char1: + res[i], diff1 = min(res[i], diff1 + 1) if res[i] else diff1 + 1, diff1 + 1 + if S[i] == C: + diff1, res[i], char1 = 0, 0, True + + if char2: + res[len(S) - 1 - i], diff2 = min(res[len(S) - 1 - i], diff2 + 1) if res[len(S) - 1 - i] else diff2 + 1, diff2 + 1 + if S[len(S) - 1 - i] == C: + diff2, res[len(S) - 1 - i], char2 = 0, 0, True + + return res + \ No newline at end of file diff --git a/solutions/python3/822.py b/solutions/python3/822.py index b487c91..d29662c 100644 --- a/solutions/python3/822.py +++ b/solutions/python3/822.py @@ -1,8 +1,13 @@ + class Solution: - def flipgame(self, fronts, backs): + def flipgame(self, fronts: List[int], backs: List[int]) -> int: """ - :type fronts: List[int] - :type backs: List[int] - :rtype: int + :param fronts: 正面数字列表 + :param backs: 反面数字列表 + :return: 能翻转的最小不同数字,如果找不到返回0 """ - return min((set(fronts) | set(backs)) - set(fronts[i] for i in range(len(fronts)) if fronts[i] == backs[i]), default = 0) \ No newline at end of file + # 使用集合操作合并正面和反面数字,并移除同时出现在正面和反面的数字 + unique_numbers = (set(fronts) | set(backs)) - set(fronts[i] for i in range(len(fronts)) if fronts[i] == backs[i]) + + # 返回最小值,如果为空则返回0 + return min(unique_numbers, default=0) diff --git a/solutions/python3/823.py b/solutions/python3/823.py index 1a620b1..ae911d9 100644 --- a/solutions/python3/823.py +++ b/solutions/python3/823.py @@ -1,15 +1,29 @@ + class Solution: def numFactoredBinaryTrees(self, A): """ :type A: List[int] :rtype: int """ + # 对输入数组A进行排序,便于后续处理 A.sort() + + # 初始化集合、结果计数器和字典结构 nums, res, trees, factors = set(A), 0, {}, collections.defaultdict(set) + + # 遍历每个元素作为根节点 for i, num in enumerate(A): + # 对于当前根节点num,寻找可以作为其因子的其他数n for n in A[:i]: - if num % n == 0 and num // n in nums: factors[num].add(n) + if num % n == 0 and num // n in nums: + factors[num].add(n) + + # 遍历每个根节点并计算可能的树的数量 for root in A: - trees[root] = 1 - for fac in factors[root]: trees[root] += trees[fac] * trees[root // fac] - return sum(trees.values()) % ((10 ** 9) + 7) \ No newline at end of file + trees[root] = 1 # 基础情况:单个节点 + for fac in factors[root]: + # 累加因子及其对应子树数量的乘积作为当前节点的子树数量 + trees[root] += trees[fac] * trees[root // fac] + + # 返回结果,注意取模以符合问题要求 + return sum(trees.values()) % ((10 ** 9) + 7) diff --git a/solutions/python3/824.py b/solutions/python3/824.py index c395112..4a27d07 100644 --- a/solutions/python3/824.py +++ b/solutions/python3/824.py @@ -1,4 +1,14 @@ + class Solution: def toGoatLatin(self, S): - s, vowels = S.split(), {"a", "e", "i", "o", "u"} - return " ".join([(s[i][0].lower() in vowels and s[i] or s[i][1:] + s[i][0]) + "m" + "a" * (i + 2) for i in range(len(s))]) \ No newline at end of file + """ + 将字符串转换为Goat Latin格式。 + + 参数: + S (str): 输入的原始字符串 + + 返回: + str: 转换后的Goat Latin格式的字符串 + """ + s, vowels = S.split(), {"a", "e", "i", "o", "u"} # 分割字符串并定义元音集合 + return " ".join([(s[i][0].lower() in vowels and s[i] or s[i][1:] + s[i][0]) + "ma" + "a" * (i + 2) for i in range(len(s))]) # 生成Goat Latin格式字符串 diff --git a/solutions/python3/825.py b/solutions/python3/825.py index 639ce1f..40f7d4f 100644 --- a/solutions/python3/825.py +++ b/solutions/python3/825.py @@ -1,13 +1,28 @@ + +from collections import Counter + class Solution: + # 计算朋友请求的数量 def numFriendRequests(self, ages): """ :type ages: List[int] :rtype: int """ - cntr, res = collections.Counter(ages), 0 + + # 使用Counter统计年龄出现次数 + cntr = Counter(ages) + res = 0 + + # 遍历每个年龄段A for A in cntr: + # 遍历每个年龄段B for B in cntr: + # 如果不符合请求条件则跳过本次循环 if B <= 0.5 * A + 7 or B > A: continue - if A == B: res += cntr[A] *(cntr[A] - 1) + + # 当A和B相同时,计算组合数(A,B) = C(n,2) + if A == B: res += cntr[A] * (cntr[A] - 1) + # 当A不等于B时,直接计算两个年龄段的乘积 else: res += cntr[A] * cntr[B] - return res \ No newline at end of file + + return res diff --git a/solutions/python3/826.py b/solutions/python3/826.py index 7b6f9ae..2a7cfa2 100644 --- a/solutions/python3/826.py +++ b/solutions/python3/826.py @@ -1,16 +1,23 @@ + class Solution: - def maxProfitAssignment(self, difficulty, profit, worker): + def maxProfitAssignment(self, difficulty: list[int], profit: list[int], worker: list[int]) -> int: """ :type difficulty: List[int] :type profit: List[int] :type worker: List[int] :rtype: int """ - jobs = sorted([a, b] for a, b in zip(difficulty, profit)) + # 将难度和利润打包成元组,按难度排序 + jobs = sorted(zip(difficulty, profit)) + res = i = maxp = 0 + # 工人能力按从小到大排序 for ability in sorted(worker): while i < len(jobs) and ability >= jobs[i][0]: + # 更新当前最大利润 maxp = max(jobs[i][1], maxp) i += 1 + # 累加最大可得利润 res += maxp - return res \ No newline at end of file + + return res diff --git a/solutions/python3/827.py b/solutions/python3/827.py index 4514529..fb4f9f8 100644 --- a/solutions/python3/827.py +++ b/solutions/python3/827.py @@ -1,23 +1,68 @@ + class Solution: def largestIsland(self, grid): + """ + 解决问题:找出给定二维网格中最大岛屿的面积。 + + 参数: + - grid: List[List[int]] -- 给定的0(水)和1(陆地)构成的矩阵 + + 返回值: + - int -- 最大的岛屿面积 + """ + def explore(i, j): + """ + 递归遍历岛屿,并标记访问过的节点。 + + 参数: + - i: int -- 当前行索引 + - j: int -- 当前列索引 + """ dic[(i, j)], count[curr] = curr, count[curr] + 1 - if i > 0 and grid[i - 1][j] == 1 and (i - 1, j) not in dic: explore(i - 1, j) - if j > 0 and grid[i][j - 1] == 1 and (i, j - 1) not in dic: explore(i, j - 1) - if i + 1 < len(grid) and grid[i + 1][j] ==1 and (i + 1, j) not in dic: explore(i + 1, j) - if j + 1 < len(grid) and grid[i][j + 1] == 1 and (i, j + 1) not in dic: explore(i, j + 1) + if i > 0 and grid[i - 1][j] == 1 and (i - 1, j) not in dic: + explore(i - 1, j) + if j > 0 and grid[i][j - 1] == 1 and (i, j - 1) not in dic: + explore(i, j - 1) + if i + 1 < len(grid) and grid[i + 1][j] == 1 and (i + 1, j) not in dic: + explore(i + 1, j) + if j + 1 < len(grid) and grid[i][j + 1] == 1 and (i, j + 1) not in dic: + explore(i, j + 1) + def neighbours(i, j, adj): - if i > 0 and grid[i - 1][j] == 1 and dic[(i - 1, j)] not in adj: adj.add(dic[(i - 1, j)]) - if j > 0 and grid[i][j - 1] == 1 and dic[(i, j - 1)] not in adj: adj.add(dic[(i, j - 1)]) - if i + 1 < len(grid) and grid[i + 1][j] ==1 and dic[(i + 1, j)] not in adj: adj.add(dic[(i + 1, j)]) - if j + 1 < len(grid) and grid[i][j + 1] == 1 and dic[(i, j + 1)] not in adj: adj.add(dic[(i, j + 1)]) + """ + 获取相邻的岛屿编号。 + + 参数: + - i: int -- 当前行索引 + - j: int -- 当前列索引 + - adj: set[int] -- 存储相邻岛屿编号 + + 返回值: + - adj: set[int] -- 更新后的相邻岛屿编号集合 + """ + if i > 0 and grid[i - 1][j] == 1 and dic[(i - 1, j)] not in adj: + adj.add(dic[(i - 1, j)]) + if j > 0 and grid[i][j - 1] == 1 and dic[(i, j - 1)] not in adj: + adj.add(dic[(i, j - 1)]) + if i + 1 < len(grid) and grid[i + 1][j] == 1 and dic[(i + 1, j)] not in adj: + adj.add(dic[(i + 1, j)]) + if j + 1 < len(grid) and grid[i][j + 1] == 1 and dic[(i, j + 1)] not in adj: + adj.add(dic[(i, j + 1)]) return adj + curr, dic, count, res = 0, {}, collections.defaultdict(int), 0 for i in range(len(grid)): for j in range(len(grid)): - if grid[i][j] == 1 and (i, j) not in dic: curr += 1; explore(i, j) + if grid[i][j] == 1 and (i, j) not in dic: + curr += 1; explore(i, j) + for i in range(len(grid)): for j in range(len(grid)): - if grid[i][j] == 1: res = max(res, count[dic[(i, j)]]) - else: res = max(res, sum(count[r] for r in neighbours(i, j, set())) + 1) - return res \ No newline at end of file + if grid[i][j] == 1: + res = max(res, count[dic[(i, j)]]) + else: + adj = set() + res = max(res, sum(count[r] for r in neighbours(i, j, adj)) + 1) + + return res diff --git a/solutions/python3/828.py b/solutions/python3/828.py index d6a1898..c60e730 100644 --- a/solutions/python3/828.py +++ b/solutions/python3/828.py @@ -1,12 +1,24 @@ + class Solution: + # 定义一个解决方案类 + def uniqueLetterString(self, S): + # 初始化每个大写字母的索引数组为[-1, -1] index = {c: [-1, -1] for c in string.ascii_uppercase} + res = 0 + # 遍历字符串S中的每一个字符及其位置 for i, c in enumerate(S): k, j = index[c] + # 计算当前字符作为子串起始或结束的唯一字符串数量,并累加到结果中 res += (i - j) * (j - k) + # 更新该字符的最新位置 index[c] = [j, i] + + # 遍历所有大写字母,计算剩余部分的贡献值 for c in index: k, j = index[c] res += (len(S) - j) * (j - k) - return res % (10**9 + 7) \ No newline at end of file + + # 返回结果对10^9 + 7取模后的值 + return res % (10**9 + 7) diff --git a/solutions/python3/829.py b/solutions/python3/829.py index c7ee752..eb6020e 100644 --- a/solutions/python3/829.py +++ b/solutions/python3/829.py @@ -1,10 +1,24 @@ + class Solution: + # 计算满足条件的连续整数序列数量 def consecutiveNumbersSum(self, N): - cnt=0 - for d in range(1, N+1): - diff=d*(d-1)//2 + # 统计符合条件的数量 + cnt = 0 + + # 遍历可能的差值d,范围从1到N + for d in range(1, N + 1): + # 计算当前差值下的总和与N的差异diff + diff = d * (d - 1) // 2 + + # 计算剩余需要补充的部分nd nd = N - diff - if nd<=0: break - if nd%d==0: - cnt+=1 - return cnt \ No newline at end of file + + # 如果剩余部分小于等于0,则结束循环 + if nd <= 0: + break + + # 检查剩余部分是否能被当前差值整除,是则计数+1 + if nd % d == 0: + cnt += 1 + + return cnt diff --git a/solutions/python3/83.py b/solutions/python3/83.py index 5fcf85a..5e79ae5 100644 --- a/solutions/python3/83.py +++ b/solutions/python3/83.py @@ -1,8 +1,16 @@ + class Solution: - def deleteDuplicates(self, head): - cur = root = head - while head: - if head.val != cur.val: - cur.next = cur = head - head = cur.next = head.next - return root \ No newline at end of file + # 初始化节点 + def deleteDuplicates(self, head: ListNode) -> ListNode: + """ + :param head: 链表头结点 + :return: 删除重复元素后的链表头结点 + """ + cur = root = head # 当前指针初始化为根节点和head + + while head: # 遍历链表 + if head.val != cur.val: # 如果当前节点值与cur不等 + cur.next = cur = head # 更新cur指向并移动cur到head的位置 + head = cur.next = head.next # 移动head指针 + + return root # 返回新的头结点 diff --git a/solutions/python3/830.py b/solutions/python3/830.py index 1251548..b561b00 100644 --- a/solutions/python3/830.py +++ b/solutions/python3/830.py @@ -1,9 +1,21 @@ + class Solution: - def largeGroupPositions(self, S): - res = [] - l = r = 0 + def largeGroupPositions(self, S: str) -> list[list[int]]: + """ + 寻找字符串中长度至少为3的相同字符连续子串的位置 + + 英文: + Find the positions of substrings in a string where characters are consecutive and identical with length at least 3. + """ + res = [] # 存储结果 + l = r = 0 # 初始化左右指针 + for i in range(1, len(S)): - if S[i] == S[i - 1]: r += 1 - if r - l >= 2 and (S[i] != S[i - 1] or i == len(S) - 1): res.append([l, r]) - if S[i] != S[i - 1]: l = r = i - return res \ No newline at end of file + if S[i] == S[i - 1]: # 如果当前字符和前一个相同,右指针r加一 + r += 1 + elif r - l >= 2 and (S[i] != S[i - 1] or i == len(S) - 1): # 当满足条件时,记录子串位置 + res.append([l, r]) + if S[i] != S[i - 1]: # 如果当前字符和前一个不同,重置左右指针 + l = r = i + + return res # 返回结果 diff --git a/solutions/python3/831.py b/solutions/python3/831.py index ecd184d..2ba0b0b 100644 --- a/solutions/python3/831.py +++ b/solutions/python3/831.py @@ -1,10 +1,20 @@ + class Solution: - def maskPII(self, S): + # 定义一个类来处理PII掩码 + + def maskPII(self, S: str) -> str: + # 如果输入字符串包含@ if "@" in S: + # 将字符串转换为小写并按@分割 s = S.lower().split("@") + # 返回格式化后的电子邮件地址 return s[0][0] + "*" * 5 + s[0][-1] + "@" + s[1] else: - nums, tmp = {"0","1","2","3","4","5","6","7","8","9"}, "" + # 定义一个集合来存储数字字符 + nums, tmp = {"0", "1", "2", "3", "4", "5", "6", "7", "8", "9"}, "" + # 遍历字符串中的每个字符 for c in S: - if c in nums: tmp += c - return "+" + "*" * (len(tmp) - 10) + "-***-***-" + tmp[-4:] if len(tmp) > 10 else "***-***-" + tmp[-4:] \ No newline at end of file + if c in nums: # 如果是数字,添加到临时变量中 + tmp += c + # 根据电话号码长度返回不同格式的掩码 + return "+" + "*" * (len(tmp) - 10) + "-***-***-" + tmp[-4:] if len(tmp) > 10 else "***-***-" + tmp[-4:] diff --git a/solutions/python3/832.py b/solutions/python3/832.py index e978fe8..48ddb86 100644 --- a/solutions/python3/832.py +++ b/solutions/python3/832.py @@ -1,3 +1,9 @@ + class Solution(object): + # 定义一个类来解决问题 + def flipAndInvertImage(self, A): - return [[1 - x for x in A[i][::-1]] for i in range(len(A))] \ No newline at end of file + # 对每个二维数组A中的每一行进行翻转并逐位取反 + + return [[1 - x for x in A[i][::-1]] for i in range(len(A))] + # 通过列表推导式实现:先对每行进行反转[::-1],然后逐元素取反1-x diff --git a/solutions/python3/833.py b/solutions/python3/833.py index aedd85f..2b63552 100644 --- a/solutions/python3/833.py +++ b/solutions/python3/833.py @@ -1,9 +1,19 @@ + class Solution: - def findReplaceString(self, s, indexes, sources, targets): + # 定义一个解决方案类 + + def findReplaceString(self, s: str, indexes: list[int], sources: list[str], targets: list[str]) -> str: + # 初始化结果字符串,字典用于存储索引与替换信息的对应关系,初始化指针j res, dic, j = "", {}, 0 + + # 遍历所有需要替换的内容,构建字典dic保存起始位置和对应的源串及目标串 for i in range(len(sources)): - if s.find(sources[i], indexes[i]) == indexes[i]: dic[indexes[i]] = (sources[i], targets[i]) + if s.find(sources[i], indexes[i]) == indexes[i]: + dic[indexes[i]] = (sources[i], targets[i]) + + # 通过指针j遍历字符串s,根据字典dic进行替换操作 while j < len(s): res += j in dic and dic[j][1] or s[j] j += j in dic and len(dic[j][0]) or 1 - return res \ No newline at end of file + + return res # 返回最终的结果字符串 diff --git a/solutions/python3/834.py b/solutions/python3/834.py index f40a752..66a87c9 100644 --- a/solutions/python3/834.py +++ b/solutions/python3/834.py @@ -1,24 +1,33 @@ + class Solution: - def sumOfDistancesInTree(self, N, edges): - tree = collections.defaultdict(set) - res = [0] * N - count = [1] * N + # 初始化树和结果列表,每个节点的子节点计数以及路径长度 + def sumOfDistancesInTree(self, N: int, edges: list[list[int]]) -> list[int]: + from collections import defaultdict + + tree = defaultdict(set) # 存储树结构,默认值为集合 + res = [0] * N # 初始化结果列表,每个节点的路径长度初始化为0 + count = [1] * N # 初始化子节点计数,每个节点初始子节点数为1 + for i, j in edges: - tree[i].add(j) + tree[i].add(j) # 构建树结构 tree[j].add(i) - def dfs(root, pre): + def dfs(root: int, pre: int) -> None: + """深度优先搜索计算每个节点的路径长度和子节点计数""" for i in tree[root]: if i != pre: - dfs(i, root) - count[root] += count[i] - res[root] += res[i] + count[i] + dfs(i, root) # 递归遍历子节点 + count[root] += count[i] # 更新当前节点的子节点总数 + res[root] += res[i] + count[i] # 更新当前节点路径长度 - def dfs2(root, pre): + def dfs2(root: int, pre: int) -> None: + """第二次深度优先搜索,计算每个节点相对于根节点的路径长度""" for i in tree[root]: if i != pre: - res[i] = res[root] - count[i] + N - count[i] - dfs2(i, root) - dfs(0, -1) - dfs2(0, -1) - return res \ No newline at end of file + res[i] = res[root] - count[i] + N - count[i] # 计算新路径长度 + dfs2(i, root) # 递归遍历子节点 + + dfs(0, -1) # 从根节点开始,深度优先搜索计算初始路径长度和子节点数 + dfs2(0, -1) # 再次深度优先搜索,计算最终每个节点的路径长度 + + return res # 返回结果列表 diff --git a/solutions/python3/835.py b/solutions/python3/835.py index 22f6451..6e252fa 100644 --- a/solutions/python3/835.py +++ b/solutions/python3/835.py @@ -1,4 +1,28 @@ + class Solution: - def largestOverlap(self, A, B): - n, shift, rn = len(A), range(-1 * len(A) + 1, len(A)), range(len(A)) - return max(sum(A[i][j] and B[i + v][j + h] for i in rn for j in rn if 0 <= i + v < n > j + h >= 0) for h in shift for v in shift) \ No newline at end of file + # 定义Solution类,用于解决两个矩阵的重叠问题 + + def largestOverlap(self, A: List[List[int]], B: List[List[int]]) -> int: + """ + :param A: 一个二进制矩阵(0 和 1) + :param B: 另一个与A同大小的二进制矩阵 + :return: 返回两个矩阵重叠时最大1的数量 + + 通过计算所有可能的平移,找到使得A和B重叠后包含最多'1'的次数。 + """ + + n = len(A) + # 计算矩阵的大小 + + shift_range = range(-n + 1, n) # 平移范围从 - (n-1) 到 (n-1) + + max_overlap = 0 + for v in shift_range: + for h in shift_range: + overlap_count = sum(A[i][j] and B[i + v][j + h] + for i in range(n) for j in range(n) + if 0 <= i + v < n and 0 <= j + h < n) + # 计算每个平移后A和B重叠的'1'的数量 + max_overlap = max(max_overlap, overlap_count) + + return max_overlap diff --git a/solutions/python3/836.py b/solutions/python3/836.py index 609f871..5e73524 100644 --- a/solutions/python3/836.py +++ b/solutions/python3/836.py @@ -1,5 +1,17 @@ + class Solution: - def isRectangleOverlap(self, rec1, rec2): - x = (rec1[2] - rec1[0] + rec2[2] - rec2[0]) > (max(rec1[2], rec2[2]) - min(rec1[0], rec2[0])) - y = (rec1[3] - rec1[1] + rec2[3] - rec2[1]) > (max(rec1[3], rec2[3]) - min(rec1[1], rec2[1])) - return x and y \ No newline at end of file + """ + 判断两个矩形是否重叠 + + 通过检查两个矩形在x轴和y轴上的投影是否相互交错来判断。 + """ + + def isRectangleOverlap(self, rec1: list[int], rec2: list[int]) -> bool: + # 检查矩形的左边界与右边界是否交错 + x_overlap = (rec1[2] - rec1[0] + rec2[2] - rec2[0]) > (max(rec1[2], rec2[2]) - min(rec1[0], rec2[0])) + + # 检查矩形的下边界与上边界是否交错 + y_overlap = (rec1[3] - rec1[1] + rec2[3] - rec2[1]) > (max(rec1[3], rec2[3]) - min(rec1[1], rec2[1])) + + # 两个方向都需交错,矩形才重叠 + return x_overlap and y_overlap diff --git a/solutions/python3/837.py b/solutions/python3/837.py index 6e21e14..c9abcd4 100644 --- a/solutions/python3/837.py +++ b/solutions/python3/837.py @@ -1,11 +1,37 @@ + class Solution: - def new21Game(self, N, K, W): - if K == 0 or N >= K + W: return 1 - dp = [1.0] + [0.0] * N - Wsum, res = 1.0, 0.0 + def new21Game(self, N: int, K: int, W: int) -> float: + """ + 计算在游戏新21点规则下赢得概率 + + Args: + N (int): 可以尝试的最大数值 + K (int): 游戏开始时的初始值 + W (int): 累计和窗口大小 + + Returns: + float: 赢得游戏的概率 + """ + + if K == 0 or N >= K + W: + # 如果K为0或N大于等于K+W,直接返回1表示必赢 + return 1 + + dp = [1.0] + [0.0] * N # 初始化动态规划表 + Wsum, res = 1.0, 0.0 # 累积和与结果初始化 + for i in range(1, N + 1): + # 更新dp[i] dp[i] += Wsum / W - if i < K: Wsum += dp[i] - else: res += dp[i] - if i - W >= 0: Wsum -= dp[i - W] - return res \ No newline at end of file + if i < K: + # 如果i小于K,累积和Wsum加上当前概率dp[i] + Wsum += dp[i] + else: + # 否则结果res累加当前概率dp[i] + res += dp[i] + + if i - W >= 0: + # 当i-W大于等于0时,从累积和中减去dp[i-W]以维护窗口大小 + Wsum -= dp[i - W] + + return res diff --git a/solutions/python3/838.py b/solutions/python3/838.py index a1984a5..925cab2 100644 --- a/solutions/python3/838.py +++ b/solutions/python3/838.py @@ -1,21 +1,49 @@ + class Solution: def pushDominoes(self, dominoes): - res, l, r , pre_l, pre_r = "", {}, {}, None, None, + """ + 解决推多米诺骨牌问题,给定一个字符串表示初始状态的多米诺骨牌序列。 + 0. 定义结果字符串res和存储左右边界信息的字典l, r + 1. 遍历dominoes正向填充r字典记录右边界距离 + 2. 反向遍历dominoes填充l字典记录左边界距离 + 3. 根据规则确定结果字符串中的每个字符 + """ + res, l, r, pre_l, pre_r = "", {}, {}, None, None + + # 正向遍历填充r字典,记录每个点右侧最近的R的位置及距离 for i, s in enumerate(dominoes): - if s == "." and pre_r != None: r[i] = i - pre_r - elif s == "R": pre_r = i - elif s == "L": pre_r = None + if s == "." and pre_r is not None: + r[i] = i - pre_r + elif s == "R": + pre_r = i + elif s == "L": + pre_r = None + + # 反向遍历填充l字典,记录每个点左侧最近的L的位置及距离 for i in range(len(dominoes) - 1, -1, -1): - if dominoes[i] == "." and pre_l != None: l[i] = pre_l - i - elif dominoes[i] == "L": pre_l = i - elif dominoes[i] == "R": pre_l = None + if dominoes[i] == "." and pre_l is not None: + l[i] = pre_l - i + elif dominoes[i] == "L": + pre_l = i + elif dominoes[i] == "R": + pre_l = None + + # 根据规则确定结果字符串中的每个字符 for i, s in enumerate(dominoes): - if s == "L" or s == "R": res += s + if s == "L" or s == "R": + res += s elif i in l and i in r: - if l[i] < r[i]: res += "L" - elif r[i] < l[i]: res += "R" - else: res += s - elif i in l: res += "L" - elif i in r: res += "R" - else: res += s - return res \ No newline at end of file + if l[i] < r[i]: + res += "L" + elif r[i] < l[i]: + res += "R" + else: + res += s + elif i in l: + res += "L" + elif i in r: + res += "R" + else: + res += s + + return res diff --git a/solutions/python3/839.py b/solutions/python3/839.py index dad3efc..8f063d5 100644 --- a/solutions/python3/839.py +++ b/solutions/python3/839.py @@ -1,21 +1,40 @@ + class Solution: def numSimilarGroups(self, A): + """ + 初始化结果计数器、图结构和访问集合。 + + :param A: 字符串列表,表示需要判断相似组的数量的字符串集合 + """ + def explore(s): + """ + 深度优先搜索函数,用于标记当前节点及其所有可达且未被标记过的邻接节点为已访问。 + + :param s: 当前正在探索的字符串 + """ visited.add(s) for v in edges[s]: - if v not in visited: explore(v) + if v not in visited: + explore(v) + res, edges, visited = 0, {}, set() + + # 如果 A 的长度大于或等于 A 中最长字符串的两倍,进行特定规则的相似性检查 if len(A) >= 2 * len(A[0]): strs = set(A) for s in A: if s not in edges: edges[s] = set() for i in range(len(s) - 1): for j in range(i + 1, len(s)): - new = s[:i] + s[j] + s[i + 1:j] + s[i] + s[j + 1:] - if new in strs: - edges[s].add(new) - if new in edges: edges[new].add(s) - else: edges[new] = {s} + new_s = s[:i] + s[j] + s[i + 1:j] + s[i] + s[j + 1:] + if new_s in strs: + edges[s].add(new_s) + if new_s in edges: + edges[new_s].add(s) + else: + edges[new_s] = {s} + # 否则,进行常规的相似性检查 else: for s in A: if s not in edges: edges[s] = set() @@ -26,10 +45,15 @@ def explore(s): if c == s[i]: same += 1 if same == len(s) - 2: edges[s].add(t) - if t in edges: edges[t].add(s) - else: edges[t] = {s} + if t in edges: + edges[t].add(s) + else: + edges[t] = {s} + + # 对于未被访问过的字符串,进行深度优先搜索并增加结果计数器 for s in A: if s not in visited: res += 1 explore(s) - return res \ No newline at end of file + + return res diff --git a/solutions/python3/84.py b/solutions/python3/84.py index 0118e91..60674c9 100644 --- a/solutions/python3/84.py +++ b/solutions/python3/84.py @@ -1,13 +1,29 @@ + class Solution: def largestRectangleArea(self, heights): - heights.append(0) - stack = [-1] - ans = 0 + """ + 输入:heights -- List[int], 表示柱状图的高度列表 + 输出:int,表示能够容纳的最大矩形面积 + + 1. 在高度列表末尾添加一个0,确保栈处理完所有元素。 + 2. 使用一个单调递增的栈来追踪可能的矩形宽度。 + 3. 遍历每一个柱子高度: + - 如果当前柱子高度小于栈顶柱子的高度,则弹出栈顶元素并计算以该柱子为高的最大矩形面积; + - 更新答案变量ans,存储最大的矩形面积。 + 4. 将末尾添加的0移除,并返回最终的答案。 + """ + heights.append(0) # Append a zero to handle the stack properly + stack = [-1] # Initialize stack with an artificial index -1 + ans = 0 # Initialize maximum area + for i in range(len(heights)): while heights[i] < heights[stack[-1]]: - h = heights[stack.pop()] - w = i - stack[-1] - 1 - ans = max(ans, h * w) - stack.append(i) - heights.pop() - return ans \ No newline at end of file + h = heights[stack.pop()] # Pop and get the height of the popped element + w = i - stack[-1] - 1 # Calculate width, -1 to exclude current index + ans = max(ans, h * w) # Update maximum area if needed + + stack.append(i) # Push current index onto stack + + heights.pop() # Remove the artificial zero added at the end + + return ans # Return the maximum area found diff --git a/solutions/python3/840.py b/solutions/python3/840.py index 8ccdbfd..7175bc6 100644 --- a/solutions/python3/840.py +++ b/solutions/python3/840.py @@ -1,13 +1,29 @@ + class Solution: def numMagicSquaresInside(self, grid): """ :type grid: List[List[int]] :rtype: int + + 计算给定网格中包含的魔方数。 """ res = 0 - for i in range(len(grid)-2): - for j in range(len(grid)-2): - if sum(grid[i][j: j + 3]) == sum(grid[i + 1][j : j +3]) == sum(grid[i + 2][j:j + 3]) == sum(grid[k][j] for k in range(i, i + 3)) == sum(grid[k][j + 1] for k in range(i, i + 3)) == sum(grid[k][j + 2] for k in range(i, i + 3)) == (grid[i][j] + grid[i + 1][j + 1] + grid[i + 2][j + 2]) == (grid[i+2][j]+ grid[i + 1][j + 1] + grid[i][j + 2]): - if set(grid[i][j: j + 3] + grid[i + 1][j: j +3] + grid[i + 2][j:j + 3]) == {1,2,3,4,5,6,7,8,9}: res += 1 + + # 遍历可能的3x3子网格 + for i in range(len(grid) - 2): + for j in range(len(grid[0]) - 2): + # 检查行、列和对角线的和是否相等 + if (sum(grid[i][j:j+3]) == + sum(grid[i+1][j:j+3]) == + sum(grid[i+2][j:j+3]) == + sum(grid[k][j] for k in range(i, i + 3)) == + sum(grid[k][j+1] for k in range(i, i + 3)) == + sum(grid[k][j+2] for k in range(i, i + 3)) == + (grid[i][j] + grid[i+1][j+1] + grid[i+2][j+2]) == + (grid[i+2][j] + grid[i+1][j+1] + grid[i][j+2])): + + # 检查数字是否为1到9的唯一组合 + if set(grid[i][j:j+3] + grid[i+1][j:j+3] + grid[i+2][j:j+3]) == {1, 2, 3, 4, 5, 6, 7, 8, 9}: + res += 1 + return res - \ No newline at end of file diff --git a/solutions/python3/841.py b/solutions/python3/841.py index d843b63..6be280a 100644 --- a/solutions/python3/841.py +++ b/solutions/python3/841.py @@ -1,9 +1,17 @@ + class Solution: + # 判断是否可以访问所有房间 + def canVisitAllRooms(self, rooms): + # 初始化可访问集合和栈,起点为0 pool, stack = set(range(len(rooms))), [0] + while stack: + # 从当前栈顶元素移除,并检查其相邻节点 pool.discard(stack[-1]) for nex in rooms[stack.pop()]: if nex in pool: stack.append(nex) - return not pool \ No newline at end of file + + # 如果所有房间都被访问过,则返回True + return not pool diff --git a/solutions/python3/842.py b/solutions/python3/842.py index 953672c..e303d73 100644 --- a/solutions/python3/842.py +++ b/solutions/python3/842.py @@ -1,24 +1,31 @@ + class Solution: + # 初始化方法,用于生成可能的起始数字对 + def getStarter(self): + arr = [] + for i in range(1, len(self.S) - 1): + for j in range(i + 1, len(self.S)): + s1, s2 = self.S[:i], self.S[i:j] + if (s1[0] == "0" and len(s1) > 1) or (s2[0] == "0" and len(s2) > 1): + continue + arr.append((int(s1), int(s2), j)) + return arr + + # 深度优先搜索方法,用于寻找满足Fibonacci序列条件的数字序列 + def dfs(self, arr, i): + if i == len(self.S): + return arr + sm = arr[-2] + arr[-1] + l = len(str(sm)) + new = int(self.S[i:i + l]) + # 检查新加入的数是否符合Fibonacci序列条件,并递归调用dfs + return (new == sm and 0 <= sm < self.mx) and dfs(arr + [new], i + l) + + # 主方法,用于拆分字符串为满足Fibonacci序列的数字列表 def splitIntoFibonacci(self, S): - def getStarter(): - arr = [] - for i in range(1, len(S) - 1): - for j in range(i + 1, len(S)): - s1, s2 = S[:i], S[i:j] - if (s1[0] == "0" and len(s1) > 1) or (s2[0] == "0" and len(s2) > 1): - continue - arr.append((int(s1), int(s2), j)) - return arr - def dfs(arr, i): - if i == len(S): - return arr - sm = arr[-2] + arr[-1] - l = len(str(sm)) - new = int(S[i:i + l]) - return new == sm and 0 <= sm <= mx and dfs(arr + [new], i + l) - q, mx = getStarter(), 2 ** 31 - 1 + q, self.mx = self.getStarter(), 2 ** 31 - 1 for p1, p2, i in q: - seq = dfs([p1, p2], i) + seq = self.dfs([p1, p2], i) if seq: return seq - return [] \ No newline at end of file + return [] diff --git a/solutions/python3/843.py b/solutions/python3/843.py index 94d7a17..057df51 100644 --- a/solutions/python3/843.py +++ b/solutions/python3/843.py @@ -1,19 +1,18 @@ -# """ -# This is Master's API interface. -# You should not implement it, or speculate about its implementation -# """ -#class Master: -# def guess(self, word): -# """ -# :type word: str -# :rtype int -# """ + +import collections +import itertools class Solution: + # 寻找秘密单词的解决方案类 def findSecretWord(self, wordlist, master): + # 尝试次数初始化为0 n = 0 while n < 6: + # 统计两个词完全不匹配的次数 count = collections.Counter(w1 for w1, w2 in itertools.permutations(wordlist, 2) if sum(i == j for i, j in zip(w1, w2)) == 0) - guess = min(wordlist, key = lambda w: count[w]) + # 选择当前猜测单词,使其在统计中出现次数最少(即与其它单词不匹配的可能性最小) + guess = min(wordlist, key=lambda w: count[w]) + # 使用Master接口进行猜测 n = master.guess(guess) - wordlist = [w for w in wordlist if sum(i == j for i, j in zip(w, guess)) == n] \ No newline at end of file + # 更新wordlist为与猜测单词n个位置匹配的单词列表 + wordlist = [w for w in wordlist if sum(i == j for i, j in zip(w, guess)) == n] diff --git a/solutions/python3/844.py b/solutions/python3/844.py index 2996c66..d985a12 100644 --- a/solutions/python3/844.py +++ b/solutions/python3/844.py @@ -1,6 +1,10 @@ + class Solution: - def backspaceCompare(self, S, T): - def construct(s): + # 比较两个字符串在执行删除操作后是否相等 + + def backspaceCompare(self, S: str, T: str) -> bool: + # 辅助函数:构建新字符串,忽略删除标记 '#' + def construct(s: str) -> list[str]: new_s = [] for c in s: if c == "#" and len(new_s) > 0: @@ -8,5 +12,9 @@ def construct(s): elif c != "#": new_s.append(c) return new_s + + # 构造处理后的字符串 s, t = construct(S), construct(T) - return s == t \ No newline at end of file + + # 比较两个构建后的字符串是否相等 + return s == t diff --git a/solutions/python3/845.py b/solutions/python3/845.py index ba09f2f..6fc4b7c 100644 --- a/solutions/python3/845.py +++ b/solutions/python3/845.py @@ -1,9 +1,29 @@ + class Solution: - def longestMountain(self, A, res = 0): + def longestMountain(self, A: List[int], res: int = 0) -> int: + """ + 计算数组A中最长的山脉长度。 + 山脉定义为元素严格递增后严格递减的一段。 + + :param A: 输入整数列表 + :param res: 结果变量,初始值为0 + :return: 最长山脉的长度 + + 1. 遍历数组A,从第二个元素开始到倒数第二个结束。 + 2. 如果当前元素是递增起点(比前一个大且比后一个小): + - 找到递增起点左侧边界l + - 找到递减终点右侧边界r + - 更新结果res为最大值 + """ for i in range(1, len(A) - 1): - if A[i + 1] < A[i] > A[i - 1]: + if A[i] > A[i - 1] and A[i] > A[i + 1]: l = r = i - while l and A[l] > A[l - 1]: l -= 1 - while r + 1 < len(A) and A[r] > A[r + 1]: r += 1 - if r - l + 1 > res: res = r - l + 1 - return res \ No newline at end of file + # 向左找到递增起点 + while l and A[l] > A[l - 1]: + l -= 1 + # 向右找到递减终点 + while r + 1 < len(A) and A[r] > A[r + 1]: + r += 1 + if r - l + 1 > res: + res = r - l + 1 + return res diff --git a/solutions/python3/846.py b/solutions/python3/846.py index 9b58f8c..4d53dd6 100644 --- a/solutions/python3/846.py +++ b/solutions/python3/846.py @@ -1,11 +1,17 @@ + class Solution: - def isNStraightHand(self, hand, W): + # 判断给定的手牌是否能组成W张连续的牌 + def isNStraightHand(self, hand: list[int], W: int) -> bool: + # 对手牌进行排序,便于后续判断连续性 hand.sort() + while hand: try: + # 以第一个元素作为基数,尝试移除接下来W-1张连续的牌 base = hand[0] for i in range(W): - hand.remove(base+i) + hand.remove(base + i) except: return False - return True \ No newline at end of file + + return True diff --git a/solutions/python3/847.py b/solutions/python3/847.py index a5b0786..b5659de 100644 --- a/solutions/python3/847.py +++ b/solutions/python3/847.py @@ -1,10 +1,24 @@ + class Solution: def shortestPathLength(self, graph): - memo, final, q = set(), (1 << len(graph)) - 1, collections.deque([(i, 0, 1 << i) for i in range(len(graph))]) + """ + 初始化记忆集合、最终状态和队列。 + + :param graph: List[List[int]] - 图的邻接表表示 + """ + memo, final_state, q = set(), (1 << len(graph)) - 1, collections.deque([(i, 0, 1 << i) for i in range(len(graph))]) + while q: node, steps, state = q.popleft() - if state == final: return steps + + # 如果当前状态等于最终状态,返回步数 + if state == final_state: + return steps + + # 遍历当前节点的邻接节点 for v in graph[node]: - if (state | 1 << v, v) not in memo: - q.append((v, steps + 1, state | 1 << v)) - memo.add((state | 1 << v, v)) \ No newline at end of file + # 构建新的状态并检查是否已经访问过 + new_state = state | 1 << v + if (new_state, v) not in memo: + q.append((v, steps + 1, new_state)) + memo.add((new_state, v)) diff --git a/solutions/python3/848.py b/solutions/python3/848.py index cd2c036..5bd12c4 100644 --- a/solutions/python3/848.py +++ b/solutions/python3/848.py @@ -1,7 +1,16 @@ + class Solution: - def shiftingLetters(self, S, shifts): + # 定义一个类用于解决字母移动问题 + + def shiftingLetters(self, S: str, shifts: list[int]) -> str: + # 初始化累积偏移量sm和结果字符串res sm, res = sum(shift % 26 for shift in shifts) % 26, "" + + # 遍历每个字符及其对应的移动值 for i, s in enumerate(shifts): + # 计算当前字符的新位置,更新累积偏移量sm,并构建结果字符串res move, sm = ord(S[i]) + sm % 26, sm - s res += chr(move > 122 and move - 26 or move) - return res \ No newline at end of file + + # 返回最终处理后的字符串 + return res diff --git a/solutions/python3/849.py b/solutions/python3/849.py index 6edc548..2f83c65 100644 --- a/solutions/python3/849.py +++ b/solutions/python3/849.py @@ -1,11 +1,24 @@ + class Solution: + # 定义一个解决方案类,用于解决求座位最大最远距离的问题 + def maxDistToClosest(self, seats): - d = {} + d = {} # 用于存储每个空位到最近人的最大距离 res = l = left = r = right = 0 + + # 正向遍历座位列表,更新左侧连续空位数并记录最左端的位置 for i, s in enumerate(seats): - if not s and left: d[i] = l = l + 1 - elif s: l, left = 0, 1 + if not s and left: + d[i] = l = l + 1 + elif s: + l, left = 0, 1 + + # 反向遍历座位列表,更新右侧连续空位数并记录最右端的位置 for i in range(len(seats) - 1, -1, -1): - if not seats[i] and right and (i not in d or d[i] > r): d[i] = r = r + 1 - elif seats[i]: r, right = 0, 1 - return max(d.values()) \ No newline at end of file + if not seats[i] and right and (i not in d or d[i] > r): + d[i] = r = r + 1 + elif seats[i]: + r, right = 0, 1 + + # 返回所有记录的最大值,即为最远距离 + return max(d.values()) diff --git a/solutions/python3/85.py b/solutions/python3/85.py index 2fa80a8..962f66d 100644 --- a/solutions/python3/85.py +++ b/solutions/python3/85.py @@ -1,20 +1,33 @@ + class Solution: - def maximalRectangle(self, matrix): + # 定义一个计算矩阵最大矩形面积的方法 + def maximalRectangle(self, matrix: list[list[str]]) -> int: + # 初始化结果,行数和列数变量 res, m, n = 0, len(matrix), len(matrix and matrix[0]) + for i in range(m): for j in range(n): if matrix[i][j] != "0": + # 如果当前位置不是“0”,则更新其值为左边连续1的数量加一 if j > 0 and matrix[i][j - 1] != "0": - matrix[i][j] = matrix[i][j - 1] + 1 + matrix[i][j] = int(matrix[i][j - 1]) + 1 else: matrix[i][j] = 1 + + # 记录当前元素值,用于后续计算矩形高度 mn, sm, k = matrix[i][j], 0, i + 1 + while k > 0 and matrix[k - 1][j] != "0": if matrix[k - 1][j] < mn: - sm, mn = (i - k + 2) * matrix[k - 1][j], matrix[k - 1][j] + # 更新最小高度和面积 + sm, mn = (i - k + 2) * int(matrix[k - 1][j]), int(matrix[k - 1][j]) else: + # 累加当前行的矩形面积 sm += mn + if sm > res: + # 更新最大矩形面积 res = sm k -= 1 - return res \ No newline at end of file + + return res diff --git a/solutions/python3/850.py b/solutions/python3/850.py index 254a29c..2ccd6d1 100644 --- a/solutions/python3/850.py +++ b/solutions/python3/850.py @@ -1,18 +1,40 @@ + class Solution: def rectangleArea(self, rectangles): + # 获取所有x轴边界点并排序去重 xs = sorted(set([x for x1, y1, x2, y2 in rectangles for x in [x1, x2]] + [0])) + + # 构建x坐标到索引的映射 x_i = {v: i for i, v in enumerate(xs)} + + # 初始化计数数组,记录每个区间的状态变化 count = [0] * len(x_i) + + # 记录所有边界点事件 L = [] for x1, y1, x2, y2 in rectangles: - L.append([y1, x1, x2, 1]) - L.append([y2, x1, x2, -1]) + L.append([y1, x1, x2, 1]) # 左边界进入 + L.append([y2, x1, x2, -1]) # 右边界退出 + + # 按纵坐标排序事件列表,确保按顺序处理矩形的上下边界 L.sort() + + # 当前纵坐标和当前横坐标和面积 cur_y = cur_x_sum = area = 0 + + # 遍历所有事件点进行计算 for y, x1, x2, sig in L: + # 计算新增的面积并累加 area += (y - cur_y) * cur_x_sum + + # 更新当前纵坐标 cur_y = y + + # 根据矩形边界更新计数数组状态 for i in range(x_i[x1], x_i[x2]): count[i] += sig - cur_x_sum = sum(x2 - x1 if c else 0 for x1, x2, c in zip(xs, xs[1:], count)) - return area % (10 ** 9 + 7) \ No newline at end of file + + # 重新计算当前横坐标的总和,过滤掉消失的区间 + cur_x_sum = sum((x2 - x1) if c else 0 for x1, x2, c in zip(xs, xs[1:], count)) + + return area % (10 ** 9 + 7) diff --git a/solutions/python3/851.py b/solutions/python3/851.py index d5ce585..b19e449 100644 --- a/solutions/python3/851.py +++ b/solutions/python3/851.py @@ -1,14 +1,36 @@ + class Solution: - def loudAndRich(self, richer, quiet): + # 定义Solution类,用于解决富人和安静程度的问题 + + def loudAndRich(self, richer: List[List[int]], quiet: List[int]) -> List[int]: + # 初始化邻接表、记忆化字典和结果列表 edges, memo, res = collections.defaultdict(list), {}, [i for i in range(len(quiet))] - for r, p in richer: edges[p].append(r) + + # 构建有向图,将富人关系存储在edges中 + for r, p in richer: + edges[p].append(r) + + # 定义深度优先搜索函数explore def explore(i): - if i in memo: return memo[i] - cur_min = i + if i in memo: + return memo[i] + + cur_min = i # 当前节点最小安静值索引,初始化为自身 + + # 遍历当前节点的所有邻居节点 for v in edges[i]: + # 递归探索邻居节点 cur = explore(v) - if quiet[cur] < quiet[cur_min]: cur_min = cur + if quiet[cur] < quiet[cur_min]: + cur_min = cur + + # 将结果存储在memo和res中 res[i] = memo[i] = cur_min + return cur_min + + # 对每个节点执行深度优先搜索 for i in range(len(quiet)): explore(i) - return res \ No newline at end of file + + # 返回最终的结果列表 + return res diff --git a/solutions/python3/852.py b/solutions/python3/852.py index 31a939f..549753d 100644 --- a/solutions/python3/852.py +++ b/solutions/python3/852.py @@ -1,8 +1,13 @@ + class Solution: + # 寻找山脉数组中的峰值索引 + def peakIndexInMountainArray(self, A): """ - :type A: List[int] - :rtype: int + :type A: List[int] # 输入的整数列表A + :rtype: int # 返回峰值元素的索引 + + 思路:找到最大值对应的索引即为峰值索引 """ - mx = max(A) - return A.index(mx) \ No newline at end of file + mx = max(A) # 找到列表中的最大值 + return A.index(mx) # 返回最大值在列表中的索引 diff --git a/solutions/python3/853.py b/solutions/python3/853.py index 02c28f8..a51b7a4 100644 --- a/solutions/python3/853.py +++ b/solutions/python3/853.py @@ -1,10 +1,30 @@ + class Solution: - def carFleet(self, target, position, speed): - res, s = 0, {position[i]: speed[i] for i in range(len(position))} + # 定义解决方案类 + + def carFleet(self, target: int, position: list[int], speed: list[int]) -> int: + """ + 计算达到目标位置的车队数量 + + :param target: 目标位置 + :param position: 每辆车的起始位置列表 + :param speed: 每辆车的速度列表 + :return: 达到目标位置的车队数量 + """ + + res, s = 0, {pos: vel for pos, vel in zip(position, speed)} + # 初始化结果计数器 res 和速度字典 s + position.sort() + # 对起始位置进行排序 + while position: cur = position.pop() res += 1 + # 弹出当前车的位置,并将车队数量加一 + while position and (s[position[-1]] - s[cur]) * (target - cur) / s[cur] >= cur - position[-1]: position.pop() - return res \ No newline at end of file + # 如果后一辆车赶上前面的车,则弹出路劲位置列表 + + return res diff --git a/solutions/python3/854.py b/solutions/python3/854.py index 8ec2b23..acec21e 100644 --- a/solutions/python3/854.py +++ b/solutions/python3/854.py @@ -1,17 +1,31 @@ + class Solution: - def kSimilarity(self, A, B): + def kSimilarity(self, A: str, B: str) -> int: + # 初始化:B转换为列表形式,获取字符串长度n,初始化最小操作次数k为无穷大, + # 并创建一个栈,初始元素包含索引0、当前计数0和复制的A b, n, k, stack = [c for c in B], len(A), float("inf"), [(0, 0, [c for c in A])] + + # 当栈非空时循环 while stack: - i, cnt, s = stack.pop() + i, cnt, s = stack.pop() # 弹出栈顶元素,包含当前索引、操作计数和字符串列表副本 + + # 找到与B当前位置字符不同的第一个位置i while i < n and s[i] == b[i]: i += 1 + + # 如果找到全部匹配,则更新最小操作次数k if i == n: if cnt < k: k = cnt + else: + # 寻找可以交换的位置j,满足条件:s[j] == b[i]且s[j] != b[j] for j in range(i + 1, n): if s[j] == b[i] and s[j] != b[j]: - ls = s[:] - ls[i], ls[j] = ls[j], ls[i] + ls = s[:] # 复制字符串列表副本 + ls[i], ls[j] = ls[j], ls[i] # 进行交换操作 + + # 将新的索引、计数加1和更新后的列表压入栈中 stack.append((i + 1, cnt + 1, ls)) - return k \ No newline at end of file + + return k # 返回最小的操作次数k diff --git a/solutions/python3/855.py b/solutions/python3/855.py index 9e6844f..c92b118 100644 --- a/solutions/python3/855.py +++ b/solutions/python3/855.py @@ -1,27 +1,36 @@ + class ExamRoom: - def __init__(self, N): + # 初始化教室座位数量N,seated记录当前已占用的座位索引列表 + def __init__(self, N: int): self.seated, self.n = [], N - 1 - - def seat(self): + # 选择一个最远距离的位置就座 + def seat(self) -> int: if not self.seated: - self.seated += 0, + self.seated += [0], # 空列表添加元素需要逗号,表示单个元素的元组 return 0 - mx = ind = 0 + + mx, ind = 0, 0 # 最大距离和对应的索引位置初始化 + + # 遍历已占用座位,计算空位最大距离 for i in range(1, len(self.seated)): l, r = self.seated[i - 1], self.seated[i] if (r - l) // 2 > mx: - mx = (r - l) // 2 - ind = l + mx + mx, ind = (r - l) // 2, l + mx + + # 检查两端空位情况 if self.seated[-1] != self.n and self.n - self.seated[-1] > mx: mx, ind = self.n - self.seated[-1], self.n + if self.seated[0] >= mx: mx, ind = self.seated[0], 0 + + # 就座 self.seated.append(ind) self.seated.sort() return ind - - - def leave(self, p): + + # 离开座位,更新已占用的座位列表 + def leave(self, p: int): self.seated.remove(p) diff --git a/solutions/python3/856.py b/solutions/python3/856.py index 2943552..15f28bd 100644 --- a/solutions/python3/856.py +++ b/solutions/python3/856.py @@ -1,13 +1,23 @@ + class Solution: - def scoreOfParentheses(self, S): + # 定义一个求括号分数的方法 + def scoreOfParentheses(self, S: str) -> int: + # 初始化栈和结果变量 stack, res = [], 0 + for c in S: if c == "(": + # 当遇到左括号时,将其对应的右括号的分值设为0并入栈 stack.append(0) else: + # 遇到右括号时计算当前子表达式的分数 add = 2 * stack.pop() or 1 + if stack: + # 如果栈不为空,将计算的结果加在栈顶元素上 stack[-1] += add else: + # 如果栈为空,则将结果累加到res中 res += add - return res \ No newline at end of file + + return res diff --git a/solutions/python3/857.py b/solutions/python3/857.py index 0b8cd2d..c954e33 100644 --- a/solutions/python3/857.py +++ b/solutions/python3/857.py @@ -1,11 +1,27 @@ + class Solution: + # 初始化解决方案类 + def mincostToHireWorkers(self, quality, wage, K): + """ + :param quality: 工人的质量列表,英文:List of workers' qualities + :param wage: 工人的工资列表,英文:List of workers' wages + :param K: 招聘的工人数量限制,英文:Limit on the number of hired workers + :return: 最小成本,英文:Minimum cost to hire workers under given constraints + """ + + # 组合每个工人的质量与工资比值,并按此排序(升序) workers, res, heap, sumq = sorted((w / q, q, w) for q, w in zip(quality, wage)), float("inf"), [], 0 + + # 遍历排序后的工人列表 for ratio, q, w in workers: - heapq.heappush(heap, -q) - sumq += q - if len(heap) > K: - sumq += heapq.heappop(heap) - if len(heap) == K: - res = min(res, ratio * sumq) - return res \ No newline at end of file + heapq.heappush(heap, -q) # 将当前工人的质量加入堆中(取负以使用最小堆实现最大值) + sumq += q # 更新总质量 + + if len(heap) > K: # 如果堆中的工人数量超过K + sumq += heapq.heappop(heap) # 弹出一个质量最大的工人,减少总质量 + + if len(heap) == K: # 当堆中工人的数量等于K时 + res = min(res, ratio * sumq) # 更新最小成本 + + return res diff --git a/solutions/python3/858.py b/solutions/python3/858.py index e25d8e7..bac50d1 100644 --- a/solutions/python3/858.py +++ b/solutions/python3/858.py @@ -1,16 +1,27 @@ + class Solution: - def mirrorReflection(self, p, q): - side, up, h = 2, 1, 0 + def mirrorReflection(self, p: int, q: int) -> int: + """ + 解决问题:模拟光束在镜子上的反射路径,返回光束最终所在的位置。 + + 参数: + p (int): 镜子的垂直边长 + q (int): 光源与垂直边的距离 + + 返回值: + int: 光束最终所在的角编号(0, 1, 或 2) + """ + side, up, h = 2, 1, 0 # 初始化:side表示水平方向的位置,up表示垂直方向的移动方向,h表示当前高度 while True: - h += q * up - side = (side + 1) % 2 + h += q * up # 更新光束的高度 + side = (side + 1) % 2 # 水平方向翻转 if side == 0: - side += 2 + side += 2 # 如果在最左面,恢复为初始状态 if h < 0: - h *= -1 + h *= -1 # 翻转光束垂直方向 up *= -1 elif h > p: - h = p - (h - p) + h = p - (h - p) # 碰到上边,调整高度并翻转方向 up *= -1 - if h % p == 0: - return h and side or 0 \ No newline at end of file + if h % p == 0: # 判断是否到达底部或顶部 + return h and side or 0 # 返回光束所在的位置 diff --git a/solutions/python3/859.py b/solutions/python3/859.py index 98e3d96..52aaab4 100644 --- a/solutions/python3/859.py +++ b/solutions/python3/859.py @@ -1,6 +1,19 @@ + class Solution: - def buddyStrings(self, A, B): + def buddyStrings(self, A: str, B: str) -> bool: + """ + 判断字符串A和B是否可以通过交换A中的两个字符得到B。 + + :param A: 第一个字符串 + :param B: 第二个字符串 + :return: 如果可以通过交换A中的两个字符得到B则返回True,否则返回False + """ if len(A) != len(B): - return False - dif, dup = [[s1, B[i]] for i, s1 in enumerate(A) if s1 != B[i]], len(A) != len(set(A)) - return len(dif) == 2 and dif[0] == dif[1][::-1] or (not dif and dup) \ No newline at end of file + return False # 如果长度不等,则不能通过交换字符使两者相等 + + # 找出A和B中不同的字符对,并检查A中是否有重复字符 + diff_pairs = [(a, b) for i, (a, b) in enumerate(zip(A, B)) if a != b] + has_duplicate = len(set(A)) < len(A) + + # 只能通过交换两个不同位置的字符得到B,且这两位字符必须互换才能使A变成B + return len(diff_pairs) == 2 and diff_pairs[0] == diff_pairs[1][::-1] or (not diff_pairs and has_duplicate) diff --git a/solutions/python3/86.py b/solutions/python3/86.py index 5595649..361f651 100644 --- a/solutions/python3/86.py +++ b/solutions/python3/86.py @@ -1,12 +1,20 @@ + class Solution: - def partition(self, head, x): + # 分类链表 - 将所有小于x的节点放在大于等于x的节点之前 + def partition(self, head: ListNode, x: int) -> ListNode: + # 创建两个虚拟头节点,用于分别指向小于x和大于等于x的节点列表 lessHead = less = ListNode(-1) greatHead = great = ListNode(-1) + while head: + # 将当前节点根据值是否小于x插入到对应的链表中 if head.val < x: less.next = less = head else: great.next = great = head head = head.next + + # 连接两个链表 less.next, great.next = greatHead.next, None - return lessHead.next \ No newline at end of file + + return lessHead.next # 返回新的头节点 diff --git a/solutions/python3/860.py b/solutions/python3/860.py index 4b67e5b..635def2 100644 --- a/solutions/python3/860.py +++ b/solutions/python3/860.py @@ -1,17 +1,26 @@ + class Solution: def lemonadeChange(self, bills): + # 定义5元和10元硬币的数量 five = ten = 0 + for num in bills: + # 如果收到的是5元 if num == 5: five += 1 + # 如果收到的是10元且有5元可用 elif num == 10 and five: ten += 1 five -= 1 + # 如果收到的是20元且有5元和10元都可用 elif num == 20 and five and ten: five -= 1 ten -= 1 + # 如果收到的20元且仅有足够的5元 elif num == 20 and five >= 3: five -= 3 else: return False - return True \ No newline at end of file + + # 如果所有情况都满足,则返回True + return True diff --git a/solutions/python3/861.py b/solutions/python3/861.py index 8c407a1..740357d 100644 --- a/solutions/python3/861.py +++ b/solutions/python3/861.py @@ -1,10 +1,25 @@ + class Solution: - def matrixScore(self, A): + def matrixScore(self, A: List[List[int]]) -> int: + """ + 类Solution包含一个方法matrixScore,用于计算矩阵A的分数。 + + 参数: + A (List[List[int]]): 输入矩阵 + + 返回值: + int: 矩阵A的最大可能分数 + """ + # 根据第一列调整行以优化初始分数 for i, row in enumerate(A): if not row[0]: A[i] = [1 - num for num in row] + m, n, sm = len(A), len(A and A[0]), 0 + + # 计算每一列的最优值并累加到总分 for c in range(n): cnt = sum(A[r][c] for r in range(m)) sm += max(cnt, m - cnt) * 2 ** (n - c - 1) - return sm \ No newline at end of file + + return sm diff --git a/solutions/python3/862.py b/solutions/python3/862.py index 761c9c6..1df3c18 100644 --- a/solutions/python3/862.py +++ b/solutions/python3/862.py @@ -1,13 +1,27 @@ + class Solution: - def shortestSubarray(self, A, K): + def shortestSubarray(self, A: List[int], K: int) -> int: + # 初始化堆、最小长度和当前累积和 heap, l, sm = [], float("inf"), 0 + + # 将初始值(0, -1)加入堆中,便于后续处理边界情况 heapq.heappush(heap, (0, -1)) + + # 遍历数组A中的每个元素 for i, num in enumerate(A): - sm += num + sm += num # 累加当前元素至累积和 + + # 计算目标差值 dif = sm - K + + # 检查堆顶元素是否满足条件,更新最小长度l while heap and (heap[0][0] <= dif or i - heap[0][1] >= l): preSum, preIndex = heapq.heappop(heap) if i - preIndex < l: l = i - preIndex + + # 将当前累积和及其索引加入堆中 heapq.heappush(heap, (sm, i)) - return l < float("inf") and l or -1 \ No newline at end of file + + # 返回最小长度,若未找到满足条件的子数组,则返回-1 + return l if l != float("inf") else -1 diff --git a/solutions/python3/863.py b/solutions/python3/863.py index d406283..b48b253 100644 --- a/solutions/python3/863.py +++ b/solutions/python3/863.py @@ -1,24 +1,35 @@ + class Solution: + # 初始化邻接表,结果集和访问状态标记 def distanceK(self, root, target, K): adj, res, visited = collections.defaultdict(list), [], collections.defaultdict(int) + + # 构建邻接表 def dfs(node): - if node.left: - adj[node].append(node.left) - adj[node.left].append(node) - dfs(node.left) - if node.right: - adj[node].append(node.right) - adj[node.right].append(node) - dfs(node.right) + if node.left: # 如果当前节点有左子节点 + adj[node].append(node.left) # 将节点与左子节点相连 + adj[node.left].append(node) # 并将左子节点与当前节点相连 + dfs(node.left) # 继续递归遍历左子树 + + if node.right: # 如果当前节点有右子节点 + adj[node].append(node.right) # 将节点与右子节点相连 + adj[node.right].append(node) # 并将右子节点与当前节点相连 + dfs(node.right) # 继续递归遍历右子树 + dfs(root) + + # 深度优先搜索,查找距离目标节点K步的节点 def dfs2(node, d): - if d < K: - visited[node] = 1 - for v in adj[node]: - if not visited[v]: - dfs2(v, d + 1) - visited[node] = 0 + if d < K: # 如果当前深度小于K + visited[node] = 1 # 标记该节点为已访问 + for v in adj[node]: # 遍历所有邻接节点 + if not visited[v]: # 如果该邻接节点未被访问过 + dfs2(v, d + 1) # 继续递归查找 + + visited[node] = 0 # 查找结束后,标记该节点为未访问(已出栈) + else: - res.append(node.val) - dfs2(target, 0) - return res \ No newline at end of file + res.append(node.val) # 当前深度等于K时,将当前节点值加入结果集 + + dfs2(target, 0) # 从目标节点开始查找 + return res diff --git a/solutions/python3/864.py b/solutions/python3/864.py index b7bcd6f..ed1cc4f 100644 --- a/solutions/python3/864.py +++ b/solutions/python3/864.py @@ -1,21 +1,30 @@ + class Solution: + # 初始化类,定义寻找所有钥匙的最短路径问题 def shortestPathAllKeys(self, grid): final, m, n, si, sj = 0, len(grid), len(grid[0]), 0, 0 + # 遍历网格,计算最终需要收集的所有钥匙的状态,并找到起始点的位置 for i in range(m): for j in range(n): if grid[i][j] in "abcdef": final |= 1 << ord(grid[i][j]) - ord("a") elif grid[i][j] == "@": si, sj = i, j + q, memo = [(0, si, sj, 0)], set() + # 使用优先队列进行广度优先搜索,同时记录已访问的状态 while q: moves, i, j, state = heapq.heappop(q) if state == final: return moves for x, y in ((i - 1, j), (i + 1, j), (i, j - 1), (i, j + 1)): + # 检查下一个位置是否在网格范围内且不是墙壁 if 0 <= x < m and 0 <= y < n and grid[x][y] != "#": - if grid[x][y].isupper() and not state & 1 << (ord(grid[x][y].lower()) - ord("a")): continue + # 如果遇到大写字母钥匙,检查对应的小写状态是否已收集 + if grid[x][y].isupper() and not state & 1 << (ord(grid[x][y].lower()) - ord("a")): + continue + # 更新状态:如果当前位置是小写字母钥匙,则更新state状态;否则保持不变 newState = ord(grid[x][y]) >= ord("a") and state | 1 << (ord(grid[x][y]) - ord("a")) or state if (newState, x, y) not in memo: memo.add((newState, x, y)) heapq.heappush(q, (moves + 1, x, y, newState)) - return -1 \ No newline at end of file + return -1 diff --git a/solutions/python3/865.py b/solutions/python3/865.py index 3d5e86a..92612be 100644 --- a/solutions/python3/865.py +++ b/solutions/python3/865.py @@ -1,33 +1,55 @@ + # Definition for a binary tree node. -# class TreeNode: -# def __init__(self, x): -# self.val = x -# self.left = None -# self.right = None +class TreeNode: + def __init__(self, x): + self.val = x + self.left = None + self.right = None class Solution: + """ + 定义一个解决方案类,用于找到二叉树中最深叶子节点的所有公共父节点。 + """ + def subtreeWithAllDeepest(self, root: TreeNode) -> TreeNode: + # 初始化最大深度和结果集 self.l = 0 self.nodes = set() - self.res = 0 + self.res = None + + """ + 使用深度优先搜索(DFS)遍历二叉树,记录最深叶子节点的值及其最大深度。 + """ + def dfs(node, l): if node: + # 如果当前深度大于已知最大深度,则更新最大深度和结果集 if l > self.l: self.nodes = {node.val} self.l = l elif l == self.l: self.nodes.add(node.val) + # 递归遍历左子树和右子树,增加当前节点的层级深度 dfs(node.left, l + 1) dfs(node.right, l + 1) + + """ + 第二次DFS用于确定包含最深叶子节点所有公共父节点的子树。 + """ + def dfs2(node): if not node: return set() + # 获取左子树和右子树的结果集 l = dfs2(node.left) r = dfs2(node.right) + # 将当前节点值加入结果集中 total = l | r | {node.val} + # 检查当前节点是否为最深叶子节点的公共父节点 if total & self.nodes == self.nodes: self.res = node return set() return total - dfs(root, 0) - dfs2(root) - return self.res \ No newline at end of file + + dfs(root, 0) # 第一次DFS遍历树,确定最深叶子节点值及其最大深度 + dfs2(root) # 第二次DFS找出包含所有最深叶子节点的公共父节点子树 + return self.res # 返回结果 diff --git a/solutions/python3/866.py b/solutions/python3/866.py index 1c23aec..cfea739 100644 --- a/solutions/python3/866.py +++ b/solutions/python3/866.py @@ -1,11 +1,19 @@ + class Solution: - def primePalindrome(self, N): - def isPrime(x): - if x < 2 or x % 2 == 0: return x == 2 - for i in range(3, int(x**0.5) + 1, 2): - if x % i == 0: return False - return True - if 8 <= N <= 11: return 11 + # 判断一个数是否为质数 + def isPrime(self, x: int) -> bool: + if x < 2 or x % 2 == 0: + return x == 2 + for i in range(3, int(x**0.5) + 1, 2): + if x % i == 0: + return False + return True + + # 寻找从N开始的最小回文质数 + def primePalindrome(self, N: int) -> int: + if 8 <= N <= 11: + return 11 for x in range(10 ** (len(str(N)) // 2), 10**5): y = int(str(x) + str(x)[-2::-1]) - if y >= N and isPrime(y): return y \ No newline at end of file + if y >= N and self.isPrime(y): + return y diff --git a/solutions/python3/867.py b/solutions/python3/867.py index 421b293..c71130f 100644 --- a/solutions/python3/867.py +++ b/solutions/python3/867.py @@ -1,3 +1,8 @@ + class Solution: + # 定义一个方法transpose,传入参数A def transpose(self, A): - return [[A[i][j] for i in range(len(A))] for j in range(len(A[0]))] \ No newline at end of file + # 使用列表推导式实现矩阵转置 + # 中文注释:使用列表推导式进行矩阵转置操作。遍历外层j范围为A[0]的长度(列数),内层i范围为A的长度(行数)。 + # 英文注释: Use list comprehension to transpose the matrix. Outer loop j ranges over the length of A[0] (number of columns), inner loop i ranges over the length of A (number of rows). + return [[A[i][j] for i in range(len(A))] for j in range(len(A[0]))] diff --git a/solutions/python3/868.py b/solutions/python3/868.py index 7dfd611..9878b96 100644 --- a/solutions/python3/868.py +++ b/solutions/python3/868.py @@ -1,8 +1,20 @@ + class Solution: + # Python类定义 + def binaryGap(self, N): + """ + :param N: int,输入的整数 + :return: int,二进制表示中最大连续0之间的1的距离 + """ pre = dist = 0 for i, c in enumerate(bin(N)[2:]): + # 遍历N的二进制表示(去掉前缀'0b'),计算每个字符的位置索引i和值c if c == "1": + # 如果当前字符是"1" dist = max(dist, i - pre) + # 计算上一个"1"与当前"1"之间的距离,更新最大距离dist pre = i - return dist \ No newline at end of file + # 更新上一个"1"的位置为当前位置i + return dist + # 返回计算得到的最大距离 diff --git a/solutions/python3/869.py b/solutions/python3/869.py index 675dfcb..a5ab769 100644 --- a/solutions/python3/869.py +++ b/solutions/python3/869.py @@ -1,4 +1,18 @@ + class Solution: - def reorderedPowerOf2(self, N): + """ + 中文注释:该类包含一个方法用于判断给定整数N是否可以通过重排其数字形成2的幂。 + 英文注释: This class contains a method to determine if the given integer N can be rearranged to form a power of 2. + """ + + def reorderedPowerOf2(self, N: int) -> bool: + """ + 中文注释:通过计算N和2的幂次方的数字计数是否相同来判断。 + 英文注释: Determine if the digit count of N and any power of 2 is the same. + + :param N: 给定整数 + :return: 如果可以通过重排其数字形成2的幂则返回True,否则返回False + """ cnt = collections.Counter(str(N)) - return any(cnt == collections.Counter(str(1 << c)) for c in range(32)) \ No newline at end of file + # 检查N的数字计数是否与2^c的数字计数相同,其中0<=c<32(因为2^31已经是32位整数) + return any(cnt == collections.Counter(str(1 << c)) for c in range(32)) diff --git a/solutions/python3/87.py b/solutions/python3/87.py index b64a872..812f9fc 100644 --- a/solutions/python3/87.py +++ b/solutions/python3/87.py @@ -1,13 +1,24 @@ + class Solution: - def isScramble(self, s1, s2): + # 判断字符串s1和s2是否为搅乱字符串(Scramble String) + + def isScramble(self, s1: str, s2: str) -> bool: n, m = len(s1), len(s2) + # 如果长度不等或排序后不同,则不是搅乱字符串 if n != m or sorted(s1) != sorted(s2): return False + + # 当长度小于4或两个字符串相同时,直接返回True if n < 4 or s1 == s2: return True + f = self.isScramble + # 尝试分割s1和s2进行递归判断 for i in range(1, n): - if f(s1[:i], s2[:i]) and f(s1[i:], s2[i:]) or \u005C - f(s1[:i], s2[-i:]) and f(s1[i:], s2[:-i]): + # 检查是否可以通过重新排列部分子字符串来构成另一个字符串 + if (f(s1[:i], s2[:i]) and f(s1[i:], s2[i:]) or + f(s1[:i], s2[-i:]) and f(s1[i:], s2[:-i])): return True - return False \ No newline at end of file + + # 如果所有分割方式都不满足条件,则返回False + return False diff --git a/solutions/python3/870.py b/solutions/python3/870.py index 45b42f1..c467803 100644 --- a/solutions/python3/870.py +++ b/solutions/python3/870.py @@ -1,16 +1,40 @@ + class Solution: + # 定义一个类来解决这个问题 + def advantageCount(self, A: List[int], B: List[int]) -> List[int]: - A.sort(reverse = True) + """ + 返回一个列表,使得其每个元素都比B中的对应元素大。 + 如果不能满足,则尽可能将A中剩下的数填入结果。 + + :param A: 需要排序并选择的整数列表 + :type A: List[int] + :param B: 比较基准的整数列表 + :type B: List[int] + :return: 一个满足条件的结果列表 + :rtype: List[int] + """ + + # 将A降序排序,以便后续选取较大值 + A.sort(reverse=True) + + # 初始化未分配元素和结果列表 non = [] res = [-1] * len(A) + + # 按B中的值及其索引进行排序,并迭代处理 for b, i in sorted([(b, i) for i, b in enumerate(B)]): while A and A[-1] <= b: + # 如果当前A的最大元素小于等于B的当前元素,将其移至未分配列表 non.append(A.pop()) - if A: - res[i] = A.pop() + if A: # 当A中有剩余元素时 + res[i] = A.pop() # 使用A中的最大值填充结果 else: - break + break # A为空时跳出循环 + + # 处理未被分配的元素,尽量填入结果中 for i in range(len(res)): if res[i] == -1: res[i] = non.pop() - return res \ No newline at end of file + + return res # 返回最终的结果列表 diff --git a/solutions/python3/871.py b/solutions/python3/871.py index 3ecfb33..f32b28e 100644 --- a/solutions/python3/871.py +++ b/solutions/python3/871.py @@ -1,18 +1,34 @@ + class Solution: - def minRefuelStops(self, target, startFuel, stations): - q, n, memo = [(0, -startFuel, 0, 0)], len(stations), set() + """ + 定义一个解决方案类,包含minRefuelStops方法用于计算加油次数。 + """ + + def minRefuelStops(self, target: int, startFuel: int, stations) -> int: + # 使用优先队列存储状态 (加满油的操作数, 当前油量的负值, 当前位置, 操作索引) + q = [(0, -startFuel, 0, 0)] + n = len(stations) + memo = set() + while q: + # 弹出优先队列顶部的状态 refill, fuel, pos, index = heapq.heappop(q) fuel *= -1 - if index == n: - if fuel - (target - pos) >= 0: - return refill + + # 如果已遍历所有加油站且有足够的油量到达目标,则返回操作数 + if index == n and fuel - (target - pos) >= 0: + return refill + else: + # 当前位置和加油量 sPos, add = stations[index] + + # 检查当前状态是否已经处理过,以及是否有足够的油量通过下一个站点 if (index, refill) not in memo and fuel - (sPos - pos) >= 0: memo.add((index, refill)) - f1 = (fuel - (sPos - pos) + add) * -1 - f2 = (fuel - (sPos - pos)) * -1 - heapq.heappush(q, (refill + 1, f1, sPos, index + 1)) - heapq.heappush(q, (refill, f2, sPos, index + 1)) - return -1 \ No newline at end of file + # 根据选择加油或不加油的情况入队 + heapq.heappush(q, (refill + 1, (fuel - (sPos - pos) + add) * -1, sPos, index + 1)) + heapq.heappush(q, (refill, (fuel - (sPos - pos)) * -1, sPos, index + 1)) + + # 如果没有可行解,返回-1 + return -1 diff --git a/solutions/python3/872.py b/solutions/python3/872.py index 49b095b..977eb92 100644 --- a/solutions/python3/872.py +++ b/solutions/python3/872.py @@ -1,9 +1,20 @@ + class Solution: def leafSimilar(self, root1, root2): + # 中文注释: 定义一个深度优先搜索辅助函数,用于遍历树并收集叶子节点值 + # English comment: Define a depth-first search helper function to traverse the tree and collect leaf node values def dfs(node, arr): if node: - if not node.left and not node.right: arr += [node.val] - dfs(node.left, arr) - dfs(node.right, arr) - return arr - return dfs(root1, []) == dfs(root2, []) \ No newline at end of file + if not node.left and not node.right: # 中文注释: 判断当前节点是否为叶子节点 + # English comment: Check if the current node is a leaf node + arr += [node.val] # 中文注释: 如果是叶子节点,将值加入数组 + # English comment: If it's a leaf node, append its value to the array + dfs(node.left, arr) # 中文注释: 递归遍历左子树 + # English comment: Recursively traverse the left subtree + dfs(node.right, arr) # 中文注释: 递归遍历右子树 + # English comment: Recursively traverse the right subtree + return arr + + # 中文注释: 比较两棵树的叶子节点序列是否相同 + # English comment: Compare if the leaf sequences of two trees are the same + return dfs(root1, []) == dfs(root2, []) diff --git a/solutions/python3/873.py b/solutions/python3/873.py index 24166fc..86245c9 100644 --- a/solutions/python3/873.py +++ b/solutions/python3/873.py @@ -1,15 +1,30 @@ + class Solution: - def lenLongestFibSubseq(self, A): - n, pair, res, back = len(A), {}, 0, set() + def lenLongestFibSubseq(self, A: List[int]) -> int: + # 初始化变量:数组长度,哈希对存储,结果值初始化为0,一个集合用于快速查找元素是否存在 + n = len(A) + pair = {} + res = 0 + back = set() + for i in range(n): + # 将当前数字加入集合中 back.add(A[i]) j = i + 1 mx = 2 * A[i] + while j < n and A[j] < mx: + # 检查前一个元素和当前元素组成的斐波那契数对是否在哈希表中 if (A[j] - A[i], A[i]) in pair: + # 如果存在,则更新这对的值为原来的值加1 pair[(A[i], A[j])] = pair[(A[j] - A[i], A[i])] + 1 else: + # 如果不存在,但当前两个元素之差在集合中,初始化长度为3;否则初始为2 pair[(A[i], A[j])] = A[j] - A[i] in back and 3 or 2 + + # 更新结果值为当前最大长度 res = max(res, pair[(A[i], A[j])]) j += 1 - return res > 2 and res or 0 \ No newline at end of file + + # 返回结果,如果最长斐波那契子序列长度大于2,则返回该长度;否则返回0 + return res > 2 and res or 0 diff --git a/solutions/python3/874.py b/solutions/python3/874.py index 4e82349..2567d94 100644 --- a/solutions/python3/874.py +++ b/solutions/python3/874.py @@ -1,10 +1,26 @@ + class Solution: - def robotSim(self, commands, obstacles): - i = j = mx = 0 - d, move, obstacles = 3, [(-1, 0), (0, -1), (1, 0), (0, 1)], set(map(tuple, obstacles)) + def robotSim(self, commands: list[int], obstacles: list[tuple[int]]) -> int: + """ + 解决问题:给定一系列命令和障碍物列表,计算机器人在执行所有命令后可能达到的最大距离的平方。 + + 参数: + - commands: 一个整数列表,表示机器人的移动指令。正数为前进步数,-2 表示左转,-1 表示右转。 + - obstacles: 一个二维整数列表,表示障碍物的位置。 + + 返回值:机器人执行所有命令后可能达到的最大距离的平方。 + """ + i, j, mx = 0, 0, 0 + # 方向定义:向下、左、向上、右;d 表示当前方向 + d, move = 3, [(-1, 0), (0, -1), (1, 0), (0, 1)] + # 将障碍物列表转换为集合以提高查找效率 + obstacles = set(map(tuple, obstacles)) + for command in commands: - if command == -2: d = (d + 1) % 4 - elif command == -1: d = (d - 1) % 4 + if command == -2: # 右转 + d = (d + 1) % 4 + elif command == -1: # 左转 + d = (d - 1) % 4 else: x, y = move[d] while command and (i + x, j + y) not in obstacles: @@ -12,4 +28,4 @@ def robotSim(self, commands, obstacles): j += y command -= 1 mx = max(mx, i ** 2 + j ** 2) - return mx \ No newline at end of file + return mx diff --git a/solutions/python3/875.py b/solutions/python3/875.py index 10dc7ab..7d95eb9 100644 --- a/solutions/python3/875.py +++ b/solutions/python3/875.py @@ -1,14 +1,32 @@ + class Solution: + # 定义一个类来解决求解最低吃香蕉速度的问题 + def minEatingSpeed(self, piles, H): + # 对香蕉堆进行排序,便于后续二分查找 piles.sort() + + # 初始化左右指针 l, r = 1, max(piles) + + # 使用二分查找来确定最小的吃香蕉速度 while l <= r: mid = (l + r) // 2 + + # 计算当前速度下吃完所有香蕉需要的时间 h = sum(math.ceil(p / mid) for p in piles) + + # 如果所需时间超过H,则降低速度(增大左边界) if h > H: l = mid + 1 + + # 如果所需时间少于H,则提高速度(减小右边界) elif h < H: r = mid - 1 + + # 找到恰好等于H的速度,直接返回 else: return mid - return l \ No newline at end of file + + # 最终结果为l + return l diff --git a/solutions/python3/876.py b/solutions/python3/876.py index 35e53bc..3ae2133 100644 --- a/solutions/python3/876.py +++ b/solutions/python3/876.py @@ -1,9 +1,18 @@ + class Solution: - def middleNode(self, head): + # 定义一个方法middleNode,用于查找链表的中间节点 + + def middleNode(self, head: ListNode) -> ListNode: + # 初始化根节点为head,并设置计数器n为0 root, n = head, 0 + + # 遍历链表统计节点数量 while head: head = head.next n += 1 + + # 移动root到链表中间位置 for _ in range(n // 2): root = root.next - return root \ No newline at end of file + + return root # 返回中间节点 diff --git a/solutions/python3/877.py b/solutions/python3/877.py index 0e61e3d..b3e2374 100644 --- a/solutions/python3/877.py +++ b/solutions/python3/877.py @@ -1,2 +1,9 @@ + class Solution: - def stoneGame(self, piles): return True \ No newline at end of file + # 判断Alice能否在石头游戏中获胜 - 英文注释 + # Judge whether Alice can win the game of stones - 中文注释 + + def stoneGame(self, piles): + # 由于总和是偶数,Alice总是可以通过某些策略获胜 - 英文注释 + # As the total sum is even, Alice can always win with certain strategies - 中文注释 + return True diff --git a/solutions/python3/878.py b/solutions/python3/878.py index 0d7cd16..d443388 100644 --- a/solutions/python3/878.py +++ b/solutions/python3/878.py @@ -1,19 +1,34 @@ + class Solution: - - def gcd(self, a, b): + + def gcd(self, a: int, b: int) -> int: + """ + 计算两个数的最大公约数 + Calculate the greatest common divisor of two numbers. + """ while b: a, b = b, a % b return a - - def count(self, num, A, B, C): + + def count(self, num: int, A: int, B: int, C: int) -> int: + """ + 计算num中包含A和B的倍数的数量,减去C的倍数的数量。 + Calculate the number of multiples of A and B up to num, subtracting the multiples of C. + """ return num // A + num // B - num // C - - def nthMagicalNumber(self, N, A, B): - l, r, C = 2, 2 ** 63 - 1, A * B // self.gcd(A, B) + + def nthMagicalNumber(self, N: int, A: int, B: int) -> int: + """ + 寻找第N个既是A的倍数又是B的倍数的数。 + Find the Nth positive number that is a multiple of both A and B. + """ + l, r, C = 2, 2 ** 63 - 1, A * B // self.gcd(A, B) + while l < r: mid = (l + r) // 2 if self.count(mid, A, B, C) < N: l = mid + 1 else: r = mid - return l % (10 ** 9 + 7) \ No newline at end of file + + return l % (10 ** 9 + 7) diff --git a/solutions/python3/879.py b/solutions/python3/879.py index aa53d7a..c3720c2 100644 --- a/solutions/python3/879.py +++ b/solutions/python3/879.py @@ -1,9 +1,32 @@ + class Solution: def profitableSchemes(self, G: int, P: int, group: List[int], profit: List[int]) -> int: - dp = [[0] * (G + 1) for i in range(P + 1)] + """ + 计算在给定限制下,可获利的方案数量。 + + 参数: + G (int): 最大团队人数限制 + P (int): 利润目标 + group (List[int]): 每个团队的人数 + profit (List[int]): 每个团队的预期利润 + + 返回值: + int: 在给定限制下,可获利的方案数量 + """ + + # 动态规划表初始化 + dp = [[0] * (G + 1) for _ in range(P + 1)] + # 起始状态:无团队时利润为0且人数为0的情况只有一种方案 dp[0][0] = 1 + + # 遍历每个团队和对应的预期利润及人数 for p, g in zip(profit, group): + # 从利润目标倒序遍历,确保已计算过的状态可用 for i in range(P, -1, -1): + # 从最大团队人数减去当前团队的人数开始反向遍历,保证数据正确更新 for j in range(G - g, -1, -1): + # 更新dp表中的状态值 dp[min(i + p, P)][j + g] += dp[i][j] - return sum(dp[P]) % (10**9 + 7) \ No newline at end of file + + # 返回满足条件的所有方案总数模数结果 + return sum(dp[P]) % (10**9 + 7) diff --git a/solutions/python3/88.py b/solutions/python3/88.py index 4d4ac11..cd26ec4 100644 --- a/solutions/python3/88.py +++ b/solutions/python3/88.py @@ -1,20 +1,22 @@ + class Solution: - def merge(self, nums1, m, nums2, n): + def merge(self, nums1: list[int], m: int, nums2: list[int], n: int) -> None: """ - :type nums1: List[int] - :type m: int - :type nums2: List[int] - :type n: int - :rtype: void Do not return anything, modify nums1 in-place instead. + :param nums1: 第一个数组,其中前m个元素有效 + :param m: 第一个数组的有效长度 + :param nums2: 第二个数组 + :param n: 第二个数组的长度 + :return: 无返回值,直接修改nums1 """ + # 使用双指针从后向前比较和填充元素 while m > 0 and n > 0: - if nums1[m-1] >= nums2[n-1]: - nums1[m+n-1] = nums1[m-1] + if nums1[m - 1] >= nums2[n - 1]: + nums1[m + n - 1] = nums1[m - 1] m -= 1 else: - nums1[m+n-1] = nums2[n-1] + nums1[m + n - 1] = nums2[n - 1] n -= 1 + + # 将剩余的nums2元素填充到nums1中 if n > 0: nums1[:n] = nums2[:n] - - \ No newline at end of file diff --git a/solutions/python3/880.py b/solutions/python3/880.py index 876ca02..f835668 100644 --- a/solutions/python3/880.py +++ b/solutions/python3/880.py @@ -1,12 +1,30 @@ + class Solution: - def decodeAtIndex(self, S, K): + def decodeAtIndex(self, S: str, K: int) -> str: + """ + 解码字符串S中的第K个字符。 + + 参数: + S (str): 输入的编码字符串 + K (int): 需要找到的解码后位置 + + 返回: + str: 第K个解码后的字符 + """ + stack, l = [], 0 + # 遍历字符串S中的每个字符c for c in S: - l = l + 1 if c.isalpha() else l * int(c) - stack += c, + # 如果是字母,长度加1;如果是数字,则扩展当前的总长度l + l += 1 if c.isalpha() else int(c) * l + stack.append(c) + # 当累积长度大于等于K时开始回溯处理 while l >= K: - while stack[-1].isdigit(): l //= int(stack.pop()) - K = K % l + # 弹出栈顶元素,更新长度l + while isinstance(stack[-1], int): + l //= stack.pop() + # 更新K的位置,并判断是否找到解码结果 + K %= l if not K: return stack[-1] l -= 1 - stack.pop() \ No newline at end of file + stack.pop() diff --git a/solutions/python3/881.py b/solutions/python3/881.py index 33e7eb6..84f46a3 100644 --- a/solutions/python3/881.py +++ b/solutions/python3/881.py @@ -1,15 +1,25 @@ + class Solution: - def numRescueBoats(self, people, limit): + def numRescueBoats(self, people: list[int], limit: int) -> int: """ - :type people: List[int] - :type limit: int - :rtype: int + :param people: 人重量列表 + :param limit: 每艘船的最大载重限制 + :return: 所需的最小船只数量 """ + + # 对人员重量进行排序,以便轻的人和重的人可以配对或单独乘坐 people.sort() + l, r, cnt = 0, len(people) - 1, 0 + # 双指针遍历列表 while l <= r: - if l != r and people[l] + people[r] > limit: l -= 1 - l += 1 - r -= 1 + if l != r and people[l] + people[r] > limit: + # 如果轻的人与重的人之和超过限制,移动右指针以尝试更轻的组合 + r -= 1 + else: + # 否则,两人都可以乘坐一艘船 + l += 1 + r -= 1 cnt += 1 - return cnt \ No newline at end of file + + return cnt diff --git a/solutions/python3/882.py b/solutions/python3/882.py index 664eb8c..2eb7557 100644 --- a/solutions/python3/882.py +++ b/solutions/python3/882.py @@ -1,10 +1,27 @@ + +from collections import defaultdict + class Solution: def reachableNodes(self, edges, M, N): - adj, seen = collections.defaultdict(dict), set() + """ + 生成图的邻接表表示,并初始化已访问节点集合。 + + :param edges: 列表,包含边及其对应的长度 + :param M: 源点可以移动的最大步数 + :param N: 节点总数(虽然未直接使用) + :return: 可达节点对的总和 + 已访问节点数量 + """ + # 使用defaultdict来存储图的邻接表表示,并初始化已访问节点集合 + adj, seen = defaultdict(dict), set() + + # 遍历每条边,填充邻接表并记录初始步数为0 for a, b, l in edges: adj[a][b] = [l, 0] adj[b][a] = [l, 0] + q = [(0, M, None)] + + # 使用广度优先搜索更新每条边的可到达步数上限 while q: new = [] for i, moves, pre in q: @@ -12,7 +29,10 @@ def reachableNodes(self, edges, M, N): for j in adj[i]: if moves > adj[i][j][1]: adj[i][j][1] = moves + # 如果当前节点可以访问到的步数大于初始步数,并且不是前一个节点,则添加新的队列元素 if moves > adj[i][j][0] and j != pre: new.append((j, moves - adj[i][j][0] - 1, i)) - q = new - return sum(min(adj[i][j][1] + adj[j][i][1], l) for i, j, l in edges) + len(seen) \ No newline at end of file + q = new + + # 计算可达节点对的总和以及已访问节点数量 + return sum(min(adj[i][j][1] + adj[j][i][1], l) for i, j, l in edges) + len(seen) diff --git a/solutions/python3/883.py b/solutions/python3/883.py index dad8dcd..dd3b9ca 100644 --- a/solutions/python3/883.py +++ b/solutions/python3/883.py @@ -1,11 +1,21 @@ + class Solution: def projectionArea(self, grid): """ :type grid: List[List[int]] :rtype: int """ + # 获取网格的大小 n = len(grid) + + # 计算顶视图面积,即非零元素的数量 top = sum(grid[i][j] != 0 for i in range(n) for j in range(n)) + + # 计算前视图面积,即每行的最大值之和 front = sum(max(grid[i]) for i in range(n)) + + # 计算侧视图面积,即每列的最大值之和 side = sum(max(grid[i][j] for i in range(n)) for j in range(n)) - return top + front + side \ No newline at end of file + + # 返回顶视图、前视图和侧视图面积的总和 + return top + front + side diff --git a/solutions/python3/884.py b/solutions/python3/884.py index 2435857..a2041c3 100644 --- a/solutions/python3/884.py +++ b/solutions/python3/884.py @@ -1,5 +1,17 @@ + class Solution: + # 定义一个类来解决问题 + def uncommonFromSentences(self, A: str, B: str) -> List[str]: + # 使用collections.Counter统计单词出现次数 c1 = collections.Counter(A.split()) c2 = collections.Counter(B.split()) - return list(c for c in c1 if c1[c] == 1 and c not in c2) + list(c for c in c2 if c2[c] == 1 and c not in c1) \ No newline at end of file + + # 找出只在A中出现一次且不在B中的单词 + uncommon_in_A = [c for c in c1 if c1[c] == 1 and c not in c2] + + # 找出只在B中出现一次且不在A中的单词 + uncommon_in_B = [c for c in c2 if c2[c] == 1 and c not in c1] + + # 返回所有不常见的单词 + return uncommon_in_A + uncommon_in_B diff --git a/solutions/python3/885.py b/solutions/python3/885.py index a0c8288..798a8e1 100644 --- a/solutions/python3/885.py +++ b/solutions/python3/885.py @@ -1,13 +1,23 @@ + class Solution: - def spiralMatrixIII(self, R, C, r0, c0): - direct, res, n, l, ind = [(-1, 0), (0, 1), (1, 0), (0, -1)], [[r0, c0]], R * C, 1, 1 + # 定义解决方案类 + + def spiralMatrixIII(self, R: int, C: int, r0: int, c0: int) -> list[list[int]]: + # 初始化方向、结果列表、总节点数、步长和当前方向索引 + direct = [(-1, 0), (0, 1), (1, 0), (0, -1)] + res = [[r0, c0]] + n = R * C + l, ind = 1, 1 + + # 当结果列表长度小于总节点数时,继续生成螺旋矩阵 while len(res) < n: - for __ in range(2): - for _ in range(l): + for _ in range(2): # 每层循环两次(水平+垂直) + for __ in range(l): r0 += direct[ind][0] - c0 += direct[ind][1] - if 0 <= r0 < R and 0 <= c0 < C: + c0 += direct[ind][1] # 更新当前位置坐标 + if 0 <= r0 < R and 0 <= c0 < C: # 判断是否在矩阵范围内 res.append([r0, c0]) - ind = (ind + 1) % 4 - l += 1 - return res \ No newline at end of file + ind = (ind + 1) % 4 # 更换方向索引 + l += 1 # 增加步长 + + return res # 返回结果列表 diff --git a/solutions/python3/886.py b/solutions/python3/886.py index 532a3c7..5d9b90b 100644 --- a/solutions/python3/886.py +++ b/solutions/python3/886.py @@ -1,15 +1,34 @@ + class Solution: - def merge(self, node, p, group, disliked): + # 定义合并函数,尝试将节点node划分为组p + def merge(self, node: int, p: int, group: list[int], disliked: dict[int, set[int]]) -> bool: + # 将节点node划分到组p中 group[node] = p + + # 遍历disliked中的连接节点v for v in disliked[node]: - if group[v] == p or (group[v] == v and not self.merge(v, -p, group, disliked)): return False + # 如果节点v已经属于相同的分组或者未被正确划分,返回False + if group[v] == p or (group[v] == v and not self.merge(v, -p, group, disliked)): + return False + + # 成功划分所有连接节点到不同组别 return True - - def possibleBipartition(self, N, dislikes): - group, disliked = [i for i in range(N + 1)], collections.defaultdict(set) + + # 定义判断是否可以二分图划分的函数 + def possibleBipartition(self, N: int, dislikes: list[list[int]]) -> bool: + # 初始化分组列表和不喜欢关系字典 + group = [i for i in range(N + 1)] + disliked = collections.defaultdict(set) + + # 建立不喜欢关系图 for a, b in dislikes: disliked[a].add(b) disliked[b].add(a) + + # 尝试将每个节点划分到不同组别 for i in range(1, N + 1): - if group[i] == i and not self.merge(i, 2001, group, disliked): return False - return True \ No newline at end of file + if group[i] == i and not self.merge(i, 2001, group, disliked): + return False + + # 如果所有节点都能正确划分,返回True + return True diff --git a/solutions/python3/887.py b/solutions/python3/887.py index 23764b8..2241b61 100644 --- a/solutions/python3/887.py +++ b/solutions/python3/887.py @@ -1,12 +1,22 @@ + class Solution: - def superEggDrop(self, K, N): - drops = 0 # the number of eggs dropped - floors = [0 for _ in range(K + 1)] # floors[i] is the number of floors that can be checked with i eggs + def superEggDrop(self, K: int, N: int) -> int: + """ + 定义一个类,用于解决超级鸡蛋掉落问题。 + + 解释: + - 通过动态规划方法计算在K个鸡蛋和N层楼的情况下最少需要尝试多少次才能确定鸡蛋的临界高度。 + """ - while floors[K] < N: # until we can reach N floors with K eggs + drops = 0 # 记录鸡蛋被丢弃的数量 + floors = [0 for _ in range(K + 1)] # floors[i] 表示使用 i 个鸡蛋可以检查的最大层数 + while floors[K] < N: # 当 K 个鸡蛋无法覆盖 N 层楼时继续循环 + + # 对于每个鸡蛋数量 eggs,从 K 到 1 逆序遍历 for eggs in range(K, 0, -1): + # 更新 floors 数组中对应的值 floors[eggs] += 1 + floors[eggs - 1] drops += 1 - return drops \ No newline at end of file + return drops diff --git a/solutions/python3/888.py b/solutions/python3/888.py index 767fb34..e965a8d 100644 --- a/solutions/python3/888.py +++ b/solutions/python3/888.py @@ -1,12 +1,20 @@ + class Solution: - def fairCandySwap(self, A, B): + def fairCandySwap(self, A: list[int], B: list[int]) -> list[int]: """ :type A: List[int] :type B: List[int] :rtype: List[int] """ + + # 将列表A和B转换为集合,以提高查找效率 a, b = set(A), set(B) - diff =(sum(A) - sum(B)) // 2 + + # 计算双方糖果数量差值的一半 + diff = (sum(A) - sum(B)) // 2 + + # 遍历集合B中的每一个元素c for c in B: + # 检查c加上计算出的差值是否在集合A中,以找到公平交换的糖果组合 if c + diff in a: - return [c + diff, c] \ No newline at end of file + return [c + diff, c] diff --git a/solutions/python3/889.py b/solutions/python3/889.py index 28bc02c..b2e145c 100644 --- a/solutions/python3/889.py +++ b/solutions/python3/889.py @@ -1,13 +1,25 @@ + class Solution: def constructFromPrePost(self, pre, post): + """ + 构造二叉树,给定前序和后序遍历结果 + + :param pre: List[int] - 前序遍历列表 + :param post: List[int] - 后序遍历列表 + :return: TreeNode - 构建的二叉树根节点 + """ if pre: - root = TreeNode(pre.pop(0)) - post.pop() - if pre: - if pre[0] == post[-1]: - root.left = self.constructFromPrePost(pre, post) + root = TreeNode(pre.pop(0)) # 弹出并设置前序遍历的第一个元素为根节点 + post.pop() # 移除后序遍历中的最后一个元素,因为它已与根节点匹配 + + if pre: # 确保列表不为空 + if pre[0] == post[-1]: # 检查左子树的前序首元素是否等于后序尾元素 + root.left = self.constructFromPrePost(pre, post) # 递归构建左子树 else: - l, r = post.index(pre[0]), pre.index(post[-1]) - root.left = self.constructFromPrePost(pre[:r], post[:l + 1]) - root.right = self.constructFromPrePost(pre[r:], post[l + 1:]) - return root \ No newline at end of file + l_idx = post.index(pre[0]) # 找到左子树在后序遍历中的索引 + r_idx = pre.index(post[-1]) # 找到右子树在前序遍历中的索引 + + root.left = self.constructFromPrePost(pre[:r_idx], post[:l_idx + 1]) # 递归构建左子树 + root.right = self.constructFromPrePost(pre[r_idx:], post[l_idx + 1:]) # 递归构建右子树 + + return root diff --git a/solutions/python3/89.py b/solutions/python3/89.py index c92f2ca..2f733c6 100644 --- a/solutions/python3/89.py +++ b/solutions/python3/89.py @@ -1,7 +1,13 @@ + class Solution: + # 定义一个类用于求解格雷码 + def grayCode(self, n: int) -> List[int]: + # 初始化结果列表,包含0作为起点 results = [0] - for i in range(n): + + for i in range(n): + # 对当前结果列表进行逆序操作,并与当前位的2的幂次相加后添加到结果中 results += [x + pow(2, i) for x in reversed(results)] - return results - \ No newline at end of file + + return results # 返回最终生成的格雷码列表 diff --git a/solutions/python3/890.py b/solutions/python3/890.py index 96ac261..c787e29 100644 --- a/solutions/python3/890.py +++ b/solutions/python3/890.py @@ -1,3 +1,4 @@ + class Solution: def findAndReplacePattern(self, words, pattern): """ @@ -5,13 +6,25 @@ def findAndReplacePattern(self, words, pattern): :type pattern: str :rtype: List[str] """ + # 初始化结果列表 res = [] + for w in words: + # 用于映射字符的字典,分别从word到pattern和pattern到word进行双向映射 mp12, mp21, match = {}, {}, True + + # 遍历单词w和模式字符串pattern中的字符对 for c1, c2 in zip(w, pattern): + # 检查当前字符是否已经存在于字典中,且对应关系不匹配,则标记为非匹配 if (c1 in mp12 and mp12[c1] != c2) or (c2 in mp21 and mp21[c2] != c1): match = False break + + # 将当前字符映射加入字典中 mp12[c1], mp21[c2] = c2, c1 - if match: res.append(w) - return res \ No newline at end of file + + # 如果当前单词符合模式,则添加至结果列表 + if match: + res.append(w) + + return res diff --git a/solutions/python3/891.py b/solutions/python3/891.py index 7419c98..168f220 100644 --- a/solutions/python3/891.py +++ b/solutions/python3/891.py @@ -1,9 +1,21 @@ + class Solution: + # 定义求子序列宽度和的解决方案类 + def sumSubseqWidths(self, A): - A.sort() - res=0 + """ + :type A: List[int] # 输入列表A,包含整数元素 + :rtype: int # 返回值为计算结果,取模10^9+7 + """ + A.sort() # 对输入列表进行排序 + + res = 0 # 初始化结果变量res为0 + for i in range(len(A)): - res*=2 - res-=A[i] - res+=A[~i] - return res % (10**9+7) \ No newline at end of file + # 每次循环将当前元素的贡献值加到结果中 + # 通过乘以2并减去和加上相应位置的元素实现子序列宽度累加 + res *= 2 + res -= A[i] + res += A[~i] + + return res % (10**9+7) # 返回结果对10^9+7取模后的值,确保结果在int范围内 diff --git a/solutions/python3/892.py b/solutions/python3/892.py index 150415e..713c4b4 100644 --- a/solutions/python3/892.py +++ b/solutions/python3/892.py @@ -1,11 +1,29 @@ + class Solution: + # 定义一个求解表面积的方法 def surfaceArea(self, grid): n, sm = len(grid), 0 + + # 遍历每个格子 for i in range(n): for j in range(n): - sm += grid[i][j] and grid[i][j] * 4 + 2 - if i > 0: sm -= min(grid[i - 1][j], grid[i][j]) - if j > 0: sm -= min(grid[i][j - 1], grid[i][j]) - if i < n - 1: sm -= min(grid[i + 1][j], grid[i][j]) - if j < n - 1: sm -= min(grid[i][j + 1], grid[i][j]) - return sm \ No newline at end of file + # 计算当前格子的贡献值:高度 * 4(上下面) + 2(侧面) + sm += grid[i][j] and (grid[i][j] * 4 + 2) + + # 检查上方 + if i > 0: + sm -= min(grid[i - 1][j], grid[i][j]) + + # 检查左方 + if j > 0: + sm -= min(grid[i][j - 1], grid[i][j]) + + # 检查下方 + if i < n - 1: + sm -= min(grid[i + 1][j], grid[i][j]) + + # 检查右方 + if j < n - 1: + sm -= min(grid[i][j + 1], grid[i][j]) + + return sm diff --git a/solutions/python3/893.py b/solutions/python3/893.py index 7b1dbd1..2d5b9da 100644 --- a/solutions/python3/893.py +++ b/solutions/python3/893.py @@ -1,3 +1,12 @@ + class Solution: + # 定义一个类来解决特殊等价分组问题 + def numSpecialEquivGroups(self, A): - return len(set("".join(sorted(s[0::2])) + "".join(sorted(s[1::2])) for s in A)) \ No newline at end of file + # 计算字符串A中不同特殊等价分组的数量 + + # 通过构建每个字符串的奇数和偶数组合,并对它们进行排序后拼接 + # 利用集合去重,得到的不同组合即为特殊等价分组数量 + return len(set("".join(sorted(s[0::2])) + "".join(sorted(s[1::2])) for s in A)) + # 中文注释:通过构建每个字符串的奇数和偶数组合,并对它们进行排序后拼接 + # 利用集合去重,得到的不同组合即为特殊等价分组数量 diff --git a/solutions/python3/894.py b/solutions/python3/894.py index fe48c3b..6ddfcde 100644 --- a/solutions/python3/894.py +++ b/solutions/python3/894.py @@ -1,12 +1,36 @@ + class Solution: - def allPossibleFBT(self, N): - def constr(N): - if N == 1: yield TreeNode(0) - for i in range(1, N, 2): - for l in constr(i): - for r in constr(N - i - 1): - m = TreeNode(0) - m.left = l - m.right = r - yield m - return list(constr(N)) \ No newline at end of file + def allPossibleFBT(self, N: int) -> List[TreeNode]: + """ + 构建所有可能的单叶二叉树,节点总数为N。 + + Parameters: + N (int): 树中结点数 + + Returns: + List[TreeNode]: 包含所有可能构建的单叶二叉树根节点的列表 + """ + + def constr(N: int) -> Generator[TreeNode, None, None]: + """ + 生成满足条件的所有可能的单叶二叉树。 + + Parameters: + N (int): 当前子树需要填充的结点数 + + Returns: + Generator[TreeNode]: 包含所有可能构建的单叶二叉树根节点的生成器 + """ + if N == 1: + yield TreeNode(0) + else: + for i in range(1, N, 2): + # 遍历左子树结点数,右子树结点数由剩余决定 + for l in constr(i): + for r in constr(N - i - 1): + m = TreeNode(0) # 创建根节点 + m.left = l # 左子树连接到根节点 + m.right = r # 右子树连接到根节点 + yield m # 返回生成的单叶二叉树 + + return list(constr(N)) # 将生成器转换为列表 diff --git a/solutions/python3/895.py b/solutions/python3/895.py index ffcbd6c..4945a58 100644 --- a/solutions/python3/895.py +++ b/solutions/python3/895.py @@ -1,17 +1,32 @@ + class FreqStack: def __init__(self): - self.stacks = collections.defaultdict(list) - self.freq = collections.Counter() + """ + 初始化类,使用defaultdict存储按频率分组的栈和计数器。 + :param: None + """ + from collections import defaultdict, Counter + self.stacks = defaultdict(list) + self.freq = Counter() self.maxFreq = 0 def push(self, x): + """ + 将元素x压入对应的频率栈中,并更新最大频率。 + :param x: 待添加的元素 + """ self.freq[x] += 1 self.maxFreq = max(self.maxFreq, self.freq[x]) self.stacks[self.freq[x]].append(x) def pop(self): + """ + 弹出并返回当前具有最大频率的栈中的最顶元素,更新计数器和最大频率。 + :return: 具有最大频率的栈中最顶元素 + """ num = self.stacks[self.maxFreq].pop() self.freq[num] -= 1 - if not self.stacks[self.maxFreq]: self.maxFreq -= 1 - return num \ No newline at end of file + if not self.stacks[self.maxFreq]: + self.maxFreq -= 1 + return num diff --git a/solutions/python3/896.py b/solutions/python3/896.py index 6a81d5c..e455338 100644 --- a/solutions/python3/896.py +++ b/solutions/python3/896.py @@ -1,3 +1,12 @@ + class Solution: + # 判断列表A是否为单调的,即非递增或非递减 def isMonotonic(self, A): - return all(A[i] <= A[i - 1] for i in range(1, len(A))) or all(A[i] >= A[i - 1] for i in range(1, len(A))) \ No newline at end of file + # 检查元素顺序是否非递减 + non_decreasing = all(A[i] >= A[i - 1] for i in range(1, len(A))) + + # 检查元素顺序是否非递增 + non_increasing = all(A[i] <= A[i - 1] for i in range(1, len(A))) + + # 如果满足其中一个条件,则返回True,否则False + return non_decreasing or non_increasing diff --git a/solutions/python3/897.py b/solutions/python3/897.py index 0392770..f30172c 100644 --- a/solutions/python3/897.py +++ b/solutions/python3/897.py @@ -1,14 +1,21 @@ + # Definition for a binary tree node. -# class TreeNode: -# def __init__(self, x): -# self.val = x -# self.left = None -# self.right = None +class TreeNode: + def __init__(self, x): + self.val = x + self.left = None + self.right = None class Solution: - def increasingBST(self, root, tail = None): - if not root: return tail - res = self.increasingBST(root.left, root) - root.left = None - root.right = self.increasingBST(root.right, tail) - return res \ No newline at end of file + # 递归构建一个单调递增的二叉树,尾节点初始为None + def increasingBST(self, root: TreeNode, tail = None) -> TreeNode: + if not root: + return tail # 如果当前节点为空,则返回尾节点 + + res = self.increasingBST(root.left, root) # 先处理左子树 + + root.left = None # 清除左指针,确保单调性 + + root.right = self.increasingBST(root.right, tail) # 处理右子树,并将当前节点连接到新的尾部 + + return res # 返回重构后的根节点 diff --git a/solutions/python3/898.py b/solutions/python3/898.py index cfbfb83..481fa96 100644 --- a/solutions/python3/898.py +++ b/solutions/python3/898.py @@ -1,7 +1,17 @@ + class Solution: + # 定义一个类来解决子数组的按位或操作问题 + def subarrayBitwiseORs(self, A): + # 初始化结果集和当前处理数组长度,同时定义一个集合用于记录前一状态的结果 nums, n, pre = set(), len(A), set() + for a in A: + # 更新当前元素a与pre中的所有元素进行按位或操作,并将结果添加到pre中 pre = {a} | {num | a for num in pre} + + # 将当前的前一状态结果集更新到最终结果集中 nums |= pre - return len(nums) \ No newline at end of file + + # 返回最终的结果集大小,即满足条件的不同子数组的数量 + return len(nums) diff --git a/solutions/python3/899.py b/solutions/python3/899.py index cda2faa..c328d5a 100644 --- a/solutions/python3/899.py +++ b/solutions/python3/899.py @@ -1,3 +1,14 @@ + class Solution: - def orderlyQueue(self, S, K): - return "".join(sorted(S)) if K > 1 else min(S[i:] + S[:i] for i in range(len(S))) \ No newline at end of file + # 定义有序队列类,用于解决字符串排序或旋转问题 + + def orderlyQueue(self, S: str, K: int) -> str: + # 如果K大于1,说明可以进行全排序 + if K > 1: + # 返回已排序的字符串 + return "".join(sorted(S)) + + # 否则K为1,只能通过旋转来尝试找到最小值 + else: + # 生成所有可能的旋转子串并返回其中最小的一个 + return min(S[i:] + S[:i] for i in range(len(S))) diff --git a/solutions/python3/9.py b/solutions/python3/9.py index af02e91..7183e5f 100644 --- a/solutions/python3/9.py +++ b/solutions/python3/9.py @@ -1,3 +1,6 @@ + class Solution: - def isPalindrome(self, x): - return str(x) == str(x)[::-1] \ No newline at end of file + # 判断一个整数是否为回文数 + def isPalindrome(self, x: int) -> bool: + # 将整数转换为字符串,并与反转后的字符串比较 + return str(x) == str(x)[::-1] diff --git a/solutions/python3/90.py b/solutions/python3/90.py index 2e12f79..c768b7d 100644 --- a/solutions/python3/90.py +++ b/solutions/python3/90.py @@ -1,15 +1,18 @@ + class Solution: - def subsetsWithDup(self, nums): + def subsetsWithDup(self, nums: list[int]) -> list[list[int]]: """ - :type nums: List[int] - :rtype: List[List[int]] + :type nums: List[int] # 输入列表,包含整数元素 + :rtype: List[List[int]] # 返回所有不重复子集组成的列表 """ from itertools import combinations as cb - res, dic = [], set() + + res = [] # 存储结果的列表 + dic = set() # 用于存储已经处理过的元组,避免重复 for i in range(len(nums) + 1): - for item in cb(nums, i): - item = tuple(sorted(item)) - if item not in dic: - dic.add(item) - res.append(item) - return res \ No newline at end of file + for item in cb(nums, i): # 使用itertools.combinations生成所有可能的组合 + item = tuple(sorted(item)) # 将列表转换为排序后的元组 + if item not in dic: # 检查是否已经处理过此组合 + dic.add(item) # 添加到已处理集合中,避免重复 + res.append(item) # 将新的子集加入结果列表 + return res # 返回所有不包含重复的子集组成的列表 diff --git a/solutions/python3/900.py b/solutions/python3/900.py index 771c0ff..7897be2 100644 --- a/solutions/python3/900.py +++ b/solutions/python3/900.py @@ -1,15 +1,28 @@ + class RLEIterator: def __init__(self, A): + """ + 初始化RLE解码器,A为压缩序列,逆序存储。 + :param A: List[int] 压缩序列 + """ self.it = A[::-1] def next(self, n): + """ + 获取下一个元素。解压前n个重复的值并返回实际元素。 + 如果无法满足n次解压,则返回-1。 + :type n: int + :rtype: int + """ while self.it and self.it[-1] <= n: - if self.it[-1]: last = self.it[-2] - n -= self.it.pop() - self.it.pop() - if n and self.it: - self.it[-1] -= n + if self.it[-1]: # 只有当数量大于0时,才更新last值 + last = self.it[-2] + n -= self.it.pop() # 减去当前的数量 + self.it.pop() # 删除当前数量 + + if n and self.it: # 如果n还有剩余且不为空 + self.it[-1] -= n # 更新剩余的解压次数 last = self.it[-2] + return last if self.it else -1 - \ No newline at end of file diff --git a/solutions/python3/901.py b/solutions/python3/901.py index 62177de..70f5bcb 100644 --- a/solutions/python3/901.py +++ b/solutions/python3/901.py @@ -1,27 +1,36 @@ + class StockSpanner: def __init__(self): - self.arr = [] + """ + 初始化类实例,用于存储股票价格序列和对应的权重。 + + :初始化: 两个列表arr和res,分别存放价格序列和权重序列。 + """ + self.arr = [] self.res = [] def next(self, price): """ + 添加一个新的股票价格,并返回该价格的权重。 + :type price: int :rtype: int """ - if self.arr and self.arr[-1] > price: self.res.append(1) + if self.arr and self.arr[-1] > price: + self.res.append(1) else: i = len(self.arr) - 1 while i >= 0: if self.arr[i] <= price and self.res[i]: i -= self.res[i] - else: break + else: + break self.res.append(len(self.arr) - i) self.arr.append(price) return self.res[-1] - # Your StockSpanner object will be instantiated and called as such: # obj = StockSpanner() -# param_1 = obj.next(price) \ No newline at end of file +# param_1 = obj.next(price) diff --git a/solutions/python3/902.py b/solutions/python3/902.py index 51ba757..6888779 100644 --- a/solutions/python3/902.py +++ b/solutions/python3/902.py @@ -1,16 +1,40 @@ + class Solution: def atMostNGivenDigitSet(self, D, N): + """ + Given a set of digits D and a number N, find how many numbers can be formed with the digits in D that are less than or equal to N. + + Args: + D: A list of unique digits (str). + N: The target number as a string. + + Returns: + The count of numbers <= N which can be formed using only digits from set D. + """ def less(c): + """ + Count how many digits in the set are smaller than c. + + Args: + c: A single character representing a digit. + + Returns: + The count of digits in D that are smaller than c. + """ return len([char for char in D if char < c]) + d, cnt, l = len(D), 0, len(str(N)) - # For numbers which have less digits than N, simply len(D) ** digits_length different numbers can be created + # For numbers with fewer digits than N, simply the number of combinations is |D|^digits_length for i in range(1, l): cnt += d ** i + """ - We should also consider edge cases where previous digits match with related digits in N. In this case, we can make a number with previous digits + (digits less than N[i]) + D ** remaining length + We need to consider cases where the leading digits match. In such cases, + we can form a number by adding 'previous valid digits' + (digits less than N[i]) + D ** remaining length. """ for i, c in enumerate(str(N)): cnt += less(c) * (d ** (l - i - 1)) if c not in D: break if i == l - 1: cnt += 1 - return cnt \ No newline at end of file + + return cnt diff --git a/solutions/python3/903.py b/solutions/python3/903.py index ecd76c1..ef810b1 100644 --- a/solutions/python3/903.py +++ b/solutions/python3/903.py @@ -1,13 +1,27 @@ + class Solution: def numPermsDISequence(self, S: str) -> int: + """ + 计算满足给定序列的排列数。 + + 参数: + S: 字符串,表示递增("I")和递减("D")序列 + + 返回: + 满足条件的排列数 % (10^9 + 7) + """ dp = [1] * (len(S) + 1) + + # 遍历字符串S for c in S: if c == "I": + # 处理递增序列 dp = dp[:-1] for i in range(1, len(dp)): dp[i] += dp[i - 1] else: + # 处理递减序列 dp = dp[1:] for i in range(len(dp) - 1)[::-1]: dp[i] += dp[i + 1] - return dp[0] % (10**9 + 7) \ No newline at end of file + return dp[0] % (10**9 + 7) diff --git a/solutions/python3/904.py b/solutions/python3/904.py index 8fa3c76..5db8413 100644 --- a/solutions/python3/904.py +++ b/solutions/python3/904.py @@ -1,12 +1,25 @@ + class Solution: def totalFruit(self, tree: List[int]) -> int: + """ + 初始化结果和指针i为0,使用字典last记录每种水果最后出现的位置 + :param tree: 树形列表,表示树上的水果种类 + :return: 最大可收集的两种不同类型的水果的数量 + """ res = i = 0 last = collections.defaultdict(int) + for j, val in enumerate(tree): + # 当前已记录的不同类型水果数量大于2且当前水果未在字典中,更新指针位置 if len(last) == 2 and val not in last: pre = min(last.values()) i = pre + 1 last.pop(tree[pre]) + + # 更新当前水果的位置到字典last中 last[val] = j + + # 计算以j为结尾的最大可收集的两种不同类型的水果数量,更新结果res res = max(res, j - i + 1) - return res \ No newline at end of file + + return res diff --git a/solutions/python3/905.py b/solutions/python3/905.py index 65b83ff..1290a08 100644 --- a/solutions/python3/905.py +++ b/solutions/python3/905.py @@ -1,3 +1,15 @@ + class Solution: + # 定义一个类用于解决数组按奇偶性排序的问题 + def sortArrayByParity(self, A): - return [a for a in A if not a % 2] + [a for a in A if a % 2] \ No newline at end of file + # 对输入的列表A进行操作,返回一个新的列表,其中偶数位于奇数之前 + + # 使用列表推导式分两部分构建新列表:首先筛选出所有偶数元素 + even_nums = [a for a in A if not a % 2] + + # 然后筛选出所有奇数元素 + odd_nums = [a for a in A if a % 2] + + # 将两部分合并,即先偶数再奇数 + return even_nums + odd_nums diff --git a/solutions/python3/906.py b/solutions/python3/906.py index 9475c5a..3b955c9 100644 --- a/solutions/python3/906.py +++ b/solutions/python3/906.py @@ -1,20 +1,46 @@ + class Solution: - def superpalindromesInRange(self, L, R): + def superpalindromesInRange(self, L: str, R: str) -> int: + """ + 给定两个整数 L 和 R ,找到所有在[L,R]区间内的超回文数字。 + + 参数: + L (str): 区间左边界 + R (str): 区间右边界 + + 返回: + int: 在[L,R]区间内的超回文数字个数 + """ + from math import floor, ceil + + # 将输入转换为整数 L, R = int(L), int(R) - left = int(math.floor(math.sqrt(L))) - right = int(math.ceil(math.sqrt(R))) - n1, n2 = len(str(left)), len(str(right)) - n1 = n1//2 if n1%2==0 else n1//2+1 - n2 = n2//2 if n2%2==0 else n2//2+1 - start = int('1' + '0'*(n1 - 1)) + + # 计算左右边界的平方根并取整 + left_sqrt = int(floor(math.sqrt(L))) + right_sqrt = int(ceil(math.sqrt(R))) + + # 获取平方根的字符串长度,并根据奇偶性计算回文中心长度 + n1, n2 = len(str(left_sqrt)), len(str(right_sqrt)) + n1 = (n1 // 2) if n1 % 2 == 0 else (n1 // 2 + 1) + n2 = (n2 // 2) if n2 % 2 == 0 else (n2 // 2 + 1) + + # 计算回文范围的起始和结束值 + start = int('1' + '0' * (n1 - 1)) end = int('9' * n2) + 1 - ans = 0 + + ans = 0 for i in range(start, end): x = str(i) + # 构建回文数:x + 反转(x) num1 = int(x + x[::-1]) - num2 = int(x + x[:-1][::-1]) + # 特殊情况处理:x + 去掉末位的反转(x) (适用于奇数长度的情况) + num2 = int(x + x[:-1][::-1]) if len(x) % 2 == 1 else 0 + for num in [num1, num2]: + # 检查生成的回文平方是否在[L,R]区间内且是超回文 cand = num * num if L <= cand <= R and str(cand) == str(cand)[::-1]: ans += 1 - return ans \ No newline at end of file + + return ans diff --git a/solutions/python3/907.py b/solutions/python3/907.py index c4f38fe..9681525 100644 --- a/solutions/python3/907.py +++ b/solutions/python3/907.py @@ -1,10 +1,22 @@ + class Solution: + # 定义一个类来解决问题 + def sumSubarrayMins(self, A): - res, stack = 0, [] + # 初始化结果和栈 + res, stack = 0, [] + + # 在数组前后分别添加哨兵元素 A = [float('-inf')] + A + [float('-inf')] + for i, n in enumerate(A): + # 当前值小于栈顶元素时,处理栈内元素 while stack and A[stack[-1]] > n: cur = stack.pop() res += A[cur] * (i - cur) * (cur - stack[-1]) + + # 将当前索引入栈 stack.append(i) - return res % (10 ** 9 + 7) \ No newline at end of file + + # 返回结果对 10^9 + 7 取模后的值 + return res % (10 ** 9 + 7) diff --git a/solutions/python3/908.py b/solutions/python3/908.py index 1515b5c..e14167c 100644 --- a/solutions/python3/908.py +++ b/solutions/python3/908.py @@ -1,4 +1,15 @@ + class Solution: + # 定义一个方法smallestRangeI,接受两个参数A和K def smallestRangeI(self, A, K): - l, r = min(A) + K, max(A) - K - return 0 if l >= r else r - l \ No newline at end of file + # 计算最小值加上K + l = min(A) + K + # 计算最大值减去K + r = max(A) - K + + # 如果最小值加上K大于等于最大值减去K,返回0 + if l >= r: + return 0 + # 否则返回r-l的差值 + else: + return r - l diff --git a/solutions/python3/909.py b/solutions/python3/909.py index bc49cb7..7562c06 100644 --- a/solutions/python3/909.py +++ b/solutions/python3/909.py @@ -1,14 +1,29 @@ + class Solution: def snakesAndLadders(self, board): + """ + 定义一个方法,接收棋盘列表board作为输入。 + + :param board: 棋盘的二维数组表示 + :return: 返回从起点到终点所需的最少移动次数,若无法到达则返回-1 + """ + # 初始化辅助数组、棋盘大小、队列、已访问标记集和步数计数器 arr, nn, q, seen, moves = [0], len(board) ** 2, [1], set(), 0 - for i, row in enumerate(board[::-1]): arr += row[::-1] if i % 2 else row + + # 将board中的行反向并按奇偶调整顺序添加至arr中,构建从终点到起点的线性表示 + for i, row in enumerate(board[::-1]): + arr += row[::-1] if i % 2 else row + + # 使用广度优先搜索遍历棋盘上的所有可能路径 while q: new = [] for sq in q: if sq == nn: return moves for i in range(1, 7): + # 计算下一步位置,检查是否已访问过,并更新队列和步数计数器 if sq + i <= nn and sq + i not in seen: seen.add(sq + i) new.append(sq + i if arr[sq + i] == -1 else arr[sq + i]) q, moves = new, moves + 1 - return -1 \ No newline at end of file + + return -1 diff --git a/solutions/python3/91.py b/solutions/python3/91.py index 63a0459..ad5b825 100644 --- a/solutions/python3/91.py +++ b/solutions/python3/91.py @@ -1,8 +1,26 @@ + class Solution: def numDecodings(self, s): - if s[0] == "0": return 0 - dp1 = dp2 = 1 + """ + 判断字符串s可以有多少种解码方法。 + + 解码规则: + - 单个字符 '1'~'9' 可以解码为一个数字(A~I); + - 两个字符 '10'~'26' 可以解码为一个字母(J~Z)。 + + :param s: str,待解码的字符串 + :return: int,解码方法的数量 + """ + + if s[0] == "0": + return 0 # 如果第一个字符是 '0',直接返回0 + + dp1 = dp2 = 1 # 初始化动态规划数组 dp1 和 dp2,dp2 表示当前位的解码数 + for i in range(1, len(s)): - if s[i] == "0" and (s[i - 1] == "0" or s[i - 1] >= "3"): return 0 - dp1, dp2 = [dp2, dp1] if s[i] == "0" else [dp2, dp2 + dp1] if "10" <= s[i -1: i + 1] <= "26" else [dp2, dp2] - return dp2 \ No newline at end of file + if s[i] == "0" and (s[i - 1] == "0" or s[i - 1] >= "3"): + return 0 # 如果当前是 '0',且前一个字符不是 '1' 或 '2' 则无法解码 + + dp1, dp2 = [dp2, dp1] if s[i] == "0" else [dp2, dp2 + dp1] if "10" <= s[i - 1: i + 1] <= "26" else [dp2, dp2] + + return dp2 diff --git a/solutions/python3/910.py b/solutions/python3/910.py index bcb18d3..a6c80ea 100644 --- a/solutions/python3/910.py +++ b/solutions/python3/910.py @@ -1,4 +1,56 @@ + class Solution: - def smallestRangeII(self, A, K): + # 定义一个类来解决问题 + + def smallestRangeII(self, A: list[int], K: int) -> int: + """ + 计算将数组A中的每个元素增加或减少K后,得到的范围内最大差值最小的范围。 + + 参数: + A (list[int]): 输入的整数列表 + K (int): 可以对每个元素进行增减的最大值 + + 返回: + int: 通过调整后的最小范围 + """ + + # 对数组A进行排序,方便后续操作 A.sort() - return min([max(A[-1] - K, A[i] + K) - min(A[0] + K, A[i + 1] - K) for i in range(len(A) - 1)] + [A[-1] - A[0]]) \ No newline at end of file + + # 计算原始最大差值作为初始最小范围 + min_range = A[-1] - A[0] + + # 遍历数组,计算调整后的可能最小范围 + for i in range(len(A) - 1): + max_val = max(A[-1] - K, A[i] + K) + min_val = min(A[0] + K, A[i + 1] - K) + + # 计算当前范围内最大差值,并更新最小范围 + min_range = min(min_range, max_val - min_val) + + return min_range + + + +class Solution: + def smallestRangeII(self, A: list[int], K: int) -> int: + """ + 计算将数组A中的每个元素增加或减少K后,得到的范围内最大差值最小的范围。 + + 参数: + A (list[int]): 输入的整数列表 + K (int): 可以对每个元素进行增减的最大值 + + 返回: + int: 通过调整后的最小范围 + """ + A.sort() + min_range = A[-1] - A[0] + + for i in range(len(A) - 1): + max_val = max(A[-1] - K, A[i] + K) + min_val = min(A[0] + K, A[i + 1] - K) + + min_range = min(min_range, max_val - min_val) + + return min_range diff --git a/solutions/python3/911.py b/solutions/python3/911.py index 5e4ed37..5e1e188 100644 --- a/solutions/python3/911.py +++ b/solutions/python3/911.py @@ -1,15 +1,23 @@ + class TopVotedCandidate: + # 初始化类,记录投票结果和获胜者 def __init__(self, persons, times): + import collections + votes = collections.defaultdict(int) winner = 0 self.winners = [None] * len(times) self.times = times + for i, person in enumerate(persons): - votes[person] += 1 + votes[person] += 1 if votes[person] >= votes[winner]: winner = person self.winners[i] = winner + # 查询给定时刻的获胜者 def q(self, t): - return self.winners[bisect.bisect(self.times, t) - 1] \ No newline at end of file + import bisect + + return self.winners[bisect.bisect(self.times, t) - 1] diff --git a/solutions/python3/912.py b/solutions/python3/912.py index 1534a1d..f9e2948 100644 --- a/solutions/python3/912.py +++ b/solutions/python3/912.py @@ -1,12 +1,28 @@ + class Solution: + # 定义一个类来解决排序问题 + def sortArray(self, nums: List[int]) -> List[int]: + """ + 使用快速排序算法对整数列表进行排序。 + + 参数: + nums (List[int]): 需要排序的整数列表 + + 返回: + List[int]: 排序后的整数列表 + """ + if len(nums) <= 1: + # 如果数组长度小于等于1,直接返回该数组 return nums pivot = random.choice(nums) + # 选择一个枢轴元素 lt = [v for v in nums if v < pivot] eq = [v for v in nums if v == pivot] gt = [v for v in nums if v > pivot] + # 根据枢轴将数组分为小于、等于和大于三部分 return self.sortArray(lt) + eq + self.sortArray(gt) - \ No newline at end of file + # 递归排序小于部分,等于部分直接加入结果,再递归排序大于部分 diff --git a/solutions/python3/913.py b/solutions/python3/913.py index a2d7988..5a4ecb0 100644 --- a/solutions/python3/913.py +++ b/solutions/python3/913.py @@ -1,56 +1,112 @@ + class Solution: + # 定义猫鼠游戏的解法类 + def catMouseGame(self, graph: 'List[List[int]]') -> 'int': + """ + 返回游戏的结果:1表示老鼠获胜,2表示猫赢,0表示无结果 + :param graph: 鼠、猫可移动到的位置列表图 + :return: 游戏结果 + """ + # 初始化老鼠访问记录和状态表 mouse_visited = [False] * len(graph) - mouse_win_map = [[None for column in range(len(graph))] for row in range(len(graph))] + mouse_win_map = [[None for _ in range(len(graph))] for _ in range(len(graph))] + + # 初始化猫访问记录和状态表 cat_visited = [False] * len(graph) - cat_win_map = [[None for column in range(len(graph))] for row in range(len(graph))] + cat_win_map = [[None for _ in range(len(graph))] for _ in range(len(graph))] + + # 检查老鼠是否能获胜 if self.isMouseWin(graph, 1, 2, mouse_visited, mouse_win_map): return 1 + + # 检查猫是否能获胜 elif self.isCatWin(graph, 1, 2, cat_visited, cat_win_map): return 2 + else: return 0 def isMouseWin(self, graph, mouse, cat, mouse_visited, mouse_win_map): + """ + 判断老鼠能否获胜 + :param graph: 鼠、猫可移动到的位置列表图 + :param mouse: 老鼠当前位置 + :param cat: 猫当前位置 + :param mouse_visited: 记录老鼠已访问过的节点 + :param mouse_win_map: 老鼠状态表 + :return: 是否能获胜 + """ if mouse == 0: return True + + # 如果状态表中已有结果,则直接返回 if mouse_win_map[mouse][cat] is not None: return mouse_win_map[mouse][cat] + + # 标记当前老鼠节点为已访问 mouse_visited[mouse] = True + for mouseMove in graph[mouse]: - if mouseMove == 0 or (mouseMove not in graph[cat] and mouseMove != cat): + if mouseMove == 0 or (mouseMove not in graph[cat] and mouseMove != cat): + # 检查老鼠移动后的情况 if not mouse_visited[mouseMove]: mouseWinFlag = True for catMove in graph[cat]: - if catMove != 0 and not self.isMouseWin(graph, mouseMove, catMove, mouse_visited, mouse_win_map): + if catMove != 0 and not self.isMouseWin(graph, mouseMove, catMove, + mouse_visited, mouse_win_map): + # 如果猫无法获胜,则老鼠可以获胜 mouseWinFlag = False break + + # 更新状态表和访问记录 if mouseWinFlag: mouse_visited[mouse] = False mouse_win_map[mouse][cat] = True return True + + # 清理当前节点的访问标记 mouse_visited[mouse] = False mouse_win_map[mouse][cat] = False return False def isCatWin(self, graph, mouse, cat, cat_visited, cat_win_map): + """ + 判断猫能否获胜 + :param graph: 鼠、猫可移动到的位置列表图 + :param mouse: 老鼠当前位置 + :param cat: 猫当前位置 + :param cat_visited: 记录猫已访问过的节点 + :param cat_win_map: 猫状态表 + :return: 是否能获胜 + """ if mouse == 0: return False + + # 如果状态表中已有结果,则直接返回 if cat_win_map[mouse][cat] is not None: return cat_win_map[mouse][cat] + + # 标记当前猫节点为已访问 cat_visited[cat] = True + for mouseMove in graph[mouse]: - if mouseMove == 0 or (mouseMove not in graph[cat] and mouseMove != cat): + if mouseMove == 0 or (mouseMove not in graph[cat] and mouseMove != cat): catWinFlag = True for catMove in graph[cat]: if catMove != 0 and not cat_visited[catMove] and not self.isCatWin(graph, mouseMove, catMove, cat_visited, cat_win_map): + # 如果老鼠无法获胜,则猫可以获胜 catWinFlag = False break + if not catWinFlag: + # 清理当前节点的访问标记 cat_visited[cat] = False cat_win_map[mouse][cat] = False return False + + # 更新状态表和访问记录 cat_visited[cat] = False cat_win_map[mouse][cat] = True - return True \ No newline at end of file + return True diff --git a/solutions/python3/914.py b/solutions/python3/914.py index 0555b09..e024cc8 100644 --- a/solutions/python3/914.py +++ b/solutions/python3/914.py @@ -1,7 +1,25 @@ + class Solution: + # 判断给定的牌组是否可以分成若干个大小相同的小组,且小组的大小大于等于2 + def hasGroupsSizeX(self, deck): + """ + :param deck: List[int] - 牌组列表 + :return: bool - 是否可以分成大小相同的小组 + + 1. 使用collections.Counter计算每个牌的数量 + 2. 对这些数量进行辗转相除法求最大公约数(GCD) + 3. 如果最大公约数不等于1,则说明可以分成若干个大小相同的小组,且小组的大小大于等于2 + """ + import functools - def gcd(a, b): - if not b: return a - return gcd(b, a % b) - return functools.reduce(gcd, collections.Counter(deck).values()) != 1 \ No newline at end of file + from collections import Counter + + # 计算每个牌的数量 + counts = Counter(deck).values() + + # 使用functools.reduce对所有数量求最大公约数 + gcd_value = functools.reduce(gcd, counts) + + # 检查是否可以分成大小相同的小组 + return gcd_value != 1 diff --git a/solutions/python3/915.py b/solutions/python3/915.py index c1697dc..e1e144e 100644 --- a/solutions/python3/915.py +++ b/solutions/python3/915.py @@ -1,12 +1,30 @@ + class Solution: - def partitionDisjoint(self, A): - rMin, lMax, mx, mn = [0] * len(A), [0] * len(A), -float("inf"), float("inf") + def partitionDisjoint(self, A: list[int]) -> int: + """ + 分区最小值问题:找到一个分区点,使得左边的最大值小于等于右边的最小值。 + + 参数: + A (list[int]): 输入整数列表 + + 返回: + int: 能满足条件的分区点索引(从1开始) + """ + + rMin, lMax = [0] * len(A), [0] * len(A) # 初始化左右最小和最大值数组 + mx, mn = -float("inf"), float("inf") # 初始化全局最大值和最小值 + + # 前向遍历,填充lMax数组,表示从左到i的最大值 for i, num in enumerate(A): mx = max(mx, num) lMax[i] = mx + + # 后向遍历,填充rMin数组,表示从i到右的最大值 for i in range(len(A) - 1, -1, -1): mn = min(mn, A[i]) rMin[i] = mn + + # 查找满足条件的分区点 for i in range(len(A) - 1): if lMax[i] <= rMin[i + 1]: - return i + 1 \ No newline at end of file + return i + 1 diff --git a/solutions/python3/916.py b/solutions/python3/916.py index eb3552c..4b0ecf3 100644 --- a/solutions/python3/916.py +++ b/solutions/python3/916.py @@ -1,12 +1,26 @@ + class Solution: + # 定义一个类,用于解决单词子集问题 + def wordSubsets(self, A: List[str], B: List[str]) -> List[str]: + # 创建一个计数器对象,用于记录B中所有字符的最大出现次数 cnt = collections.Counter() + for b in B: - for k, v in collections.Counter(b).items(): + # 对每个字符串b中的字符进行计数 + bc = collections.Counter(b) + + for k, v in bc.items(): + # 如果当前字符k在cnt中的值小于bc[k],则更新cnt中k的值为bc[k] if cnt[k] < v: cnt[k] = v + res = [] + # 遍历A中的每个字符串a for a in A: - if not cnt - collections.Counter(a): + # 检查cnt和当前字符串a组成的计数器之差是否为空,即a包含所有B中字符的最大出现次数 + if not (cnt - collections.Counter(a)): + # 如果满足条件,则将a添加到结果列表中 res.append(a) - return res \ No newline at end of file + + return res # 返回结果列表 diff --git a/solutions/python3/917.py b/solutions/python3/917.py index 10c7b94..df986d1 100644 --- a/solutions/python3/917.py +++ b/solutions/python3/917.py @@ -1,4 +1,16 @@ + class Solution: + # 1. 初始化解决方案类 + def reverseOnlyLetters(self, S): + """ + :type S: str + :rtype: str + # 2. 输入:字符串S;输出:经过处理的字符串 + """ + r = [s for s in S if s.isalpha()] - return "".join(S[i] if not S[i].isalpha() else r.pop() for i in range(len(S))) \ No newline at end of file + # 3. 使用列表推导式筛选出所有字母 + + return "".join(S[i] if not S[i].isalpha() else r.pop() for i in range(len(S))) + # 4. 遍历原字符串S,如果是非字母字符保持不变;若是字母则替换为r中的最后一个字母,并从r中移除该字母 diff --git a/solutions/python3/918.py b/solutions/python3/918.py index ba9cd12..cbcfaee 100644 --- a/solutions/python3/918.py +++ b/solutions/python3/918.py @@ -1,12 +1,21 @@ + class Solution: + # 定义一个类,用于解决带环的子数组最大和问题 + def maxSubarraySumCircular(self, A): + # 初始化最小左侧和、最大右侧和、结果值、当前左侧和、当前右侧和以及前缀和 lMn, rMx, res, lSm, rSm, preSm = float("inf"), [-float("inf")] * (len(A) + 1), -float("inf"), 0, 0, 0 + + # 计算从右向左的前缀和,并更新最大右侧和 for i in range(len(A) - 1, -1, -1): rSm += A[i] rMx[i] = max(rMx[i + 1], rSm) + + # 遍历数组,计算当前左侧和、最小左侧和,并更新结果值 for i in range(len(A)): preSm += A[i] lMn = min(lMn, lSm) res = max(res, preSm, preSm - lMn, preSm + rMx[i + 1]) lSm += A[i] - return res \ No newline at end of file + + return res diff --git a/solutions/python3/919.py b/solutions/python3/919.py index ab4bcbd..486cd4e 100644 --- a/solutions/python3/919.py +++ b/solutions/python3/919.py @@ -1,19 +1,26 @@ + class CBTInserter: + # 初始化,构建自底向上的完全二叉树表示 def __init__(self, root): - self.arr, q = [], [root] + from collections import deque + self.arr, q = [], deque([root]) while q: - self.arr += [node for node in q] - q = [child for node in q for child in (node.left, node.right) if child] + for node in q: + self.arr.append(node) + q.extend(child for node in q if (child := getattr(node, 'left', None) or getattr(node, 'right', None))) + # 插入节点,返回插入节点的父节点值 def insert(self, v): parent = self.arr[(len(self.arr) - 1) // 2] + child = TreeNode(v) if not len(self.arr) % 2: - child = parent.right = TreeNode(v) + parent.right = child else: - child = parent.left = TreeNode(v) - self.arr += [child] + parent.left = child + self.arr.append(child) return parent.val + # 获取根节点 def get_root(self): - return self.arr[0] \ No newline at end of file + return self.arr[0] diff --git a/solutions/python3/92.py b/solutions/python3/92.py index fe373e7..b474778 100644 --- a/solutions/python3/92.py +++ b/solutions/python3/92.py @@ -1,18 +1,35 @@ + class Solution: + # 定义一个辅助节点,用于在链表头部进行操作 def reverseBetween(self, head, m, n): + # 添加虚拟头节点方便处理边界情况 dummy_left, dummy_left.next, i = ListNode(0), head, 1 + prev = dummy_left while head: latter = head.next + + # 如果m和n相同,无需反转直接退出循环 if m == n: break + + # 当i等于m时记录反转起始节点及其前一个节点 if i == m: head_left, right = prev, head + + # 当i等于n时记录反转结束后的下一节点和当前节点作为结束点 if i == n: head_right, left = head.next, head - if m < i <= n: + + # 在m到n之间进行链表反转操作 + if m < i <= n: head.next = prev - prev, head, i = head, latter, i+1 + + # 更新指针位置,继续遍历下一个节点 + prev, head, i = head, latter, i + 1 + + # 如果区间存在则完成链表的连接 if m != n: head_left.next, right.next = left, head_right - return dummy_left.next \ No newline at end of file + + return dummy_left.next diff --git a/solutions/python3/920.py b/solutions/python3/920.py index c451993..f732759 100644 --- a/solutions/python3/920.py +++ b/solutions/python3/920.py @@ -1,7 +1,13 @@ + from functools import lru_cache class Solution: + # 定义一个求解音乐播放列表数量的函数 def numMusicPlaylists(self, N, L, K): + # 使用lru_cache缓存中间结果,提高性能 @lru_cache(None) - def dp(i, j): return +(j == 0) if not i else (dp(i-1, j-1) * (N-j+1) + dp(i-1, j) * max(j-K, 0)) % (10**9+7) - return dp(L, N) \ No newline at end of file + def dp(i, j): + # 当i为0且j不为0时返回0 + return 1 if not i else (dp(i-1, j-1) * (N-j+1) + dp(i-1, j) * max(j-K, 0)) % (10**9+7) + # 调用dp函数计算最终结果 + return dp(L, N) diff --git a/solutions/python3/921.py b/solutions/python3/921.py index 4af6b6a..8a6ea6e 100644 --- a/solutions/python3/921.py +++ b/solutions/python3/921.py @@ -1,11 +1,20 @@ + class Solution: + # 定义一个类来解决最小添加使括号有效的问题 + def minAddToMakeValid(self, S): + # r 记录需要添加的右括号数量,l 列表用来辅助匹配左括号和右括号 r, l = 0, [] + for s in S: if s == "(": + # 遇到左括号时将其入栈(列表) l.append(s) - elif l: + elif l: # 如果此时栈不为空,说明可以匹配一个右括号 l.pop() else: + # 栈为空且遇到右括号时,需要增加的右括号数量加一 r += 1 - return r + len(l) \ No newline at end of file + + # 最终返回需要添加的左右括号总数 + return r + len(l) diff --git a/solutions/python3/922.py b/solutions/python3/922.py index c9055e4..e5b9b5d 100644 --- a/solutions/python3/922.py +++ b/solutions/python3/922.py @@ -1,4 +1,11 @@ + class Solution: + # Python 方法:根据奇偶性对数组进行排序 + def sortArrayByParityII(self, A): - even, odd = [a for a in A if not a % 2], [a for a in A if a % 2] - return [even.pop() if not i % 2 else odd.pop() for i in range(len(A))] \ No newline at end of file + # 分离出偶数和奇数列表 + even = [a for a in A if not a % 2] + odd = [a for a in A if a % 2] + + # 根据索引的奇偶性,交替插入偶数和奇数 + return [even.pop() if i % 2 == 0 else odd.pop() for i in range(len(A))] diff --git a/solutions/python3/923.py b/solutions/python3/923.py index 94479ea..f390338 100644 --- a/solutions/python3/923.py +++ b/solutions/python3/923.py @@ -1,10 +1,28 @@ + +from collections import Counter +import itertools + class Solution: def threeSumMulti(self, A, target): - c = collections.Counter(A) + """ + :param A: List[int], 输入数组 + :param target: int, 目标和 + :return: int, 满足条件的三元组组合数 + + 使用计数器统计数组中每个元素的数量,通过组合计算满足目标和的三元组数量。 + """ + + c = Counter(A) res = 0 for i, j in itertools.combinations_with_replacement(c, 2): k = target - i - j - if i == j == k: res += c[i] * (c[i] - 1) * (c[i] - 2) // 6 - elif i == j != k: res += c[i] * (c[i] - 1) // 2 * c[k] - elif k > i and k > j: res += c[i] * c[j] * c[k] - return res % (10**9 + 7) \ No newline at end of file + if i == j == k: + # 三个相同的数,组合公式:C(n, 3) = n * (n-1) * (n-2) / 6 + res += c[i] * (c[i] - 1) * (c[i] - 2) // 6 + elif i == j != k: + # 两个相同的数,一个不同的数,组合公式:C(n, 2) * n = n * (n-1) / 2 + res += c[i] * (c[i] - 1) // 2 * c[k] + elif k > i and k > j: + # 三个不同且大于i和j的数,直接组合 + res += c[i] * c[j] * c[k] + return res % (10**9 + 7) diff --git a/solutions/python3/924.py b/solutions/python3/924.py index ffd677b..0661d63 100644 --- a/solutions/python3/924.py +++ b/solutions/python3/924.py @@ -1,14 +1,32 @@ + class Solution: + # 定义一个解题类 + def minMalwareSpread(self, graph, initial): + """ + :param graph: 二维列表,表示图的连接关系 + :param initial: 列表,初始被感染节点的集合 + :return: 返回最小蔓延点,使得仅该节点被移除后能减少最多感染节点 + """ + def dfs(i): + # 深度优先搜索函数 nodes.add(i) for j in range(len(graph[i])): if graph[i][j] and j not in nodes: dfs(j) - rank, initial = collections.defaultdict(list), set(initial) - for node in sorted(initial): + + rank, initial_set = collections.defaultdict(list), set(initial) + # 初始化排名字典和初始感染节点集合 + + for node in sorted(initial_set): + # 遍历排序后的初始感染节点 nodes = set() dfs(node) - if nodes & initial == {node}: + # 对每个节点进行深度优先搜索并记录其连接节点集 + if nodes & initial_set == {node}: + # 检查当前节点是否是唯一的初始感染节点 rank[len(nodes)].append(node) - return rank[max(rank)][0] if rank else min(initial) \ No newline at end of file + + return rank[max(rank)][0] if rank else min(initial_set) + # 返回排名最高的唯一感染节点,或者如果没有满足条件的节点,则返回最小的初始感染节点 diff --git a/solutions/python3/925.py b/solutions/python3/925.py index 2ae4c13..5160608 100644 --- a/solutions/python3/925.py +++ b/solutions/python3/925.py @@ -1,9 +1,17 @@ + class Solution: - def isLongPressedName(self, name, typed): - pre, i = None, 0 + # 判断typed字符串是否为name的长按变形 + def isLongPressedName(self, name: str, typed: str) -> bool: + pre = None # 前一个字符 + i = 0 # name字符串索引 + for c in typed: + # 如果当前typed中的字符与name当前字符相同,更新前一个字符和i的位置 if i < len(name) and c == name[i]: pre, i = name[i], i + 1 + # 否则如果当前typed中的字符与pre不同,则返回False elif c != pre: return False - return i == len(name) \ No newline at end of file + + # 检查是否遍历完name字符串 + return i == len(name) diff --git a/solutions/python3/926.py b/solutions/python3/926.py index d79e1e4..51db225 100644 --- a/solutions/python3/926.py +++ b/solutions/python3/926.py @@ -1,5 +1,13 @@ + class Solution: - def minFlipsMonoIncr(self, s): + # 定义一个类用于解决最小翻转单调递增字符串问题 + + def minFlipsMonoIncr(self, s: str) -> int: + # 初始化结果变量res和当前零的数量cur为s中"0"的个数 res = cur = s.count("0") - for c in s: res, cur = c == "1" and (res, cur + 1) or (min(res, cur - 1), cur - 1) - return res \ No newline at end of file + + for c in s: # 遍历字符串s中的每个字符c + # 根据当前字符决定翻转后的最小值,更新res和cur + res, cur = (res, cur + 1) if c == "1" else (min(res, cur - 1), cur - 1) + + return res # 返回最小翻转次数 diff --git a/solutions/python3/927.py b/solutions/python3/927.py index 62a9fb4..e54ee0a 100644 --- a/solutions/python3/927.py +++ b/solutions/python3/927.py @@ -1,11 +1,39 @@ + class Solution(object): def threeEqualParts(self, A): + """ + :param A: List[int] -- 输入数组A + :return: List[int] -- 返回两个分割点,使得分割后的三部分相等 + + 思路: + 1. 计算数组中1的总和sm + 2. 如果sm不能被3整除,则不可能分成三个相同的部分,返回[-1, -1] + 3. 否则,每个部分需要包含的1的数量为t = sm // 3 + 4. 特殊情况:如果t为0,说明数组全为0,直接返回[0, len(A) - 1] + 5. 寻找1的位置作为分割点breaks,并确定各部分起始和结束位置 + 6. 检查三部分是否相等,不等则返回[-1, -1] + 7. 最后判断分割点的有效性,无效则返回[-1, -1],否则计算并返回结果 + + 示例: + A = [0, 0, 1, 0, 0, 1, 0, 1] + 输出:[3, 6] + """ + sm = sum(A) - if sm % 3: return [-1, -1] + if sm % 3: + return [-1, -1] + t = sm // 3 - if not t: return [0, len(A) - 1] + if not t: + return [0, len(A) - 1] + breaks = [0] + [i for i, x in enumerate(A) if x] i1, j1, i2, j2, i3, j3 = breaks[1], breaks[t], breaks[t + 1], breaks[2 * t], breaks[2 * t + 1], breaks[3 * t] - if not (A[i1: j1 + 1] == A[i2: j2 + 1] == A[i3: j3 + 1]): return [-1, -1] - if i2 - j1 < len(A) - j3 or i3 - j2 < len(A) - j3: return [-1, -1] - return [j1 + len(A) - j3 - 1, j2+ len(A) - j3] \ No newline at end of file + + if not (A[i1: j1 + 1] == A[i2: j2 + 1] == A[i3: j3 + 1]): + return [-1, -1] + + if i2 - j1 < len(A) - j3 or i3 - j2 < len(A) - j3: + return [-1, -1] + + return [j1 + len(A) - j3 - 1, j2 + len(A) - j3] diff --git a/solutions/python3/928.py b/solutions/python3/928.py index 76a91bd..32f08af 100644 --- a/solutions/python3/928.py +++ b/solutions/python3/928.py @@ -1,13 +1,40 @@ + class Solution: def minMalwareSpread(self, graph, initial): + """ + 寻找最小化感染范围的初始节点 + + 参数: + graph:邻接矩阵表示的图结构 + initial:初始被感染节点列表 + + 返回值: + 最小化感染范围的初始节点 + """ + def dfs(i): + """ + 深度优先搜索查找与i相连且未访问过的节点 + + 参数: + i:当前节点索引 + + 返回值: + True或False,表示是否有新的连接且未被访问过 + """ seen.add(i) return not any(graph[i][j] and j not in seen and (j in initials or not dfs(j)) for j in range(len(graph[i]))) - res, mx, initials = min(initial), 1, set(initial) - for node in sorted(initial): - impact = set() - for j in range(len(graph[node])): - seen = {node} - if graph[node][j] and j not in initials and dfs(j): impact |= seen - if len(impact) > mx: res, mx = node, len(impact) - return res \ No newline at end of file + + res, mx, initials = min(initial), 1, set(initial) # 初始结果,最大影响节点数,初始感染节点集合 + for node in sorted(initial): # 遍历所有初始感染节点 + impact = set() # 影响节点集 + + for j in range(len(graph[node])): # 遍历当前节点的所有邻接节点 + seen = {node} # 当前访问集合初始化为当前节点 + if graph[node][j] and j not in initials and dfs(j): # 如果节点j满足条件,进行DFS并更新影响集 + impact |= seen + + if len(impact) > mx: # 更新结果 + res, mx = node, len(impact) + + return res diff --git a/solutions/python3/929.py b/solutions/python3/929.py index 6f15666..4a81fc2 100644 --- a/solutions/python3/929.py +++ b/solutions/python3/929.py @@ -1,8 +1,19 @@ + class Solution: def numUniqueEmails(self, emails: List[str]) -> int: - rec = set() + """ + 计算去重后的有效唯一邮箱数量 + + :param emails: 邮箱列表 + :return: 唯一有效邮箱的数量 + """ + rec = set() # 使用集合来存储唯一的有效邮箱地址 + for email in emails: - local, domain = email.split('@') - local = local.split('+')[0].replace('.', '') + local, domain = email.split('@') # 分割本地部分和域名部分 + local = local.split('+')[0].replace('.', '') # 移除'+'及其后的所有内容,并替换"."为空字符 + + # 构造处理后的有效邮箱地址并添加到集合中,利用set的唯一性自动去重 rec.add(local + '@' + domain) - return len(rec) \ No newline at end of file + + return len(rec) # 返回去重后邮箱的数量 diff --git a/solutions/python3/93.py b/solutions/python3/93.py index 5e4cc93..aa3977b 100644 --- a/solutions/python3/93.py +++ b/solutions/python3/93.py @@ -1,14 +1,32 @@ + class Solution: def restoreIpAddresses(self, s: str) -> List[str]: - if len(s) > 12: return [] - bfs = [(0, '')] + """ + 恢复给定字符串为有效的IP地址。 + + :param s: 输入的字符串形式的数字序列 + :type s: str + :return: 所有可能的有效IP地址列表 + :rtype: List[str] + """ + + if len(s) > 12: + return [] + + bfs = [(0, '')] # 初始状态,当前位置为0,路径为空字符串 + for c in s: new = [] c = int(c) for cur, st in bfs: + # 如果当前数字加上新字符后的值小于等于255 if cur * 10 + c <= 255 and (st[-1:] != '0' or cur): - new.append((cur * 10 + c, st + str(c))) + new.append((cur * 10 + c, st + str(c))) # 不加点的情况 + + # 如果路径已非空,添加分隔符 if st: - new.append((c, st + '.' + str(c))) - bfs = new - return [st for cur, st in bfs if st.count('.') == 3] \ No newline at end of file + new.append((c, st + '.' + str(c))) # 加上点的情况 + + bfs = new # 更新队列状态 + + return [st for cur, st in bfs if st.count('.') == 3] # 过滤出有效的IP地址(共4部分) diff --git a/solutions/python3/930.py b/solutions/python3/930.py index 3db6ca2..a6f8fdb 100644 --- a/solutions/python3/930.py +++ b/solutions/python3/930.py @@ -1,8 +1,25 @@ + class Solution: - def numSubarraysWithSum(self, A, S): + def numSubarraysWithSum(self, A: list[int], S: int) -> int: + """ + 计算数组中和为S的连续子数组的数量。 + + 参数: + A (list[int]): 输入整数列表。 + S (int): 目标和。 + + 返回值: + int: 和为S的连续子数组数量。 + """ + res, sm, sums = 0, 0, collections.defaultdict(int) + # 初始化结果计数器res、当前累积和sm以及使用字典存储累积和出现次数 for a in A: sm += a + # 每次累加当前元素a到累积和sm中 res += sums[sm - S] + (sm == S) + # 如果当前累积和等于目标S,直接计数;否则查找差值在字典中的出现次数并累计结果 sums[sm] += 1 - return res \ No newline at end of file + # 将当前累积和的出现次数加一记录到字典中 + return res + # 返回最终的结果计数器res diff --git a/solutions/python3/931.py b/solutions/python3/931.py index bd07b13..8839bb2 100644 --- a/solutions/python3/931.py +++ b/solutions/python3/931.py @@ -1,6 +1,16 @@ + class Solution: + # 定义一个类来解决问题 + def minFallingPathSum(self, A): + # 计算最小下降路径和 + for i in range(1, len(A)): + # 从第二行开始遍历,每一行的每个元素 for j in range(len(A)): - A[i][j] += min(A[i - 1][j and j - 1:j + 2]) - return min(A[-1]) \ No newline at end of file + # 遍历当前行的所有列 + + # 更新当前元素为上一行相邻元素中的最小值加上自身 + A[i][j] += min(A[i - 1][max(0, j - 1):j + 2]) + + return min(A[-1]) # 返回最后一行的最小值,即最终结果 diff --git a/solutions/python3/932.py b/solutions/python3/932.py index d1a2b18..bf69bc4 100644 --- a/solutions/python3/932.py +++ b/solutions/python3/932.py @@ -1,5 +1,18 @@ + class Solution: - def beautifulArray(self, N): - if N == 1: return [1] + # 定义一个类用于解决美丽数组问题 + + def beautifulArray(self, N: int) -> List[int]: + # 如果N为1,直接返回[1] + if N == 1: + return [1] + half = self.beautifulArray(N - N // 2) - return [i * 2 - 1 for i in half] + [i * 2 for i in half if i * 2 <= N] \ No newline at end of file + # 递归生成前半部分美丽数组 + even_half = [i * 2 for i in half if i * 2 <= N] + # 生成偶数序列,确保所有元素不超过N + odd_half = [i * 2 - 1 for i in half] + # 生成奇数序列 + + return even_half + odd_half + # 将生成的偶数和奇数组合返回 diff --git a/solutions/python3/933.py b/solutions/python3/933.py index 9c3243d..5698fa8 100644 --- a/solutions/python3/933.py +++ b/solutions/python3/933.py @@ -1,10 +1,21 @@ + class RecentCounter: def __init__(self): - self.p = collections.deque() + """ + 初始化滑动窗口,使用双端队列存储ping的时间戳。 + :return: None + """ + from collections import deque + self.queue = deque() - def ping(self, t): - self.p.append(t) - while self.p[0] < t - 3000: - self.p.popleft() - return len(self.p) \ No newline at end of file + def ping(self, t: int) -> int: + """ + 添加一个新时间戳t,并移除超出3000毫秒范围的旧时间戳,返回当前窗口中的元素个数。 + :param t: 新的时间戳 + :return: 当前有效ping的数量 + """ + self.queue.append(t) + while self.queue[0] < t - 3000: + self.queue.popleft() + return len(self.queue) diff --git a/solutions/python3/934.py b/solutions/python3/934.py index 5694139..f929491 100644 --- a/solutions/python3/934.py +++ b/solutions/python3/934.py @@ -1,27 +1,32 @@ + class Solution: - def shortestBridge(self, A): - def dfs(i, j): - A[i][j] = -1 - q.append((i, j)) - for x, y in ((i - 1, j), (i + 1, j), (i, j - 1), (i, j + 1)): - if 0 <= x < n and 0 <= y < n and A[x][y] == 1: - dfs(x, y) - def first(): - for i in range(n): - for j in range(n): - if A[i][j]: - return i, j - n, step, q = len(A), 0, [] - dfs(*first()) - while True: - new = [] - for i, j in q: - for x, y in ((i - 1, j), (i + 1, j), (i, j - 1), (i, j + 1)): - if 0 <= x < n and 0 <= y < n: - if A[x][y] == 1: - return step - elif not A[x][y]: - A[x][y] = -1 - new.append((x, y)) - step += 1 - q = new \ No newline at end of file + # 定义深度优先搜索函数,用于标记陆地并将相邻的'1'加入队列 + def dfs(self, i: int, j: int): + A[i][j] = -1 + self.q.append((i, j)) + for x, y in ((i - 1, j), (i + 1, j), (i, j - 1), (i, j + 1)): + if 0 <= x < n and 0 <= y < n and A[x][y] == 1: + self.dfs(x, y) + + # 定义寻找第一个陆地的辅助函数 + def first(self): + for i in range(n): + for j in range(n): + if A[i][j]: + return i, j + + n, step, q = len(A), 0, [] # 初始化:岛屿个数、步数和队列 + self.dfs(*self.first()) # 从第一个陆地开始深度优先搜索 + + while True: + new = [] + for i, j in self.q: # 遍历当前层的每个位置 + for x, y in ((i - 1, j), (i + 1, j), (i, j - 1), (i, j + 1)): # 检查相邻的位置 + if 0 <= x < n and 0 <= y < n: + if A[x][y] == 1: # 找到另一个岛屿,直接返回步数 + return self.step + elif not A[x][y]: # 将未访问过的陆地标记为已访问并加入下一层队列 + A[x][y] = -1 + new.append((x, y)) + self.step += 1 # 更新步数 + self.q = new # 更新当前层的队列为下一层的队列 diff --git a/solutions/python3/935.py b/solutions/python3/935.py index d79ae06..b256d84 100644 --- a/solutions/python3/935.py +++ b/solutions/python3/935.py @@ -1,10 +1,20 @@ + class Solution: def knightDialer(self, N): + """ + :type N: int + :rtype: int + """ + # 初始化各个位置的计数器 x1 = x2 = x3 = x4 = x5 = x6 = x7 = x8 = x9 = x0 = 1 + for _ in range(N - 1): - x1, x2, x3, x4, x5, x6, x7, x8, x9, x0 = \u005C - x6 + x8, x7 + x9, x4 + x8, \u005C - x7 + x9 + x0, 0, x1 + x7 + x0, \u005C - x2 + x6, x1 + x7, x2 + x4, \u005C - x4 + x6 - return (x1 + x2 + x3 + x4 + x5 + x6 + x7 + x8 + x9 + x0) % (10 ** 9 + 7) \ No newline at end of file + # 更新各个位置的计数器值 + x1, x2, x3, x4, x5, x6, x7, x8, x9, x0 = \ + (x6 + x8), (x7 + x9), (x4 + x8), \ + (x7 + x9 + x0), 0, (x1 + x7 + x0), \ + (x2 + x6), (x1 + x7), (x2 + x4), \ + (x4 + x6) + + # 返回结果模数 + return (x1 + x2 + x3 + x4 + x5 + x6 + x7 + x8 + x9 + x0) % (10 ** 9 + 7) diff --git a/solutions/python3/936.py b/solutions/python3/936.py index d741276..a89a68c 100644 --- a/solutions/python3/936.py +++ b/solutions/python3/936.py @@ -1,20 +1,42 @@ + class Solution: def movesToStamp(self, stamp, target): + """ + 判断当前字符串是否可以通过stamp匹配,如果可以返回True,否则False。 + :param s: 当前子串 + :return: 匹配结果 + 英文注释:Check if the current substring can be matched by the stamp. Return True if it matches, False otherwise. + """ def okay(s): ret = False for c1, c2 in zip(s, stamp): - if c1 == "*": continue - elif c1 != c2: return False - else: ret = True + if c1 == "*": continue # 如果当前字符为'*',则跳过检查 + elif c1 != c2: return False # 不匹配直接返回False + else: ret = True # 匹配设置ret为True return ret - t, move, mx, arr = "*" * len(target), 0, 10 * len(target), [] + + t, move, mx, arr = "*" * len(target), 0, 10 * len(target), [] # 初始化变量 + """ + t: target的掩码版本,用于比较判断是否完全匹配 + move: 记录当前操作次数 + mx: 最大尝试次数限制 + arr: 存储成功匹配的位置索引 + + 英文注释:t: the masked version of target used for comparison and judgment, + move: record the current number of operations, + mx: maximum trial times limit, + arr: store successful match position indexes. + """ + while move < mx: - pre = move + pre = move # 记录上一次匹配次数 for i in range(len(target) - len(stamp) + 1): - if okay(target[i:i + len(stamp)]): + if okay(target[i:i + len(stamp)]): # 尝试匹配stamp move += 1 - arr = [i] + arr - target = target[:i] + "*" * len(stamp) + target[i + len(stamp):] - if target == t: return arr - if move == pre: break - return [] \ No newline at end of file + arr = [i] + arr # 成功则记录位置并反转添加到结果数组中 + target = target[:i] + "*" * len(stamp) + target[i + len(stamp):] # 更新target状态 + + if target == t: return arr # 如果完全匹配,返回结果 + if move == pre: break # 连续无匹配则跳出循环 + + return [] # 返回空列表表示无法完成匹配 diff --git a/solutions/python3/937.py b/solutions/python3/937.py index eab2539..99d822a 100644 --- a/solutions/python3/937.py +++ b/solutions/python3/937.py @@ -1,3 +1,28 @@ + class Solution: + # 定义一个用于重新排列日志文件的方法 def reorderLogFiles(self, logs): - return sorted(filter(lambda l: l[l.find(" ") + 1].isalpha(), logs), key = lambda x: (x[x.find(" "):], x[:x.find(" ")])) + list(filter(lambda l: l[l.find(" ") + 1].isdigit(), logs)) \ No newline at end of file + """ + :param logs: 列表,包含字符串形式的日志信息 + :return: 排列后的日志列表 + + 1. 过滤出以字母开头的行 (letter-logs) + 2. 对这些行按照 " " 后面的内容和前面的部分排序 + 3. 然后过滤出以数字开头的行 (digit-logs) + 4. 最后将两个结果合并 + + 示例: + 输入: ["dig1 8 1 5 1", "let1 art can", "dig2 3 6", "let2 own kit dig", "let3 art zero"] + 输出: ["let1 art can", "let3 art zero", "let2 own kit dig", "dig1 8 1 5 1", "dig2 3 6"] + + """ + # 过滤出以字母开头的行 + letter_logs = filter(lambda l: l[l.find(" ") + 1].isalpha(), logs) + # 对这些行按照 " " 后面的内容和前面的部分排序 + sorted_letter_logs = sorted(letter_logs, key=lambda x: (x[x.find(" "):], x[:x.find(" ")])) + + # 过滤出以数字开头的行 + digit_logs = filter(lambda l: l[l.find(" ") + 1].isdigit(), logs) + + # 合并两个结果列表 + return sorted_letter_logs + list(digit_logs) diff --git a/solutions/python3/938.py b/solutions/python3/938.py index 139dc35..1af0775 100644 --- a/solutions/python3/938.py +++ b/solutions/python3/938.py @@ -1,6 +1,15 @@ + class Solution: + # 中文:定义一个方法,用于计算二叉搜索树中值在[L, R]范围内的节点和 + # 英文: Define a method to calculate the sum of node values within range [L, R] in a Binary Search Tree (BST) + def rangeSumBST(self, root, L, R): - if not root: return 0 - l = self.rangeSumBST(root.left, L, R) - r = self.rangeSumBST(root.right, L, R) - return l + r + (L <= root.val <= R) * root.val \ No newline at end of file + if not root: # 中文:如果根节点为空,返回0;英文: If the root is None, return 0 + return 0 + + l = self.rangeSumBST(root.left, L, R) # 中文:递归计算左子树范围内的节点和;英文: Recursively calculate the sum of nodes within range in the left subtree + r = self.rangeSumBST(root.right, L, R) # 中文:递归计算右子树范围内的节点和;英文: Recursively calculate the sum of nodes within range in the right subtree + + # 中文:判断当前节点值是否在[L, R]范围内,如果在,则累加当前节点值到结果中 + # 英文: Check if the current node's value is within [L, R], if yes, add its value to the result + return l + r + (L <= root.val <= R) * root.val diff --git a/solutions/python3/939.py b/solutions/python3/939.py index c47ee74..2a523dd 100644 --- a/solutions/python3/939.py +++ b/solutions/python3/939.py @@ -1,12 +1,40 @@ + class Solution: + """ + 解决最小矩形面积问题。 + + Class to solve the problem of finding the minimum area of a rectangle. + """ + def minAreaRect(self, points): + """ + 计算给定点集合中最小的矩形面积。 + + Calculate the minimum area of a rectangle from the given set of points. + + :param points: 列表,包含点集 (x, y)。 + :type points: List[List[int]] + :return: 最小矩形面积 + :rtype: int + """ seen, bases, baseX, res = collections.defaultdict(dict), [], -1, float("inf") + + # 对 x 坐标进行排序,便于后续处理 for x, y in sorted(points): if x != baseX: + # 更新 baseX 并清空 bases 列表 baseX, bases = x, [] + + # 遍历当前横坐标下的所有基线 for base in bases: + # 如果存在 y 值相同的点,则计算矩形面积并更新最小值 if y in seen[base]: res = min(res, (x - seen[base][y]) * (y - base)) + + # 记录当前 x 坐标下的基线 y 值 seen[base][y] = x + + # 将当前 y 值添加到 bases 列表中,用于后续比较 bases.append(y) - return res if res < float("inf") else 0 \ No newline at end of file + + return res if res < float("inf") else 0 diff --git a/solutions/python3/94.py b/solutions/python3/94.py index 9220d53..bc578f7 100644 --- a/solutions/python3/94.py +++ b/solutions/python3/94.py @@ -1,17 +1,25 @@ + # Definition for a binary tree node. -# class TreeNode: -# def __init__(self, x): -# self.val = x -# self.left = None -# self.right = None +class TreeNode: + def __init__(self, x): + self.val = x + self.left = None + self.right = None class Solution: + # 中文: 实现二叉树的中序遍历 + # 英文: Implement in-order traversal of a binary tree def inorderTraversal(self, root: TreeNode) -> List[int]: self.res = [] + + # 中文: 深度优先搜索函数,用于递归遍历节点 + # 英文: Depth-first search function for recursive node traversal def dfs(node): - if not node: return + if not node: + return dfs(node.left) self.res.append(node.val) dfs(node.right) + dfs(root) - return self.res \ No newline at end of file + return self.res diff --git a/solutions/python3/940.py b/solutions/python3/940.py index 7bf2119..78f3f6e 100644 --- a/solutions/python3/940.py +++ b/solutions/python3/940.py @@ -1,6 +1,17 @@ + class Solution: - def distinctSubseqII(self, S): - res, end = 0, collections.Counter() + def distinctSubseqII(self, S: str) -> int: + """ + 计算字符串S中所有不同子序列的个数,结果对10^9 + 7取模。 + + Args: + S (str): 输入字符串 + + Returns: + int: 不同子序列的个数 + """ + res, end = 0, collections.Counter() # 初始化结果和记录每个字符最后出现位置的计数器 for c in S: - res, end[c] = res * 2 + 1 - end[c], res + 1 - return res % (10**9 + 7) \ No newline at end of file + # 更新结果:当前字符的新子序列数量等于之前的结果翻倍加一减去该字符上次出现时的结果 + res, end[c] = (res * 2 + 1 - end[c]) % (10**9 + 7), res + 1 # 取模操作确保结果在int范围内 + return res % (10**9 + 7) # 返回最终结果取模后的值 diff --git a/solutions/python3/941.py b/solutions/python3/941.py index 4ea2cc9..b668ca8 100644 --- a/solutions/python3/941.py +++ b/solutions/python3/941.py @@ -1,4 +1,11 @@ + class Solution: + # 检查给定的数组是否为有效的山脉数组 def validMountainArray(self, A): - i = A and A.index(max(A)) - return A and 0a3 for a2,a3 in zip(A[i:],A[i+1:])) or False \ No newline at end of file + i = A and A.index(max(A)) # 找到数组中的最大值索引 + + # 如果数组为空或只有一个元素,或者最大值在边界上,则不是有效山脉数组 + return (A and + 0 < i < len(A) - 1 and # 确保最大值不在边界且索引大于0和小于数组长度-1 + all(a1 < a2 for a1, a2 in zip(A[:i], A[1:i+1])) and # 升序检查前半段 + all(a2 > a3 for a2, a3 in zip(A[i:], A[i+1:])) or False) # 降序检查后半段 diff --git a/solutions/python3/942.py b/solutions/python3/942.py index 7448d87..7c36b63 100644 --- a/solutions/python3/942.py +++ b/solutions/python3/942.py @@ -1,7 +1,12 @@ + class Solution: + # 解决数字序列匹配问题,输入字符串S由'I'和'D'组成 + # 'I'表示当前数比前一个数大,'D'表示当前数比前一个数小 + def diStringMatch(self, S): - l, r, arr = 0, len(S), [] + l, r, arr = 0, len(S), [] # 初始化左指针l为0,右指针r为S的长度,结果数组arr为空 for s in S: + # 如果字符是'I',则当前数比前一个数大,将其加入结果数组;否则将当前数设置为较小值 arr.append(l if s == "I" else r) - l, r = l + (s == "I"), r - (s == "D") - return arr + [l] \ No newline at end of file + l, r = l + (s == "I"), r - (s == "D") # 更新指针位置 + return arr + [l] # 最后一个数字直接添加到结果数组尾部 diff --git a/solutions/python3/943.py b/solutions/python3/943.py index a552d1a..6a469b0 100644 --- a/solutions/python3/943.py +++ b/solutions/python3/943.py @@ -1,31 +1,59 @@ + class Solution: + # 寻找最短超级字符串 def shortestSuperstring(self, A): + """ + :param A: 字符串列表 + :return: 最短的包含所有给定字符串的超级字符串 + """ + def merge(a, b): + """ + 将两个字符串合并,返回最大前缀重叠长度及剩余部分 + :param a: 首个字符串 + :param b: 后一个字符串 + :return: 最大前缀重叠长度和剩余部分组成的元组 + """ for i in range(len(b), 0, -1): if a.endswith(b[:i]): - return i - return 0 + return i, b[i:] + return 0, '' + def dfs(sup, s, st): + """ + 深度优先搜索,用于寻找最短超级字符串 + :param sup: 当前构建的超级字符串部分 + :param s: 当前处理的字符串 + :param st: 剩余未使用字符串集合 + """ if len(sup + "".join(st)) < len(res[0]): res[0] = sup + "".join(st) + + # 检查是否可以合并,继续搜索 if st and any(new in st for new in merged[s][1:]): for new in merged[s][1:]: if new in st: dfs(sup + new[merged[s][0]:], new, st - {new}) else: + # 逐个尝试剩余字符串进行合并 for nex in st: for new in merged[nex][1:]: if new in st: dfs(sup + nex + new[merged[nex][0]:], new, st - {nex, new}) + + # 计算两个字符串的最大重叠前缀长度和剩余部分 merged = {} for a, b in itertools.combinations(A, 2): for a, b in ((a, b), (b, a)): s = merge(a, b) - if a not in merged or s > merged[a][0]: - merged[a] = [s, b] - elif s == merged[a][0]: + if a not in merged or s[0] > merged[a][0]: + merged[a] = [s[0], s[1]] + elif s[0] == merged[a][0]: merged[a].append(b) + + # 初始化结果集和剩余字符串集合 res, st = ["".join(A)], set(A) for a in A: dfs(a, a, st - {a}) - return res[0] \ No newline at end of file + + return res[0] diff --git a/solutions/python3/944.py b/solutions/python3/944.py index bd687a8..635ee52 100644 --- a/solutions/python3/944.py +++ b/solutions/python3/944.py @@ -1,3 +1,6 @@ + class Solution: + # 定义一个方法来计算需要删除的最小列数,使得剩余的矩阵按行单调递增 def minDeletionSize(self, A): - return sum(any(a[j] > b[j] for a, b in zip(A, A[1:])) for j in range(len(A[0]))) \ No newline at end of file + # 计算所有列中存在非递增情况的数量 + return sum(any(a[j] > b[j] for a, b in zip(A, A[1:])) for j in range(len(A[0]))) diff --git a/solutions/python3/945.py b/solutions/python3/945.py index 637e3f3..a4fc19d 100644 --- a/solutions/python3/945.py +++ b/solutions/python3/945.py @@ -1,5 +1,22 @@ + class Solution: + # 定义一个类来解决最小增量问题 + def minIncrementForUnique(self, A): + """ + :param A: 列表,包含非负整数 + :return: 将列表转换为唯一值所需的最小操作次数 + + 算法思路: + 1. 使用两个集合 st 和 used 分别存储原始数组和已使用过的数字。 + 2. 使用 heapq.heapify() 初始化堆 A。 + 3. 创建一个空列表 empty,用于存放尚未被使用的最小整数。 + 4. 当堆 A 不为空时,执行以下操作: + - 弹出堆顶元素 num + - 如果 num 已经在 used 中,则从 empty 列表中找到可以填补的位置,并将所需的操作次数累加到 move 变量中。 + - 将调整后的数重新推入堆 A。 + 5. 返回操作次数 move 作为最终结果。 + """ st, used, move = set(A), set(), 0 heapq.heapify(A) empty = [i for i in range(80000) if i not in st][::-1] if A else [] @@ -12,4 +29,4 @@ def minIncrementForUnique(self, A): empty.pop() move += empty[-1] - num heapq.heappush(A, empty.pop()) - return move \ No newline at end of file + return move diff --git a/solutions/python3/946.py b/solutions/python3/946.py index 08e5a7f..70d78b8 100644 --- a/solutions/python3/946.py +++ b/solutions/python3/946.py @@ -1,14 +1,21 @@ + class Solution: def validateStackSequences(self, pushed, popped): """ :type pushed: List[int] :type popped: List[int] :rtype: bool + + 输入两个列表,验证pushed序列是否可以通过栈操作按顺序得到popped序列。 + - 使用一个辅助数组arr模拟栈 + - i指针用于跟踪popped中当前需要匹配的元素 """ arr, i = [], 0 for num in pushed: arr.append(num) + # 当前栈顶与popped[i]相等时,出栈并i++ while arr and arr[-1] == popped[i]: i += 1 arr.pop() - return arr == popped[i:][::-1] \ No newline at end of file + # 最终检查arr剩余元素是否能逆序匹配popped + return arr == popped[i:][::-1] diff --git a/solutions/python3/947.py b/solutions/python3/947.py index 258a934..9a709be 100644 --- a/solutions/python3/947.py +++ b/solutions/python3/947.py @@ -1,6 +1,24 @@ + class Solution: def removeStones(self, stones): + """ + 移除石子问题:计算能够通过移除最少数量的石子,使剩余石子分布在多个独立岛上的数量。 + + Args: + stones (List[Tuple[int, int]]): 石子的位置列表 + + Returns: + int: 需要移除的最小石子数 + """ + def dfs(i, j): + """ + 深度优先搜索遍历当前岛屿的所有连通石子。 + + Args: + i (int): 当前行号 + j (int): 当前列号 + """ points.discard((i, j)) for y in rows[i]: if (i, y) in points: @@ -8,12 +26,19 @@ def dfs(i, j): for x in cols[j]: if (x, j) in points: dfs(x, j) + + # 初始化数据结构 points, island, rows, cols = {(i, j) for i, j in stones}, 0, collections.defaultdict(list), collections.defaultdict(list) + + # 构建行和列的索引 for i, j in stones: rows[i].append(j) cols[j].append(i) + + # 遍历石子进行DFS,计算独立岛的数量 for i, j in stones: if (i, j) in points: dfs(i, j) island += 1 - return len(stones) - island \ No newline at end of file + + return len(stones) - island diff --git a/solutions/python3/948.py b/solutions/python3/948.py index 0de5a9b..d1ba2fd 100644 --- a/solutions/python3/948.py +++ b/solutions/python3/948.py @@ -1,21 +1,28 @@ + class Solution: - def bagOfTokensScore(self, tokens, P): + def bagOfTokensScore(self, tokens: list[int], P: int) -> int: """ - :type tokens: List[int] - :type P: int - :rtype: int + :type tokens: List[int] # 令牌列表 + :type P: int # 玩家当前得分 + :rtype: int # 最大分数 + + 思路:对令牌进行排序,优先使用较小的令牌来增加分数,遇到无法使用的较大令牌时, + 尽量通过之前获得的分数减去一个较大的令牌来继续游戏。 """ - tokens.sort() - l, r, score = 0, len(tokens) - 1, 0 + tokens.sort() # 对令牌列表进行升序排序 + l, r, score = 0, len(tokens) - 1, 0 # 初始化双指针和得分 + while l <= r: - if P >= tokens[l]: - P -= tokens[l] - score += 1 - l += 1 - elif score and l != r: - P += tokens[r] - score -= 1 - r -= 1 + if P >= tokens[l]: # 当前得分足够使用最小的令牌时 + P -= tokens[l] # 使用该令牌,减少当前得分 + score += 1 # 增加分数 + l += 1 # 移动左指针 + elif score and l != r: # 分数充足且左右指针未相遇 + P += tokens[r] # 使用最大的令牌增加当前得分 + score -= 1 # 减少分数 + r -= 1 # 移动右指针 else: - break - return score \ No newline at end of file + break # 无法继续游戏,退出循环 + + return score # 返回最大分数 + \ No newline at end of file diff --git a/solutions/python3/949.py b/solutions/python3/949.py index 833007d..3823e86 100644 --- a/solutions/python3/949.py +++ b/solutions/python3/949.py @@ -1,10 +1,25 @@ + +import itertools + +# 中文注释:定义一个类,用于寻找给定数字组成的最大时间 class Solution: + # 英文注释: Define a class to find the largest time from given digits def largestTimeFromDigits(self, A): - h = m = -float("inf") + h = m = -float("inf") # 初始化最大小时和分钟为负无穷 + + # 中文注释:遍历所有可能的排列组合 + # 英文注释: Traverse all possible permutations of the input list A for n1, n2, n3, n4 in itertools.permutations(A): - hh, mm = n1 * 10 + n2, n3 * 10 + n4 + hh, mm = n1 * 10 + n2, n3 * 10 + n4 # 组合成小时和分钟 + + # 中文注释:检查组合是否合法,更新最大时间 + # 英文注释: Check if the combination is valid and update the maximum time if 0 <= hh <= 23 and 0 <= mm <= 59 and (hh > h or hh == h and mm > m): h, m = hh, mm - sh = str(h) if h > 9 else "0" + str(h) - sm = str(m) if m > 9 else "0" + str(m) - return 0 <= h <= 23 and 0 <= m <= 59 and sh + ":" + sm or "" \ No newline at end of file + + sh = str(h) if h > 9 else "0" + str(h) # 处理小时格式 + sm = str(m) if m > 9 else "0" + str(m) # 处理分钟格式 + + # 中文注释:返回合法的最大时间,否则返回空字符串 + # 英文注释: Return the valid maximum time or an empty string if none is found + return sh + ":" + sm if 0 <= h <= 23 and 0 <= m <= 59 else "" diff --git a/solutions/python3/95.py b/solutions/python3/95.py index f8f11bd..b170f88 100644 --- a/solutions/python3/95.py +++ b/solutions/python3/95.py @@ -1,24 +1,34 @@ + # Definition for a binary tree node. -# class TreeNode: -# def __init__(self, x): -# self.val = x -# self.left = None -# self.right = None +class TreeNode: + def __init__(self, x): + self.val = x + self.left = None + self.right = None class Solution: + # 生成1到n的二叉搜索树 def generateTrees(self, n: int) -> List[TreeNode]: + # 深度优先搜索,构造以m为根节点的子树 def dfs(l, r): - if r < l: return [None] + if r < l: + return [None] # 边界条件:空节点 + arr = [] - for m in range(l, r + 1): - left = dfs(l, m - 1) - right = dfs(m + 1, r) + for m in range(l, r + 1): # 枚举每一个可能的根节点值 + left = dfs(l, m - 1) # 左子树的所有情况 + right = dfs(m + 1, r) # 右子树的所有情况 + for lNode in left: - for rNode in right: - new = TreeNode(m) - new.left = lNode - new.right = rNode - arr.append(new) + for rNode in right: + new_tree = TreeNode(m) # 构造新的根节点 + new_tree.left = lNode # 左子树连接到新节点 + new_tree.right = rNode # 右子树连接到新节点 + + arr.append(new_tree) # 收集所有可能的树结构 return arr - res = dfs(1, n) - return [] if res == [None] else res \ No newline at end of file + + result = dfs(1, n) + + # 如果结果中只有一个空节点,返回空列表;否则返回所有的树结构 + return [] if result == [None] else result diff --git a/solutions/python3/950.py b/solutions/python3/950.py index 7d8db74..51f3890 100644 --- a/solutions/python3/950.py +++ b/solutions/python3/950.py @@ -1,7 +1,17 @@ + class Solution: + # 定义一个方法来模拟逐步揭示升序排列的牌 def deckRevealedIncreasing(self, deck): + # 创建指示器列表,记录当前待揭示的牌的位置 ind = list(range(len(deck))) + + # 对输入的deck进行排序 for num in sorted(deck): + # 将当前数字放置在指示器列表的第一个位置 deck[ind[0]] = num - ind = ind[2:] + [ind[1]] if len(ind) > 1 else [] - return deck \ No newline at end of file + + # 更新指示器列表:移除第一个元素,并将第二个元素移动到末尾 + if len(ind) > 1: + ind = ind[2:] + [ind[1]] + + return deck diff --git a/solutions/python3/951.py b/solutions/python3/951.py index dec478f..117d8d9 100644 --- a/solutions/python3/951.py +++ b/solutions/python3/951.py @@ -1,6 +1,17 @@ + class Solution: + # 解决方案类 + def flipEquiv(self, root1, root2): - if not root1 or not root2: return root1 == root2 - if root1.left and root2.left and root1.left.val != root2.left.val or (not root1.left and root2.left) or (root1.left and not root2.left): + # 如果其中一个节点为空,检查两个节点是否同时为空 + if not root1 or not root2: + return root1 == root2 + + # 检查左右子节点的值是否相等或不一致的情况 + if (root1.left and root2.left and root1.left.val != root2.left.val) \ + or (not root1.left and root2.left) or (root1.left and not root2.left): + # 如果不匹配,交换root1的左右子节点 root1.left, root1.right = root1.right, root1.left - return root1.val == root2.val and self.flipEquiv(root1.left, root2.left) and self.flipEquiv(root1.right, root2.right) \ No newline at end of file + + # 递归检查当前节点及其子树是否翻转等价 + return root1.val == root2.val and self.flipEquiv(root1.left, root2.left) and self.flipEquiv(root1.right, root2.right) diff --git a/solutions/python3/952.py b/solutions/python3/952.py index 3324614..35a85ad 100644 --- a/solutions/python3/952.py +++ b/solutions/python3/952.py @@ -1,9 +1,23 @@ + class Solution: def largestComponentSize(self, A): + """ + 初始化并查集和质因数映射字典。 + :param A: 非空整数数组,表示集合中的元素。 + """ + def find(i): + """ + 查找元素i的根节点,并进行路径压缩。 + :param i: 从0开始的索引 + """ return i if i == parent[i] else find(parent[i]) - + def prime_factors(n): + """ + 获取n的所有质因数(重复的不重复添加)。 + :param n: 需要分解质因数的整数 + """ res = set() while n % 2 == 0: res.add(2) @@ -15,12 +29,17 @@ def prime_factors(n): if n > 2: res.add(n) return res + parent, dic = list(range(len(A))), {} + # 将每个元素与其质因数进行关联,并通过并查集将具有相同质因数的元素连通 for i, n in enumerate(A): for p in prime_factors(n): if p in dic: parent[find(i)] = find(dic[p]) dic[p] = i + + # 最终计算每个联通分量的大小,并返回最大的连通分量的大小。 for i, x in enumerate(parent): parent[i] = find(x) - return max(collections.Counter(parent).values()) \ No newline at end of file + + return max(collections.Counter(parent).values()) diff --git a/solutions/python3/953.py b/solutions/python3/953.py index 09698cc..1bdcafa 100644 --- a/solutions/python3/953.py +++ b/solutions/python3/953.py @@ -1,19 +1,30 @@ -class Solution: + class Solution: def isAlienSorted(self, words, order): """ :type words: List[str] :type order: str :rtype: bool """ + # 创建一个字典,用于快速查找字符在新排序规则中的位置 ind = {c: i for i, c in enumerate(order)} + + # 遍历相邻的单词对 for a, b in zip(words, words[1:]): + # 检查较短单词是否为较长单词的前缀,如果是,则顺序错误 if len(a) > len(b) and a[:len(b)] == b: return False + + # 遍历两个单词对应的字符 for s1, s2 in zip(a, b): + # 如果当前字符在新排序规则中的位置小于另一个,说明已找到正确顺序,跳出循环 if ind[s1] < ind[s2]: break + # 若相等,则继续检查下一个字符 elif ind[s1] == ind[s2]: continue - else: + # 否则,顺序错误 + else: return False + + # 如果所有单词都符合新排序规则,则返回 True return True \ No newline at end of file diff --git a/solutions/python3/954.py b/solutions/python3/954.py index 46d3741..985bce3 100644 --- a/solutions/python3/954.py +++ b/solutions/python3/954.py @@ -1,11 +1,20 @@ + class Solution: + # 定义一个类来解决重排问题 + def canReorderDoubled(self, A): - cnt = collections.Counter(A) - for a in sorted(A, key = abs): - if cnt[a] and cnt[a * 2]: - cnt[a] -= 1 - cnt[a * 2] -= 1 - elif cnt[a] and a % 2 == 0 and cnt[a // 2]: - cnt[a] -= 1 - cnt[a // 2] -= 1 - return all(cnt[a] == 0 for a in A) \ No newline at end of file + from collections import Counter + # 导入Counter工具,用于统计元素出现次数 + + cnt = Counter(A) + # 使用Counter统计输入列表A中每个数字的出现频率 + + for a in sorted(A, key=abs): # 按绝对值排序后遍历列表 + if cnt[a] and cnt[a * 2]: # 如果当前元素a及其两倍数存在且次数大于0 + cnt[a] -= 1 # 将计数减一,表示匹配成功一个目标数 + cnt[a * 2] -= 1 + elif cnt[a] and a % 2 == 0 and cnt[a // 2]: # 如果当前元素a是偶数且其一半存在且次数大于0 + cnt[a] -= 1 # 将计数减一,表示匹配成功一个目标数 + cnt[a // 2] -= 1 + # 遍历结束后检查所有元素是否都被匹配 + return all(cnt[a] == 0 for a in A) # 如果A中每个元素都恰好被匹配了一次,则返回True diff --git a/solutions/python3/955.py b/solutions/python3/955.py index 53e2e93..ac458b1 100644 --- a/solutions/python3/955.py +++ b/solutions/python3/955.py @@ -1,11 +1,19 @@ + class Solution: - def minDeletionSize(self, A): + # 定义一个类来解决问题 + + def minDeletionSize(self, A: List[str]) -> int: + # 初始化结果计数器和当前列的状态 res = 0 cur = [""] * len(A) + + # 遍历每一列(使用zip(*)对矩阵转置) for col in zip(*A): + # 将当前列状态与新的一行进行比较并排序后对比 cur2 = list(zip(cur, col)) - if cur2 == sorted(cur2): - cur = cur2 + if cur2 == sorted(cur2): # 如果保持顺序,则更新当前状态为排序后的结果,表明这一列不需要删除 + cur = [x[0] for x in sorted(cur2)] else: - res += 1 - return res \ No newline at end of file + res += 1 # 若不是有序的,则说明需要删除该列以满足条件 + + return res # 返回最终的结果计数 diff --git a/solutions/python3/956.py b/solutions/python3/956.py index 57fc69d..027fae7 100644 --- a/solutions/python3/956.py +++ b/solutions/python3/956.py @@ -1,8 +1,19 @@ + class Solution: def tallestBillboard(self, rods): + """ + :param rods: 列表,表示不同长度的钢筋(英文:List of integers representing the lengths of different rods) + :return: 返回可以构建的最大高度差(英文:Return the maximum possible height difference that can be achieved by selecting a subset of rods) + + 使用动态规划解决最大高度差问题。 + """ dp = {0: 0} for x in rods: - for d, h in list(dp.items()): - dp[d + x] = max(dp.get(x + d, 0), h) + # 创建一个dp的临时副本,避免在迭代过程中修改原字典 + temp_dp = dp.copy() + for d, h in temp_dp.items(): + # 更新以d+x为差异时的最大高度 + dp[d + x] = max(dp.get(d + x, 0), h) + # 计算并更新以abs(d-x)为差异时的高度,取两者中的较大值 dp[abs(d - x)] = max(dp.get(abs(d - x), 0), h + min(d, x)) - return dp[0] \ No newline at end of file + return dp[0] diff --git a/solutions/python3/957.py b/solutions/python3/957.py index e3cb285..5bf1102 100644 --- a/solutions/python3/957.py +++ b/solutions/python3/957.py @@ -1,11 +1,26 @@ + class Solution: def prisonAfterNDays(self, cells, N): + """ + 使用字典记录状态,并找到循环节以优化计算。 + + :param cells: 初始囚犯状态列表(字符串形式) + :param N: 天数 + :return: N天后的囚犯状态列表(整数形式) + """ + day, state, cur = 0, {}, "".join(map(str, cells)) + + # 记录当前状态及其对应天数,直到遇到重复状态 while cur not in state: state[cur] = day state[day] = cur if day == N: return list(map(int, cur)) day += 1 + + # 根据规则更新当天的囚犯状态 cur = "0" + "".join(cur[i - 1] == cur[i + 1] and "1" or "0" for i in range(1, len(cur) - 1)) + "0" - return list(map(int, state[state[cur] + (N - state[cur]) % (day - state[cur])])) \ No newline at end of file + + # 计算实际需要计算的天数,并返回结果 + return list(map(int, state[state[cur] + (N - state[cur]) % (day - state[cur])])) diff --git a/solutions/python3/958.py b/solutions/python3/958.py index 6adbf93..4cdc304 100644 --- a/solutions/python3/958.py +++ b/solutions/python3/958.py @@ -1,10 +1,18 @@ + class Solution: + # 检查给定的二叉树是否为完全二叉树 def isCompleteTree(self, root): + # 使用队列进行层次遍历,同时标记节点结束位置 q, pre = [root, None], 1 - while any(q): - i = q.index(None) - if any(q[i:]) or pre > 1: + + while any(q): # 遍历队列中的所有元素直到为空 + i = q.index(None) # 找到第一个None的位置 + + if any(q[i:]) or pre > 1: # 如果后面还有非空节点或之前标记了多个结束点,返回False return False - pre = len(q[i:]) - q = [child for node in q[:i] for child in (node.left, node.right)] + [None] - return True \ No newline at end of file + + pre = len(q[i:]) # 更新上一个None后的节点数 + + q = [child for node in q[:i] for child in (node.left, node.right)] + [None] # 展平子树并添加新的None标记 + + return True # 如果没有违反完全二叉树规则,返回True diff --git a/solutions/python3/959.py b/solutions/python3/959.py index d3917cd..d62463c 100644 --- a/solutions/python3/959.py +++ b/solutions/python3/959.py @@ -1,37 +1,65 @@ + class Solution: - def regionsBySlashes(self, grid): - def dfs(i, j, k): - if 0 <= i < n > j >= 0 and not matrix[i][j][k]: - if grid[i][j] == "*": - if k <= 1: - matrix[i][j][0] = matrix[i][j][1] = cnt + def regionsBySlashes(self, grid: list[str]) -> int: + """ + 计算由网格中的斜杠和空格划分的区域数量。 + + 参数: + grid:一个二维字符串列表,其中'\\'表示斜线,'/'表示反斜线,' '为空格。 + + 返回值: + 区域的数量。 + """ + + def dfs(i: int, j: int, k: int) -> None: + """ + 深度优先搜索函数。 + + 参数: + i:当前行索引 + j:当前列索引 + k:当前方向,0-左,1-右,2-下,3-上。 + """ + if 0 <= i < n and 0 <= j < n and not matrix[i][j][k]: + # 根据字符类型进行分支处理 + match grid[i][j]: + case '\\': + if k == 1 or k == 2: + matrix[i][j] = [cnt, cnt] + dfs(i, j + 1, 3) + dfs(i + 1, j, 0) + else: + matrix[i][j] = [cnt, cnt] + dfs(i - 1, j, 2) + dfs(i, j - 1, 1) + case '/': + if k == 0 or k == 3: + matrix[i][j] = [cnt, cnt] + dfs(i, j + 1, 3) + dfs(i + 1, j, 0) + else: + matrix[i][j] = [cnt, cnt] + dfs(i - 1, j, 2) + dfs(i, j - 1, 1) + case _: + matrix[i][j] = [cnt, cnt, cnt, cnt] dfs(i - 1, j, 2) dfs(i, j + 1, 3) - else: - matrix[i][j][2] = matrix[i][j][3] = cnt dfs(i + 1, j, 0) dfs(i, j - 1, 1) - elif grid[i][j] == "/": - if 1 <= k <= 2: - matrix[i][j][1] = matrix[i][j][2] = cnt - dfs(i, j + 1, 3) - dfs(i + 1, j, 0) - else: - matrix[i][j][0] = matrix[i][j][3] = cnt - dfs(i - 1, j, 2) - dfs(i, j - 1, 1) - else: - matrix[i][j][0] = matrix[i][j][1] = matrix[i][j][2] = matrix[i][j][3] = cnt - dfs(i - 1, j, 2) - dfs(i, j + 1, 3) - dfs(i + 1, j, 0) - dfs(i, j - 1, 1) - grid, n = [row.replace("\u005C\u005C", "*") for row in grid], len(grid) - matrix, cnt = [[[0, 0, 0, 0] for j in range(n)] for i in range(n)], 0 + + # 替换双反斜线为星号 + grid = [row.replace("\\\\", "*") for row in grid] + n = len(grid) + matrix = [[[0] * 4 for _ in range(n)] for _ in range(n)] + cnt = 0 + + # 初始化矩阵并进行DFS遍历 for i in range(n): for j in range(n): for k in range(4): if not matrix[i][j][k]: cnt += 1 dfs(i, j, k) - return cnt \ No newline at end of file + + return cnt diff --git a/solutions/python3/96.py b/solutions/python3/96.py index 7ee3bb8..4a0175e 100644 --- a/solutions/python3/96.py +++ b/solutions/python3/96.py @@ -1,10 +1,26 @@ + class Solution: - def numTrees(self, n): + def numTrees(self, n: int) -> int: + """ + 计算n个节点的二叉搜索树的数量。 + + 参数: + n (int): 节点数量 + + 返回: + int: 二叉搜索树的数量 + """ if n <= 1: return 1 + catalan = [0] * (n + 1) - catalan[0] = catalan[1] = 1 + # 初始化卡特兰数的前两个值 + catalan[0], catalan[1] = 1, 1 + for i in range(2, n + 1): for j in range(i): + # 计算第i个节点时的卡特兰数值 catalan[i] += catalan[j] * catalan[i - j - 1] - return catalan[n] \ No newline at end of file + + return catalan[n] + \ No newline at end of file diff --git a/solutions/python3/960.py b/solutions/python3/960.py index 32821b6..bf69e27 100644 --- a/solutions/python3/960.py +++ b/solutions/python3/960.py @@ -1,9 +1,20 @@ + class Solution: - def minDeletionSize(self, A): + # 定义一个类来解决最小删除列数问题 + + def minDeletionSize(self, A: list[str]) -> int: + # 初始化行数m和列数n,分别代表矩阵A的长度和每个子列表的长度 m, n = len(A), len(A[0]) + + # dp数组初始化为1,表示每个列至少需要删除0次才能满足条件 dp = [1] * n + + # 动态规划计算每一列是否可以通过前一列转换而来 for j in range(1, n): for i in range(j): if all(A[k][i] <= A[k][j] for k in range(m)): + # 如果当前列的值大于等于所有行中对应上一个列的值,则更新dp[j] dp[j] = max(dp[j], dp[i] + 1) - return n - max(dp) \ No newline at end of file + + # 返回需要删除的最小列数,即n减去可以保持递增的最长列数 + return n - max(dp) diff --git a/solutions/python3/961.py b/solutions/python3/961.py index 9f57660..50c065b 100644 --- a/solutions/python3/961.py +++ b/solutions/python3/961.py @@ -1,7 +1,13 @@ + class Solution: + # 定义一个类来解决重复N次的元素问题 + def repeatedNTimes(self, A): """ :type A: List[int] :rtype: int """ - return collections.Counter(A).most_common(1)[0][0] \ No newline at end of file + # 使用collections.Counter计算列表中每个元素出现的次数 + # 返回出现次数最多的那个元素,由于题目保证了一定存在一个重复的元素, + # 所以most_common(1)返回的是一个包含单个元组的列表,[0][0]取出这个元组的第一个值 + return collections.Counter(A).most_common(1)[0][0] diff --git a/solutions/python3/962.py b/solutions/python3/962.py index da37e95..42f62ca 100644 --- a/solutions/python3/962.py +++ b/solutions/python3/962.py @@ -1,14 +1,29 @@ + class Solution: def maxWidthRamp(self, A): """ :type A: List[int] :rtype: int + + 解题思路: + 1. 首先通过字典存储每个数值对应的所有索引位置,方便后续查找。 + 2. 对原始列表A进行排序,以确定最左边和最右边的边界。 + 3. 遍历排序后的A,计算当前数字对应的最大宽度。 + 4. 更新最小索引值ind,确保最终结果正确。 """ ind, mx, index = float("inf"), 0, collections.defaultdict(list) + + # 构建字典index,键为数值,值为该数值对应的索引列表 for i, num in enumerate(A): index[num].append(i) + + # 对原始数组进行排序 A.sort() + + # 遍历排序后的A,计算最大宽度 for i in range(len(A)): mx = max(mx, index[A[i]][-1] - ind) ind = min(ind, index[A[i]][0]) - return mx \ No newline at end of file + + return mx + \ No newline at end of file diff --git a/solutions/python3/963.py b/solutions/python3/963.py index 0fd5744..e82aa61 100644 --- a/solutions/python3/963.py +++ b/solutions/python3/963.py @@ -1,13 +1,29 @@ class Solution: + # 定义一个类来解决最小自由矩形面积问题 + def minAreaFreeRect(self, points): - mn, st, n = float('inf'), {(x, y) for x, y in points}, len(points) + # 初始化最小面积为正无穷大,存储所有点的集合,并获取点的数量 + mn, st, n = float('inf'), {(x, y) for x, y in points}, len(points) + + # 遍历每一个顶点i for i in range(n): x1, y1 = points[i] + + # 从i之后的每个顶点j开始,避免重复计算 for j in range(i + 1, n): x2, y2 = points[j] + + # 从j之后的每个顶点k开始,形成一个矩形的三条边 for k in range(j + 1, n): x3, y3 = points[k] - if not (x3 - x1) * (x2 - x1) + (y3 - y1) * (y2 - y1) and (x3 + (x2 - x1), y3 + (y2 - y1)) in st: - mn = min(mn, ((x2 - x1) ** 2 + (y2 - y1) ** 2) ** 0.5 * ((x3 - x1) ** 2 + (y3 - y1) ** 2) ** 0.5) - return mn if mn < float("inf") else 0 \ No newline at end of file + + # 检查是否能构成直角三角形(即第三条边与前两条垂直) + if not (x3 - x1) * (x2 - x1) + (y3 - y1) * (y2 - y1): + # 确认第四点存在 + if (x3 + (x2 - x1), y3 + (y2 - y1)) in st: + # 计算矩形的面积并更新最小值 + mn = min(mn, ((x2 - x1) ** 2 + (y2 - y1) ** 2) ** 0.5 * ((x3 - x1) ** 2 + (y3 - y1) ** 2) ** 0.5) + + # 如果找到了有效矩形,返回最小面积;否则返回0 + return mn if mn < float("inf") else 0 diff --git a/solutions/python3/964.py b/solutions/python3/964.py index 2ded97a..4996756 100644 --- a/solutions/python3/964.py +++ b/solutions/python3/964.py @@ -1,11 +1,22 @@ + class Solution: def leastOpsExpressTarget(self, x: int, y: int) -> int: + """ + 计算最小操作次数来表示目标值y + + 英文注释:Calculate the minimum number of operations to express target value y. + """ pos = neg = k = 0 + # 当y不为0时持续循环 while y: y, cur = divmod(y, x) - if k: + if k: # 如果k大于0,处理正负值 + # 更新pos和neg的最小操作次数 pos, neg = min(cur * k + pos, (cur + 1) * k + neg), min((x - cur) * k + pos, (x - cur - 1) * k + neg) - else: + else: # 初始情况下处理正负值 + # 直接计算当前位置的正负操作次数 pos, neg = cur * 2, (x - cur) * 2 - k += 1 - return min(pos, k + neg) - 1 \ No newline at end of file + k += 1 # 每次循环k加一,表示当前层级 + + # 返回最小的操作次数减1 + return min(pos, k + neg) - 1 diff --git a/solutions/python3/965.py b/solutions/python3/965.py index 8b3ef9e..79a50c6 100644 --- a/solutions/python3/965.py +++ b/solutions/python3/965.py @@ -1,17 +1,34 @@ + # Definition for a binary tree node. -# class TreeNode: -# def __init__(self, x): -# self.val = x -# self.left = None -# self.right = None +class TreeNode: + def __init__(self, x): + self.val = x + self.left = None + self.right = None class Solution: - def isUnivalTree(self, root): + # 检查是否为单值二叉树 + def isUnivalTree(self, root: 'TreeNode') -> 'bool': """ :type root: TreeNode :rtype: bool + + English: Check if the binary tree is a univalue tree. + + Parameters: + root (TreeNode): The root node of the binary tree + + Returns: + bool: True if all nodes have the same value, False otherwise """ - if not root: return True - if root.left and root.left.val != root.val: return False - if root.right and root.right.val != root.val: return False - return self.isUnivalTree(root.left) and self.isUnivalTree(root.right) \ No newline at end of file + # 如果根节点为空,返回True + if not root: + return True + # 检查左子树是否为单值树且左子节点的值等于根节点值 + if root.left and root.left.val != root.val: + return False + # 检查右子树是否为单值树且右子节点的值等于根节点值 + if root.right and root.right.val != root.val: + return False + # 递归检查左、右子树是否为单值树 + return self.isUnivalTree(root.left) and self.isUnivalTree(root.right) diff --git a/solutions/python3/966.py b/solutions/python3/966.py index 5a41a8b..be97834 100644 --- a/solutions/python3/966.py +++ b/solutions/python3/966.py @@ -1,11 +1,20 @@ + class Solution: - def spellchecker(self, wordlist, queries): + def spellchecker(self, wordlist: list[str], queries: list[str]) -> list[str]: """ - :type wordlist: List[str] - :type queries: List[str] - :rtype: List[str] + :param wordlist: 一个单词列表 + :param queries: 需要检查的查询单词列表 + :return: 对于每个查询单词,返回最接近的正确拼写形式或者空字符串(如果不存在) """ - st, cap, vow = set(wordlist), {}, {} + + # 使用集合存储所有单词以实现快速查找 + st = set(wordlist) + # 用于存储大写字母单词及其小写对应词 + cap = {} + # 用于存储去掉了元音字母后的单词及其原始单词 + vow = {} + + # 构建容错字典 for w in wordlist: newC = w.lower() newW = "".join(c if c not in "aeiou" else "*" for c in newC) @@ -13,15 +22,18 @@ def spellchecker(self, wordlist, queries): cap[newC] = w if newW not in vow: vow[newW] = w + + # 对每个查询进行处理 for i, w in enumerate(queries): if w in st: - pass + pass # 已存在于单词列表中,不做修改 elif w.lower() in cap: - queries[i] = cap[w.lower()] + queries[i] = cap[w.lower()] # 大写形式匹配,使用正确的拼写 else: new = "".join(c if c not in "aeiou" else "*" for c in w.lower()) if new in vow: - queries[i] = vow[new] + queries[i] = vow[new] # 替换元音后的形式匹配,使用正确的拼写 else: - queries[i] = "" - return queries \ No newline at end of file + queries[i] = "" # 未找到匹配项 + + return queries diff --git a/solutions/python3/967.py b/solutions/python3/967.py index 779f079..ca7bdce 100644 --- a/solutions/python3/967.py +++ b/solutions/python3/967.py @@ -1,18 +1,21 @@ + class Solution: - def numsSameConsecDiff(self, N, K): + def numsSameConsecDiff(self, N: int, K: int) -> List[int]: """ - :type N: int - :type K: int - :rtype: List[int] + :type N: int # 输入数字N的长度 + :type K: int # 输入整数K,表示相邻两位间的差值 + :rtype: List[int] # 返回符合条件的所有数字列表 """ - q = {i for i in range(10)} - for _ in range(N - 1): - new = set() - for num in q: - last = num % 10 - if num and 0 <= last + K <= 9: - new.add(num * 10 + last + K) - if num and 0 <= last - K <= 9: - new.add(num * 10 + last - K) - q = new - return list(q) \ No newline at end of file + q = {i for i in range(10)} # 初始集合包含0到9的所有数字 + + for _ in range(N - 1): # 遍历N-1次,构造长度为N的数 + new = set() # 新集合用于存储下一层可能的结果 + for num in q: # 遍历当前层所有结果 + last = num % 10 # 获取当前数字的最后一位 + if num and 0 <= last + K <= 9: # 检查加K是否合法 + new.add(num * 10 + last + K) # 将新构造的数字加入集合 + if num and 0 <= last - K <= 9: # 检查减K是否合法 + new.add(num * 10 + last - K) # 将新构造的数字加入集合 + q = new # 更新当前结果集为新的一层可能的结果 + + return list(q) # 转换并返回最终符合条件的所有数字列表 diff --git a/solutions/python3/968.py b/solutions/python3/968.py index 496b507..bdef12e 100644 --- a/solutions/python3/968.py +++ b/solutions/python3/968.py @@ -1,14 +1,33 @@ + class Solution: res = 0 + + # 计算最少需要安装的摄像头数量以覆盖所有节点 def minCameraCover(self, root): + """ + :type root: TreeNode + :rtype: int + """ + + # 深度优先搜索,返回当前节点的状态 def dfs(root): - if not root: return 2 - if not root.left and not root.right: return 0 - l, r = dfs(root.left), dfs(root.right) - if l == 0 or r == 0: + if not root: + return 2 # 空节点,状态为可覆盖 + + left = dfs(root.left) + right = dfs(root.right) + + # 如果左或右子树中有一个未被覆盖,则需要安装一个摄像头 + if left == 0 or right == 0: self.res += 1 - return 1 - if l == 1 or r == 1: + return 1 # 安装了摄像头,状态为已覆盖 + + # 如果当前节点的左右子树都被覆盖,则返回2表示可覆盖 + if left == 1 or right == 1: return 2 + + # 否则,返回0表示未被覆盖 return 0 - return (dfs(root) == 0) + self.res \ No newline at end of file + + # 最终结果:根节点自身未被覆盖的情况下需要额外增加一个摄像头 + return (dfs(root) == 0) + self.res diff --git a/solutions/python3/969.py b/solutions/python3/969.py index 1333e6f..0a81269 100644 --- a/solutions/python3/969.py +++ b/solutions/python3/969.py @@ -1,8 +1,19 @@ + class Solution: + # Python 解决翻转数组使有序的问题 + def pancakeSort(self, A): - res = [] - for x in range(len(A), 1, -1): - i = A.index(x) + """ + :type A: List[int] + :rtype: List[int] + """ + res = [] # 用于存储每次需要执行的操作的反转次数 + + for x in range(len(A), 1, -1): # 从数组长度递减到2 + i = A.index(x) # 找到当前最大值x的位置 + + # 将最大值翻转至开头,再整体翻转至指定位置 res.extend([i + 1, x]) A = A[:i:-1] + A[:i] - return res \ No newline at end of file + + return res # 返回所需的操作序列 diff --git a/solutions/python3/97.py b/solutions/python3/97.py index 767bb90..3384f0d 100644 --- a/solutions/python3/97.py +++ b/solutions/python3/97.py @@ -1,9 +1,20 @@ + class Solution: - def isInterleave(self, s1, s2, s3): - def dfs(i, j, k): + # 判断字符串s1和s2是否可以交错形成s3 + + def isInterleave(self, s1: str, s2: str, s3: str) -> bool: + # 使用记忆化搜索减少重复计算 + def dfs(i: int, j: int, k: int): if (i, j, k) not in memo: - memo[(i, j, k)] = k>=l3 or (i= l3 or # s3的当前字符匹配结束情况 + (i < l1 and s3[k] == s1[i] and dfs(i + 1, j, k + 1)) or # 尝试从s1中取字符 + (j < l2 and s3[k] == s2[j] and dfs(i, j + 1, k + 1))) # 尝试从s2中取字符 return memo[(i, j, k)] - l1, l2, l3, memo = len(s1), len(s2), len(s3), {} - if l3 != l1 + l2: return False - return dfs(0, 0, 0) \ No newline at end of file + + l1, l2, l3, memo = len(s1), len(s2), len(s3), {} # 计算字符串长度并初始化记忆字典 + + if l3 != l1 + l2: # 初步验证s3的长度是否合理 + return False + + return dfs(0, 0, 0) # 调用深度优先搜索从起点开始查找交错路径 diff --git a/solutions/python3/970.py b/solutions/python3/970.py index 6906fbd..8b9724e 100644 --- a/solutions/python3/970.py +++ b/solutions/python3/970.py @@ -1,22 +1,37 @@ + class Solution: - def powerfulIntegers(self, x, y, bound): + def powerfulIntegers(self, x: int, y: int, bound: int) -> List[int]: """ :type x: int :type y: int :type bound: int :rtype: List[int] """ + + # 使用集合存储结果,避免重复值 res = set() - i = j = 0 + + i, j = 0, 0 + + # 对于x的幂次遍历 while x ** i <= bound: + # 对于y的幂次遍历 while x ** i + y ** j <= bound: - if x ** i + y ** j not in res: - res.add(x ** i + y ** j) + if (val := x ** i + y ** j) not in res: + res.add(val) + j += 1 + + # 如果y等于1,跳出内层循环 if y == 1: break + + # 准备下一次x的幂次遍历 j = 0 i += 1 + + # 如果x等于1,跳出外层循环 if x == 1: break + return list(res) diff --git a/solutions/python3/971.py b/solutions/python3/971.py index 2b3bcc5..3bec801 100644 --- a/solutions/python3/971.py +++ b/solutions/python3/971.py @@ -1,3 +1,4 @@ + # Definition for a binary tree node. # class TreeNode: # def __init__(self, x): @@ -6,16 +7,25 @@ # self.right = None class Solution: - def flipMatchVoyage(self, root, voyage): - res = [] - self.i = 0 + # 初始化翻转结果列表和遍历索引 + def flipMatchVoyage(self, root: 'TreeNode', voyage: list[int]) -> list[int]: + res = [] # 存储需要翻转的节点值 + self.i = 0 # 遍历voyage数组的索引 + def dfs(node): - if not node: return True + if not node: + return True # 当前节点为空,返回True表示满足要求 if node.val != voyage[self.i]: - return False - self.i += 1 + return False # 节点值与voyage中对应位置的值不符,直接返回False + self.i += 1 # 遍历索引后移 + + # 如果左子节点存在且其值不等于voyage当前值,则交换左右子节点,并将当前节点加入结果列表 if node.left and node.left.val != voyage[self.i]: node.left, node.right = node.right, node.left res.append(node.val) + + # 递归遍历左子树和右子树,两个条件都满足才返回True return dfs(node.left) and dfs(node.right) - return res if dfs(root) else [-1] \ No newline at end of file + + # 如果整个树满足要求则返回结果列表,否则返回[-1] + return res if dfs(root) else [-1] diff --git a/solutions/python3/972.py b/solutions/python3/972.py index ada5684..34beae8 100644 --- a/solutions/python3/972.py +++ b/solutions/python3/972.py @@ -1,8 +1,14 @@ + class Solution: - def isRationalEqual(self, S, T): - def f(s): + # 检查两个字符串S和T是否表示相同的有理数,最多保留前20位有效数字 + def isRationalEqual(self, S: str, T: str) -> bool: + def parse(s): + # 找到括号开始位置 i = s.find('(') if i >= 0: + # 替换循环节,只保留20次循环后的结果以简化比较 s = s[:i] + s[i + 1:-1] * 20 return float(s[:20]) - return f(S) == f(T) \ No newline at end of file + + # 比较两个字符串解析后的浮点数是否相等 + return parse(S) == parse(T) diff --git a/solutions/python3/973.py b/solutions/python3/973.py index bee0cd6..16d29c8 100644 --- a/solutions/python3/973.py +++ b/solutions/python3/973.py @@ -1,3 +1,8 @@ + class Solution: + # 定义一个类来解决最接近点对的问题 + def kClosest(self, points, K): - return sorted(points, key = lambda p: p[0] ** 2 + p[1] ** 2)[:K] \ No newline at end of file + # 返回points中与原点最接近的K个点 + return sorted(points, key=lambda p: p[0] ** 2 + p[1] ** 2)[:K] + # 使用sorted函数,通过计算每个点到原点的距离平方来排序,并返回前K个点 diff --git a/solutions/python3/974.py b/solutions/python3/974.py index 9f37bae..676ed07 100644 --- a/solutions/python3/974.py +++ b/solutions/python3/974.py @@ -1,10 +1,23 @@ + class Solution: def subarraysDivByK(self, A: List[int], K: int) -> int: - res = sm = 0 - sums = collections.defaultdict(int) - sums[0] = 1 - for a in A: - sm = (sm + a) % K - sums[sm] += 1 - res += sums[sm] - 1 - return res \ No newline at end of file + """ + 计算数组A中和能被K整除的子数组数量 + + Args: + A (List[int]): 输入整数列表 + K (int): 整除的基数 + + Returns: + int: 和能被K整除的子数组数量 + """ + res = sm = 0 # 初始化结果和当前前缀和 + sums = collections.defaultdict(int) # 使用字典存储前缀和出现次数 + sums[0] = 1 # 前缀和为0的情况初始化 + + for a in A: # 遍历输入数组A + sm = (sm + a) % K # 更新当前前缀和并对K取模 + sums[sm] += 1 # 当前前缀和出现次数加一 + res += sums[sm] - 1 # 累加满足条件的子数组数量 + + return res # 返回结果 diff --git a/solutions/python3/975.py b/solutions/python3/975.py index 20bf620..b38cf27 100644 --- a/solutions/python3/975.py +++ b/solutions/python3/975.py @@ -1,24 +1,34 @@ + class Solution: + # 定义一个类,用于解决奇偶跳跃问题 + def oddEvenJumps(self, A: List[int]) -> int: - n = len(A) + n = len(A) # 获取数组长度 + # 初始化两个列表,分别存储更高和更低元素的下一个位置索引 next_higher, next_lower = [0] * n, [0] * n + # 第一次遍历,找到每个位置的更高元素下一个位置 stack = [] for a, i in sorted([a, i] for i, a in enumerate(A)): while stack and stack[-1] < i: - next_higher[stack.pop()] = i - stack.append(i) + next_higher[stack.pop()] = i # 更新栈中元素的更高元素索引 + stack.append(i) # 将当前元素压入栈 + # 第二次遍历,找到每个位置的更低元素下一个位置 stack = [] for a, i in sorted([-a, i] for i, a in enumerate(A)): while stack and stack[-1] < i: - next_lower[stack.pop()] = i - stack.append(i) + next_lower[stack.pop()] = i # 更新栈中元素的更低元素索引 + stack.append(i) # 将当前元素压入栈 + # 初始化两个标志列表,用于记录每个位置是否可以跳到下一个更高或更低的位置 higher, lower = [0] * n, [0] * n - higher[-1] = lower[-1] = 1 + higher[-1] = lower[-1] = 1 # 设置最后一个位置的初始值为1 + + # 反向遍历数组,更新跳跃标志列表 for i in range(n - 1)[::-1]: - higher[i] = lower[next_higher[i]] - lower[i] = higher[next_lower[i]] + higher[i] = lower[next_higher[i]] # 更新当前位置可以跳到更高位置的下一个位置是否可以到达终点 + lower[i] = higher[next_lower[i]] # 更新当前位置可以跳到更低位置的下一个位置是否可以到达终点 + + # 返回可以完成跳跃的数量总和 return sum(higher) - \ No newline at end of file diff --git a/solutions/python3/976.py b/solutions/python3/976.py index dfc2017..734d282 100644 --- a/solutions/python3/976.py +++ b/solutions/python3/976.py @@ -1,8 +1,13 @@ + class Solution: def largestPerimeter(self, A): """ :type A: List[int] :rtype: int + + 英文注释:定义一个方法largestPerimeter,输入一个整数列表A,返回由这三个元素组成的三角形的周长最大值。 + + 中文注释:定义一个方法largestPerimeter,输入一个整数列表A,返回由这三个元素组成的三角形的周长最大值。 """ - A.sort() - return ([0] + [a + b + c for a, b, c in zip(A, A[1:], A[2:]) if c < a + b])[-1] \ No newline at end of file + A.sort() # 对数组进行排序 + return ([0] + [a + b + c for a, b, c in zip(A, A[1:], A[2:]) if c < a + b])[-1] # 遍历所有可能的三角形组合,返回最大周长 diff --git a/solutions/python3/977.py b/solutions/python3/977.py index 205cec2..9f5697f 100644 --- a/solutions/python3/977.py +++ b/solutions/python3/977.py @@ -1,7 +1,11 @@ + class Solution: + # Python 方法定义,处理整数列表A的平方后排序 + def sortedSquares(self, A): """ - :type A: List[int] - :rtype: List[int] + :type A: List[int] # 输入:一个整数列表A + :rtype: List[int] # 输出:整数列表A中每个元素平方后的有序列表 """ - return sorted([x ** 2 for x in A]) \ No newline at end of file + + return sorted([x ** 2 for x in A]) # 列表推导式计算每个元素的平方,排序后返回结果 diff --git a/solutions/python3/978.py b/solutions/python3/978.py index 6ecf775..985cc4a 100644 --- a/solutions/python3/978.py +++ b/solutions/python3/978.py @@ -1,11 +1,30 @@ + class Solution: - def maxTurbulenceSize(self, A): - arr = [A[i - 1] < A[i] for i in range(1, len(A))] + # 定义一个类用于解决最大湍流子数组的问题 + + def maxTurbulenceSize(self, A: list[int]) -> int: + """ + 计算数组A中的最大湍流子数组长度。 + :param A: 输入的整数列表 + :return: 最大的湍流子数组长度 + + 逻辑解析: + - 首先通过比较相邻元素确定每个位置上两数是否成升序或降序关系,形成一个布尔数组 + - 然后遍历布尔数组,统计连续不同趋势的最长子序列长度 + """ + + # 创建一个布尔列表来记录每对相邻元素的趋势(True表示升序,False表示降序) + arr = [A[i-1] < A[i] for i in range(1, len(A))] + + # 初始化当前最大湍流子数组长度和前一次的比较结果 cur = mx = 1 + (len(A) > 1) + + # 遍历布尔列表,统计最大湍流子数组长度 for i in range(1, len(arr)): - if A[i] != A[i + 1] and arr[i] != arr[i - 1]: + if A[i] != A[i+1] and arr[i] != arr[i-1]: cur += 1 mx = max(cur, mx) else: cur = 2 - return mx \ No newline at end of file + + return mx diff --git a/solutions/python3/979.py b/solutions/python3/979.py index fe0ccad..a7d1a9b 100644 --- a/solutions/python3/979.py +++ b/solutions/python3/979.py @@ -1,12 +1,38 @@ + class Solution: def distributeCoins(self, root): + """ + 分发硬币问题:给定一棵二叉树,每个节点包含整数(可能为负、零或正)。目标是确保每个节点的值恰好为1, + 同时尽量减少从根到叶的所有路径上移动硬币的总次数。 + + 方法: + - 使用深度优先搜索 (DFS) 来遍历树,并计算需要调整的硬币数量。 + - 对于每个节点,计算其左子树和右子树的硬币不平衡情况(即多余的或缺少的硬币数)。 + - 更新全局变量 `self.ans` 以记录总的硬币移动次数。 + + 参数: + root (TreeNode): 二叉树的根节点 + + 返回值: + int: 调整至每个节点值为1所需的最小硬币移动次数 + """ + self.ans = 0 def dfs(node): + """ + 深度优先搜索辅助函数 + + 参数: + node (TreeNode): 当前处理的树节点 + + 返回值: + int: 当前节点及其子树的硬币不平衡情况(多余或缺少的硬币数) + """ if not node: return 0 L, R = dfs(node.left), dfs(node.right) self.ans += abs(L) + abs(R) return node.val + L + R - 1 dfs(root) - return self.ans \ No newline at end of file + return self.ans diff --git a/solutions/python3/98.py b/solutions/python3/98.py index 2e60f07..ece174e 100644 --- a/solutions/python3/98.py +++ b/solutions/python3/98.py @@ -1,18 +1,34 @@ + # Definition for a binary tree node. -# class TreeNode: -# def __init__(self, x): -# self.val = x -# self.left = None -# self.right = None +class TreeNode: + def __init__(self, x): + self.val = x + self.left = None + self.right = None class Solution: - def isValidBST(self, root): + # 检查二叉树是否为有效二叉搜索树 + def isValidBST(self, root: 'TreeNode') -> 'bool': """ :type root: TreeNode :rtype: bool """ + def validate(node, mn, mx): - if not node: return True - if node.valmx: return False - return validate(node.left,mn,node.val-1) and validate(node.right,node.val+1,mx) - return validate(root, -float("inf"),float("inf")) \ No newline at end of file + """ + 验证节点值是否在给定的范围内,并递归验证其左右子树。 + - node: 当前检查的节点 + - mn: 节点值必须大于该最小值 + - mx: 节点值必须小于该最大值 + :type node: TreeNode + :type mn: int + :type mx: int + :rtype: bool + """ + if not node: + return True + if node.val < mn or node.val > mx: + return False + return validate(node.left, mn, node.val-1) and validate(node.right, node.val+1, mx) + + return validate(root, -float("inf"), float("inf")) diff --git a/solutions/python3/980.py b/solutions/python3/980.py index 033013f..c988cb3 100644 --- a/solutions/python3/980.py +++ b/solutions/python3/980.py @@ -1,20 +1,29 @@ + class Solution: def uniquePathsIII(self, grid: List[List[int]]) -> int: + + # 深度优先搜索函数,参数为当前坐标 (i, j) 和已访问过的空地数量 visited def dfs(i, j, visited): if grid[i][j] == 2: + # 到达目标位置,检查是否所有空地都被访问过 self.walks += visited == self.visit return + for x, y in ((i - 1, j), (i + 1, j), (i, j - 1), (i, j + 1)): + # 检查边界和障碍物 if 0 <= x < m and 0 <= y < n and grid[x][y] != -1: - grid[i][j] -= 1 + grid[i][j] -= 1 # 标记当前位置为已访问或非空地,防止重复访问 dfs(x, y, visited + 1) - grid[i][j] += 1 - m, n = len(grid), len(grid[0]) - self.visit = m * n - sum(c == -1 for row in grid for c in row) + grid[i][j] += 1 # 还原现场 + + m, n = len(grid), len(grid[0]) # 获取网格的行数和列数 + self.visit = m * n - sum(c == -1 for row in grid for c in row) # 计算需要访问的空地数量 self.walks = 0 + + # 遍历整个网格,寻找起点并进行深度优先搜索 for i in range(m): for j in range(n): if grid[i][j] == 1: - grid[i][j] -= 1 - dfs(i, j, 1) - return self.walks \ No newline at end of file + grid[i][j] -= 1 # 标记起点为已访问或非空地 + dfs(i, j, 1) # 调用深度优先搜索函数 + return self.walks diff --git a/solutions/python3/981.py b/solutions/python3/981.py index f13729c..9d1ee80 100644 --- a/solutions/python3/981.py +++ b/solutions/python3/981.py @@ -1,13 +1,18 @@ + class TimeMap: + # 构造函数,初始化两个字典,默认值为列表 def __init__(self): - self.times = collections.defaultdict(list) - self.values = collections.defaultdict(list) + from collections import defaultdict + self.times = defaultdict(list) # 存储时间戳 + self.values = defaultdict(list) # 存储对应的值 + # 设置键的值和对应的时间戳 def set(self, key: str, value: str, timestamp: int) -> None: - self.times[key].append(timestamp) - self.values[key].append(value) + self.times[key].append(timestamp) # 将时间戳添加到对应键的列表中 + self.values[key].append(value) # 将值添加到对应键的列表中 + # 获取特定键在某个时间戳之前的最大值 def get(self, key: str, timestamp: int) -> str: - i = bisect.bisect(self.times[key], timestamp) - return self.values[key][i - 1] if i else '' + i = bisect.bisect(self.times[key], timestamp) # 使用二分查找找到插入位置 + return self.values[key][i - 1] if i else '' # 如果找到了,则返回对应的值,否则返回空字符串 diff --git a/solutions/python3/982.py b/solutions/python3/982.py index 852cc88..e615645 100644 --- a/solutions/python3/982.py +++ b/solutions/python3/982.py @@ -1,4 +1,12 @@ + class Solution: + """ + Solution 类,包含 countTriplets 方法用于计算满足特定条件的三元组数量。 + """ + def countTriplets(self, A: List[int]) -> int: + # 使用 Counter 统计所有可能的按位与结果及其出现次数 cnt = collections.Counter([a & b for a in A for b in A]) - return sum(cnt[k] for a in A for k in cnt if not a & k) \ No newline at end of file + + # 计算满足条件的三元组数量:对于每个元素 a 和统计中所有 k,如果 a 与 k 的按位与结果为 0,则累加计数 + return sum(cnt[k] for a in A for k in cnt if not a & k) diff --git a/solutions/python3/983.py b/solutions/python3/983.py index 88cb2c0..636b580 100644 --- a/solutions/python3/983.py +++ b/solutions/python3/983.py @@ -1,9 +1,20 @@ + class Solution: def mincostTickets(self, days: List[int], costs: List[int]) -> int: - day, days, last = [0] * 366, set(days), days[-1] - for i in range(1, last + 1): - if i not in days: - day[i] = day[i - 1] - else: - day[i] = min(day[i - 1] + costs[0], day[i - 7 if i>= 7 else 0] + costs[1], day[i - 30 if i >= 30 else 0] + costs[2]) - return day[last] \ No newline at end of file + """ + 定义一个类Solution,包含一个方法mincostTickets用于计算最小旅行成本。 + + :param days: 一个整数列表,表示需要旅行的天数。 + :param costs: 一个整数列表,表示不同票种的价格。 + :return: 返回最小的成本。 + """ + day, days_set, last_day = [0] * 366, set(days), max(days) # 初始化天数数组和集合,获取最后一天 + for i in range(1, last_day + 1): # 遍历从1到last_day的每一天 + if i not in days_set: # 如果当前不是需要旅行的日子 + day[i] = day[i - 1] # 继承前一天的成本 + else: # 否则,是需要旅行的一天 + # 计算三种不同票种下的最小成本,并更新当前day[i] + day[i] = min(day[i - 1] + costs[0], + day[max(0, i - 7)] + costs[1], + day[max(0, i - 30)] + costs[2]) + return day[last_day] # 返回最后一天的最小成本 diff --git a/solutions/python3/984.py b/solutions/python3/984.py index 090d185..6f19088 100644 --- a/solutions/python3/984.py +++ b/solutions/python3/984.py @@ -1,12 +1,19 @@ + class Solution: def strWithout3a3b(self, A: int, B: int) -> str: - if not A and not B: return '' + """ + 构造一个字符串,使得其中任意连续的字符数量不超过2个。 + + 中文注释:构造一个字符串,确保其中任何连续的字符数量都不超过两个。 + """ + if not A and not B: + return '' + # 当A的数量大于等于B时 if A >= B: - a = 2 if A >= 2 else 1 - b = 2 if A - a - B < 1 and B >= 2 else 1 if B else 0 - return a * 'a' + b * 'b' + self.strWithout3a3b(A - a, B - b) + a = 2 if A >= 2 else 1 # 确定a的值,最多用2个'a' + b = 2 if A - a - B < 1 and B >= 2 else 1 if B else 0 # 确定b的值,如果剩余条件满足,则使用2个'b', 否则为1或0 + return a * 'a' + b * 'b' + self.strWithout3a3b(A - a, B - b) # 递归构造剩余部分 else: - b = 2 if B >= 2 else 1 - a = 2 if B - b - A < 1 and A >= 2 else 1 if A else 0 - return b * 'b' + a * 'a' + self.strWithout3a3b(A - a, B - b) - \ No newline at end of file + b = 2 if B >= 2 else 1 # 确定b的值,最多用2个'b' + a = 2 if B - b - A < 1 and A >= 2 else 1 if A else 0 # 确定a的值,如果剩余条件满足,则使用2个'a', 否则为1或0 + return b * 'b' + a * 'a' + self.strWithout3a3b(A - a, B - b) # 递归构造剩余部分 diff --git a/solutions/python3/985.py b/solutions/python3/985.py index dbd8999..3c4556e 100644 --- a/solutions/python3/985.py +++ b/solutions/python3/985.py @@ -1,10 +1,25 @@ + class Solution: + # 定义一个解决方案类 + def sumEvenAfterQueries(self, A: List[int], queries: List[List[int]]) -> List[int]: - sm = sum(a for a in A if a % 2 == 0) + # 初始化偶数和为0 + even_sum = sum(a for a in A if a % 2 == 0) + + # 遍历查询列表 for i in range(len(queries)): val, ind = queries[i] - sm -= A[ind] % 2 == 0 and A[ind] + + # 更新偶数和:先减去旧值,再加新值 + even_sum -= A[ind] % 2 == 0 and A[ind] A[ind] += val - sm += A[ind] % 2 == 0 and A[ind] - queries[i] = sm - return queries \ No newline at end of file + + # 更新偶数和:如果新值是偶数,则加上该值 + if A[ind] % 2 == 0: + even_sum += A[ind] + + # 将当前计算出的偶数和赋给查询结果 + queries[i] = even_sum + + return queries + # 返回处理后的查询结果列表 diff --git a/solutions/python3/986.py b/solutions/python3/986.py index 72202a5..204f966 100644 --- a/solutions/python3/986.py +++ b/solutions/python3/986.py @@ -1,17 +1,27 @@ + class Solution: def intervalIntersection(self, A: List[Interval], B: List[Interval]) -> List[Interval]: + # 初始化两个指针和结果列表 i = j = 0 res = [] + + # 双指针遍历A和B的区间 while i < len(A) and j < len(B): + # 计算重叠区间的起始和结束点 s = max(A[i].start, B[j].start) e = min(A[i].end, B[j].end) + + # 如果有重叠区间,将其添加到结果中 if s <= e: res.append(Interval(s, e)) + + # 根据B区间的结束位置决定移动哪个指针 if A[i].end < B[j].end: i += 1 - elif A[i].end == B[j].end: + elif A[i].end == B[j].end: # 两个区间同时结束的情况 i += 1 j += 1 else: j += 1 - return res \ No newline at end of file + + return res diff --git a/solutions/python3/987.py b/solutions/python3/987.py index 99fa263..d1c6616 100644 --- a/solutions/python3/987.py +++ b/solutions/python3/987.py @@ -1,10 +1,29 @@ + class Solution: - def verticalTraversal(self, root: TreeNode) -> List[List[int]]: - self.arr = [] - def dfs(node, x, y): + def verticalTraversal(self, root: 'TreeNode') -> List[List[int]]: + """ + 该方法用于垂直遍历二叉树,并返回按垂直顺序排列的节点值列表。 + + :param root: 二叉树根节点 + :return: 按垂直顺序排列的节点值列表 + """ + + self.arr = [] # 存储节点信息元组 (x坐标, y坐标, 节点值) + + def dfs(node: 'TreeNode', x: int, y: int) -> None: + """ + 深度优先搜索遍历二叉树。 + + :param node: 当前遍历到的节点 + :param x: 当前节点在x轴上的坐标 + :param y: 当前节点在y轴上的坐标 + """ if node: - self.arr.append((x, y, node.val)) - dfs(node.left, x - 1, y + 1) - dfs(node.right, x + 1, y + 1) - dfs(root, 0, 0) - return [list(map(lambda x: x[-1], g)) for k, g in itertools.groupby(sorted(self.arr), key = lambda x: x[0])] \ No newline at end of file + self.arr.append((x, y, node.val)) # 记录当前节点信息 + dfs(node.left, x - 1, y + 1) # 遍历左子树 + dfs(node.right, x + 1, y + 1) # 遍历右子树 + + dfs(root, 0, 0) # 从根节点开始深度优先搜索 + + # 按x坐标排序,然后按y坐标分组,最后提取每个组中的节点值 + return [list(map(lambda x: x[-1], g)) for k, g in itertools.groupby(sorted(self.arr), key=lambda x: x[0])] diff --git a/solutions/python3/988.py b/solutions/python3/988.py index 352137d..ee7883b 100644 --- a/solutions/python3/988.py +++ b/solutions/python3/988.py @@ -1,9 +1,17 @@ + class Solution: - def smallestFromLeaf(self, root: TreeNode, s = '') -> str: + def smallestFromLeaf(self, root: 'TreeNode', s = '') -> str: + # 中文注释:如果当前节点没有左右子节点,返回由当前节点值组成的字符与s拼接后的字符串 if not root.right and not root.left: return chr(97 + root.val) + s + + # 中文注释:如果当前节点只有右子节点,递归调用左子树,并将当前节点的字符添加到s中 if not root.right: return self.smallestFromLeaf(root.left, chr(97 + root.val) + s) + + # 中文注释:如果当前节点只有左子节点,递归调用右子树,并将当前节点的字符添加到s中 if not root.left: return self.smallestFromLeaf(root.right, chr(97 + root.val) + s) - return min(self.smallestFromLeaf(root.left, chr(97 + root.val) + s), self.smallestFromLeaf(root.right, chr(97 + root.val) + s)) \ No newline at end of file + + # 中文注释:如果当前节点有左右子节点,分别递归处理左右子树,并返回较小的结果 + return min(self.smallestFromLeaf(root.left, chr(97 + root.val) + s), self.smallestFromLeaf(root.right, chr(97 + root.val) + s)) diff --git a/solutions/python3/989.py b/solutions/python3/989.py index e09c23f..5fb3897 100644 --- a/solutions/python3/989.py +++ b/solutions/python3/989.py @@ -1,5 +1,11 @@ + class Solution: + # 定义一个类来解决数组加整数的问题 + def addToArrayForm(self, A, K): + # 遍历数组A,从后向前逐位相加K,并处理进位 for i in range(len(A))[::-1]: A[i], K = (A[i] + K) % 10, (A[i] + K) // 10 - return [int(i) for i in str(K)] + A if K else A \ No newline at end of file + + # 如果K还有剩余部分,则将其转换为列表并添加到A的前面 + return [int(i) for i in str(K)] + A if K else A diff --git a/solutions/python3/99.py b/solutions/python3/99.py index a21243d..6b62327 100644 --- a/solutions/python3/99.py +++ b/solutions/python3/99.py @@ -1,17 +1,36 @@ + class Solution: def recoverTree(self, root): + """ + 修复二叉搜索树中两个错误节点的值以恢复正确的排序。 + + :param root: 二叉搜索树的根节点 + """ + def inorder(node): + """ + 中序遍历生成器,用于迭代访问二叉搜索树中的每个节点。 + + :param node: 当前访问的节点 + """ if node.left: yield from inorder(node.left) yield node if node.right: yield from inorder(node.right) + swap1 = swap2 = smaller = None - for node in inorder(root): + for node in inorder(root): + """ + 遍历二叉搜索树中的每个节点,找到需要交换的两个节点。 + + :param node: 当前访问的节点 + """ if smaller and smaller.val > node.val: - if not swap1: + if not swap1: swap1 = smaller - swap2 = node + swap2 = node smaller = node + if swap1: - swap1.val, swap2.val = swap2.val, swap1.val \ No newline at end of file + swap1.val, swap2.val = swap2.val, swap1.val diff --git a/solutions/python3/990.py b/solutions/python3/990.py index c5cd1e9..0fb709d 100644 --- a/solutions/python3/990.py +++ b/solutions/python3/990.py @@ -1,12 +1,28 @@ + class Solution: def equationsPossible(self, equations: List[str]) -> bool: + # 使用路径压缩和按秩合并优化的并查集初始化 def uf(c): - return uf(parent[ord(c) - ord('a')]) if parent[ord(c) - ord('a')] != c else ord(c) - ord('a') + if parent[ord(c) - ord('a')] != c: + parent[ord(c) - ord('a')] = uf(parent[ord(c) - ord('a')]) + return parent[ord(c) - ord('a')] + + # 初始化并查集,每个字符初始为自己父节点 parent = [c for c in string.ascii_lowercase] + + # 处理等号约束条件 for eq in equations: if eq[1] == '=': - parent[uf(eq[0])] = parent[uf(eq[-1])] + # 合并等号两边的连通分量 + root_x = uf(eq[0]) + root_y = uf(eq[-1]) + parent[root_x] = root_y + + # 检查非等号约束条件 for eq in equations: - if eq[1] == '!' and parent[uf(eq[0])] == parent[uf(eq[-1])]: - return False - return True \ No newline at end of file + if eq[1] == '!': + # 如果非等号两边属于同一个连通分量,返回False + if uf(eq[0]) == uf(eq[-1]): + return False + + return True diff --git a/solutions/python3/991.py b/solutions/python3/991.py index 04761db..05a0767 100644 --- a/solutions/python3/991.py +++ b/solutions/python3/991.py @@ -1,7 +1,31 @@ + class Solution: - def brokenCalc(self, X, Y): + # 定义一个解决类,用于实现计算从X到Y所需操作次数的方法 + + def brokenCalc(self, X: int, Y: int) -> int: + # 计算将X变为Y所需的最小按键次数 res = 0 + # 初始化结果计数器为0 + while X < Y: - res += Y % 2 + 1 - Y = (Y + 1) // 2 - return res + X - Y \ No newline at end of file + if Y % 2 == 0: + Y //= 2 # 如果Y是偶数,直接除以2 + else: + Y += 1 # 如果Y是奇数,加1使其变为偶数再除以2 + res += 1 # 每次操作计数器加1 + + return res + X - Y # 返回总操作次数加上X和Y的差值 + + + +class Solution: + def brokenCalc(self, X: int, Y: int) -> int: + res = 0 + while X < Y: + if Y % 2 == 0: + Y //= 2 + else: + Y += 1 + res += 1 + + return res + X - Y diff --git a/solutions/python3/993.py b/solutions/python3/993.py index d918d76..bc09a00 100644 --- a/solutions/python3/993.py +++ b/solutions/python3/993.py @@ -1,9 +1,42 @@ + class Solution: - def isCousins(self, root: TreeNode, x: int, y: int) -> bool: - def dfs(node, parent, depth, mod): - if node: - if node.val == mod: - return depth, parent - return dfs(node.left, node, depth + 1, mod) or dfs(node.right, node, depth + 1, mod) - dx, px, dy, py = dfs(root, None, 0, x) + dfs(root, None, 0, y) - return dx == dy and px != py \ No newline at end of file + def isCousins(self, root: 'TreeNode', x: int, y: int) -> bool: + """ + 判断二叉树中的两个节点是否为堂兄弟。 + + :param root: 二叉树根节点 + :param x: 第一个节点值 + :param y: 第二个节点值 + :return: 如果两个节点是堂兄弟,返回True;否则返回False + + 通过深度优先搜索(DFS)遍历树来找到目标节点x和y。 + """ + + def dfs(node, parent=None, depth=0): + """ + 深度优先搜索函数,用于递归地在树中查找节点。 + + :param node: 当前处理的节点 + :param parent: 当前节点的父节点 + :param depth: 当前节点所在的深度 + """ + if not node: + return None, None # 如果当前节点为空,则返回None + + if node.val == x or node.val == y: + # 如果当前节点是目标之一,返回其深度和父节点 + return (depth, parent) + + # 递归搜索左子树和右子树 + left_result = dfs(node.left, node, depth + 1) + if left_result: + return left_result + + right_result = dfs(node.right, node, depth + 1) + return right_result + + dx, px = dfs(root) # 搜索x所在的深度和父节点 + dy, py = dfs(root) # 搜索y所在的深度和父节点 + + # 如果两个节点的深度相同且父节点不同,则它们是堂兄弟 + return dx == dy and px != py diff --git a/solutions/python3/994.py b/solutions/python3/994.py index 0ef9bb1..173ea90 100644 --- a/solutions/python3/994.py +++ b/solutions/python3/994.py @@ -1,13 +1,32 @@ + class Solution: def orangesRotting(self, grid: List[List[int]]) -> int: + """ + 初始化腐烂橘子的起始位置,并使用广度优先搜索(BFS)来模拟感染过程。 + + :param grid: 二维列表,表示橘子的状态,0 表示空地,1 表示新鲜橘子,2 表示腐烂橘子 + :return: 返回腐烂所需的时间,如果所有橘子都腐烂则返回时间,否则返回 -1 + + 初始化腐烂橘子的起始位置和计时器 t、网格大小 m 和 n。 + """ bfs, t, m, n = [(i, j) for i, row in enumerate(grid) for j, val in enumerate(row) if val == 2], 0, len(grid), len(grid[0]) + while bfs: + # 新一轮的腐烂橘子 new = [] + + # 遍历当前轮次中的所有腐烂橘子 for i, j in bfs: + # 检查四个方向上的邻近位置 for x, y in ((i - 1, j), (i + 1, j), (i, j - 1), (i, j + 1)): if 0 <= x < m and 0 <= y < n and grid[x][y] == 1: + # 邻近的新鲜橘子腐烂 grid[x][y] = 2 new.append((x, y)) + bfs = new + # 如果有新的腐烂橘子加入,则计时器 t 加一 t += bool(bfs) - return t if all(val != 1 for row in grid for val in row) else -1 \ No newline at end of file + + # 检查所有橘子是否都已腐烂 + return t if all(val != 1 for row in grid for val in row) else -1 diff --git a/solutions/python3/995.py b/solutions/python3/995.py index 7f8871c..9dd6155 100644 --- a/solutions/python3/995.py +++ b/solutions/python3/995.py @@ -1,11 +1,30 @@ + class Solution: def minKBitFlips(self, a: List[int], k: int) -> int: - q = collections.deque() - res = 0 + """ + 定义一个解决方案类,其中包含一个方法来计算最小的翻转次数使得数组a中任意连续k个元素至少有一个为0。 + + :param a: List[int] - 输入的整数列表 + :param k: int - 连续需要翻转的长度 + :return: int - 最小的翻转次数,如果无法满足条件返回-1 + """ + from collections import deque + + q = deque() # 使用双端队列记录每个需要翻转的位置 + res = 0 # 记录总的翻转次数 + for i in range(len(a)): if len(q) % 2 != 0 and a[i] == 1 or len(q) % 2 == a[i] == 0: + # 当前元素不需要被翻转但队列中已经有奇数个位置需要翻转,或者当前元素需要被翻转且队列中有偶数个 res += 1 - q.append(i+k-1) - if q and q[0] == i: q.popleft() - if q and q[-1] >= len(a): return -1 - return res \ No newline at end of file + q.append(i + k - 1) + + if q and q[0] == i: + # 如果队列中最左边的位置已经处理完,则移除该位置 + q.popleft() + + if q and q[-1] >= len(a): + # 检查是否超出了数组长度,如果超出则无法满足条件,返回-1 + return -1 + + return res # 返回总的翻转次数 diff --git a/solutions/python3/996.py b/solutions/python3/996.py index 54adee2..148a60d 100644 --- a/solutions/python3/996.py +++ b/solutions/python3/996.py @@ -1,27 +1,57 @@ + class Solution: def numSquarefulPerms(self, A: List[int]) -> int: + """ + 计算给定数组A中可以构成平方和的排列数量 + + 参数: + A (List[int]): 给定整数列表 + + 返回值: + int: 可以构成平方和的排列数量 + """ + self.res = 0 + def dfs(cnt, num): + """ + 深度优先搜索,寻找合法路径 + + 参数: + cnt (Counter): 当前元素使用情况计数器 + num (int): 当前节点值 + """ if not cnt: + # 所有元素都已使用完,找到一个有效排列 self.res += 1 for new in nex[num]: if cnt[new]: + # 使用当前新元素,并更新计数器 cnt[new] -= 1 if not cnt[new]: cnt.pop(new) dfs(cnt, new) + # 恢复状态 cnt[new] += 1 - - nex = collections.defaultdict(set) - cnt = collections.Counter(A) + + from collections import Counter + import itertools + + nex = collections.defaultdict(set) # 邻接表,记录可以构成平方和的相邻关系 + cnt = Counter(A) # 记录当前元素使用情况计数器 + + # 构建邻接表nex for a, b in itertools.permutations(A, 2): - if not (a + b) ** 0.5 % 1: + if not (a + b) ** 0.5 % 1: # 判断是否能构成平方和 nex[a].add(b) nex[b].add(a) + + # 开始深度优先搜索,遍历所有起始点 for a in set(A): cnt[a] -= 1 if not cnt[a]: cnt.pop(a) dfs(cnt, a) cnt[a] += 1 - return self.res \ No newline at end of file + + return self.res diff --git a/solutions/python3/997.py b/solutions/python3/997.py index c184f65..8104c73 100644 --- a/solutions/python3/997.py +++ b/solutions/python3/997.py @@ -1,4 +1,11 @@ + class Solution: + # 定义一个类来解决问题 + def findJudge(self, N: int, trust: List[List[int]]) -> int: + # 使用计数器统计被信任的人的次数,取出现次数最多的那个 j, cnt = collections.Counter(b for a, b in trust).most_common(1)[0] if trust else (N, 0) - return j if j not in {a for a, b in trust} and cnt == N - 1 else -1 \ No newline at end of file + + # 如果这个人没有信任任何人,并且被其他 N-1 个人信任,则他是法官 + return j if j not in {a for a, b in trust} and cnt == N - 1 else -1 + # 返回结果,如果找不到法官则返回 -1 diff --git a/solutions/python3/998.py b/solutions/python3/998.py index f9c4c1f..183f583 100644 --- a/solutions/python3/998.py +++ b/solutions/python3/998.py @@ -1,14 +1,21 @@ + class Solution: + # 定义插入最大值的函数,输入根节点root、要插入的值val以及父节点parent def insertIntoMaxTree(self, root: TreeNode, val: int, parent = None) -> TreeNode: + # 如果当前节点为空或新值大于当前节点值,则创建新节点,并调整父子关系 if not root or val > root.val: new = TreeNode(val) - new.left = root - if parent: - if parent.right == root: + new.left = root # 将原根节点作为新插入节点的左子树 + + if parent: # 如果存在父节点 + if parent.right == root: # 若当前节点是父节点的右孩子,则将新节点设为父节点的新右孩子 parent.right = new - else: + else: # 否则,设置为父节点的左子树 parent.left = new - root = new + + return new # 返回新根节点 else: + # 如果当前节点值大于插入值,则递归地将新值插入到右子树中 root.right = self.insertIntoMaxTree(root.right, val, root) - return root \ No newline at end of file + + return root # 返回调整后的根节点 diff --git a/solutions/python3/999.py b/solutions/python3/999.py index 83021a1..7a373d8 100644 --- a/solutions/python3/999.py +++ b/solutions/python3/999.py @@ -1,22 +1,33 @@ + class Solution: + # 初始化解决方案类 + def numRookCaptures(self, board: List[List[str]], res = 0) -> int: + # 计算棋盘中皇后能吃掉的子的数量 + for i in range(8): for j in range(8): if board[i][j] == 'R': + # 找到第一个R(皇后)的位置 + + # 检查向上是否有可吃的棋子 for x in range(i - 1, -1, -1): if board[x][j] in 'Bp': res += board[x][j] == 'p' break + # 检查向下是否有可吃的棋子 for x in range(i + 1, 8): if board[x][j] in 'Bp': res += board[x][j] == 'p' break + # 检查向左是否有可吃的棋子 for y in range(j - 1, -1, -1): if board[i][y] in 'Bp': res += board[i][y] == 'p' break + # 检查向右是否有可吃的棋子 for y in range(j + 1, 8): if board[i][y] in 'Bp': res += board[i][y] == 'p' break - return res \ No newline at end of file + return res # 返回总数 diff --git a/solutions/python3/bak/1.py.bak b/solutions/python3/bak/1.py.bak new file mode 100644 index 0000000..9228e78 --- /dev/null +++ b/solutions/python3/bak/1.py.bak @@ -0,0 +1,7 @@ +class Solution: + def twoSum(self, nums, target): + nums_hash = {} + for i in range(len(nums)): + if target - nums[i] in nums_hash: + return [nums_hash[target - nums[i]], i] + nums_hash[nums[i]] = i \ No newline at end of file diff --git a/solutions/python3/bak/10.py.bak b/solutions/python3/bak/10.py.bak new file mode 100644 index 0000000..9457b2a --- /dev/null +++ b/solutions/python3/bak/10.py.bak @@ -0,0 +1,3 @@ +class Solution: + def isMatch(self, s, p): + return bool(re.match(r"%s" %p, s)) and re.match(r"%s" %p, s).group(0) == s \ No newline at end of file diff --git a/solutions/python3/bak/100.py.bak b/solutions/python3/bak/100.py.bak new file mode 100644 index 0000000..6701136 --- /dev/null +++ b/solutions/python3/bak/100.py.bak @@ -0,0 +1,3 @@ +class Solution: + def isSameTree(self, p, q): + return p == q if not p or not q else p.val == q.val and self.isSameTree(p.left, q.left) and self.isSameTree(p.right, q.right) \ No newline at end of file diff --git a/solutions/python3/bak/1000.py.bak b/solutions/python3/bak/1000.py.bak new file mode 100644 index 0000000..bfe4817 --- /dev/null +++ b/solutions/python3/bak/1000.py.bak @@ -0,0 +1,17 @@ +class Solution: + def mergeStones(self, stones, K): + n = len(stones) + if (n - 1) % (K - 1): return -1 + prefix = [0] * (n + 1) + for i in range(n): + prefix[i + 1] = prefix[i] + stones[i] + + import functools + @functools.lru_cache(None) + def dp(i, j): + if j - i + 1 < K: return 0 + res = min(dp(i, mid) + dp(mid + 1, j) for mid in range(i, j, K - 1)) + if (j - i) % (K - 1) == 0: + res += prefix[j + 1] - prefix[i] + return res + return dp(0, n - 1) \ No newline at end of file diff --git a/solutions/python3/bak/1001.py.bak b/solutions/python3/bak/1001.py.bak new file mode 100644 index 0000000..b2346e8 --- /dev/null +++ b/solutions/python3/bak/1001.py.bak @@ -0,0 +1,29 @@ +class Solution: + def gridIllumination(self, N: int, lamps: List[List[int]], queries: List[List[int]]) -> List[int]: + lampsOn = set() + rowsOn = collections.defaultdict(int) + colsOn = collections.defaultdict(int) + diagOnTopLeftBottomRight = collections.defaultdict(int) + diagOnBottomLeftTopRight = collections.defaultdict(int) + for r, c in lamps: + lampsOn.add((r, c)) + rowsOn[r] += 1 + colsOn[c] += 1 + diagOnTopLeftBottomRight[c-r] += 1 + diagOnBottomLeftTopRight[c+r-N] += 1 + + result = [] + for r, c in queries: + if rowsOn[r] > 0 or colsOn[c] > 0 or diagOnTopLeftBottomRight[c-r] > 0 or diagOnBottomLeftTopRight[c+r-N] > 0: + result.append(1) + else: + result.append(0) + adjacentLamps = [(r, c), (r, c-1), (r, c+1), (r-1, c), (r-1, c-1), (r-1, c+1), (r+1, c), (r+1, c-1), (r+1, c+1)] + for r, c in adjacentLamps: + if (r, c) in lampsOn: + lampsOn.discard((r, c)) + rowsOn[r] -= 1 + colsOn[c] -= 1 + diagOnTopLeftBottomRight[c-r] -= 1 + diagOnBottomLeftTopRight[c+r-N] -= 1 + return result \ No newline at end of file diff --git a/solutions/python3/bak/1002.py.bak b/solutions/python3/bak/1002.py.bak new file mode 100644 index 0000000..46a8d55 --- /dev/null +++ b/solutions/python3/bak/1002.py.bak @@ -0,0 +1,11 @@ +class Solution: + def commonChars(self, A: List[str]) -> List[str]: + cnt, res = {s: [float('inf'), 0] for s in string.ascii_lowercase}, [] + for w in A: + for k, v in collections.Counter(w).items(): + cnt[k][0] = min(cnt[k][0], v) + cnt[k][1] += 1 + for k in cnt: + if cnt[k][1] == len(A): + res += [k] * cnt[k][0] + return res \ No newline at end of file diff --git a/solutions/python3/bak/1003.py.bak b/solutions/python3/bak/1003.py.bak new file mode 100644 index 0000000..cfc1961 --- /dev/null +++ b/solutions/python3/bak/1003.py.bak @@ -0,0 +1,12 @@ +class Solution: + def isValid(self, S: str) -> bool: + stack = [] + for i in S: + if i == 'c': + if stack[-2:] != ['a', 'b']: + return False + stack.pop() + stack.pop() + else: + stack.append(i) + return not stack \ No newline at end of file diff --git a/solutions/python3/bak/1004.py.bak b/solutions/python3/bak/1004.py.bak new file mode 100644 index 0000000..a815051 --- /dev/null +++ b/solutions/python3/bak/1004.py.bak @@ -0,0 +1,6 @@ +class Solution: + def longestOnes(self, A: List[int], K: int) -> int: + zeros, res = [-1] + [i for i, c in enumerate(A) if not c] + [len(A)], 0 + for j in range(K + 1, len(zeros)): + res = max(res, zeros[j] - zeros[j - K - 1] - 1) + return res or K and len(A) \ No newline at end of file diff --git a/solutions/python3/bak/1005.py.bak b/solutions/python3/bak/1005.py.bak new file mode 100644 index 0000000..d4b7905 --- /dev/null +++ b/solutions/python3/bak/1005.py.bak @@ -0,0 +1,7 @@ +class Solution: + def largestSumAfterKNegations(self, A: List[int], K: int) -> int: + heapq.heapify(A) + for _ in range(K): + val = heapq.heappop(A) + heapq.heappush(A, -val) + return sum(A) \ No newline at end of file diff --git a/solutions/python3/bak/1006.py.bak b/solutions/python3/bak/1006.py.bak new file mode 100644 index 0000000..58b69bd --- /dev/null +++ b/solutions/python3/bak/1006.py.bak @@ -0,0 +1,12 @@ +class Solution: + def clumsy(self, N: int) -> int: + if N <= 2: + return N + if N <= 4: + return N + 3 + if N % 4 == 0: + return N + 1 + elif N % 4 <= 2: + return N + 2 + else: + return N - 1 \ No newline at end of file diff --git a/solutions/python3/bak/1007.py.bak b/solutions/python3/bak/1007.py.bak new file mode 100644 index 0000000..5927048 --- /dev/null +++ b/solutions/python3/bak/1007.py.bak @@ -0,0 +1,4 @@ +class Solution: + def minDominoRotations(self, A: List[int], B: List[int]) -> int: + res = min(len(A) - max(A.count(c), B.count(c)) if all(a == c or b == c for a, b in zip(A, B)) else float('inf') for c in (A[0], B[0])) + return res if res < float('inf') else -1 \ No newline at end of file diff --git a/solutions/python3/bak/1008.py.bak b/solutions/python3/bak/1008.py.bak new file mode 100644 index 0000000..f185557 --- /dev/null +++ b/solutions/python3/bak/1008.py.bak @@ -0,0 +1,14 @@ +class Solution: + def bstFromPreorder(self, preorder: List[int]) -> TreeNode: + root = TreeNode(preorder[0]) + stack = [root] + for value in preorder[1:]: + if value < stack[-1].val: + stack[-1].left = TreeNode(value) + stack.append(stack[-1].left) + else: + while stack and stack[-1].val < value: + last = stack.pop() + last.right = TreeNode(value) + stack.append(last.right) + return root \ No newline at end of file diff --git a/solutions/python3/bak/1009.py.bak b/solutions/python3/bak/1009.py.bak new file mode 100644 index 0000000..653f3d1 --- /dev/null +++ b/solutions/python3/bak/1009.py.bak @@ -0,0 +1,3 @@ +class Solution: + def bitwiseComplement(self, N: int, M = 0, m = 0) -> int: + return N ^ M if M and M >= N else self.bitwiseComplement(N, M + 2 ** m, m + 1) \ No newline at end of file diff --git a/solutions/python3/bak/101.py.bak b/solutions/python3/bak/101.py.bak new file mode 100644 index 0000000..2cea9f6 --- /dev/null +++ b/solutions/python3/bak/101.py.bak @@ -0,0 +1,31 @@ +#Definition for a binary tree node. +class TreeNode: + def __init__(self, x): + self.val = x + self.left = None + self.right = None + +class Solution: + def isSymmetric(self, root): + """ + :type root: TreeNode + :rtype: bool + """ + if root is None: + return True + else: + return self.isMirror(root.left, root.right) + + def isMirror(self, left, right): + if left is None and right is None: + return True + if left is None or right is None: + return False + + if left.val == right.val: + outPair = self.isMirror(left.left, right.right) + inPiar = self.isMirror(left.right, right.left) + return outPair and inPiar + else: + return False + \ No newline at end of file diff --git a/solutions/python3/bak/1010.py.bak b/solutions/python3/bak/1010.py.bak new file mode 100644 index 0000000..1a62844 --- /dev/null +++ b/solutions/python3/bak/1010.py.bak @@ -0,0 +1,7 @@ +class Solution: + def numPairsDivisibleBy60(self, time: List[int]) -> int: + mod = [0] * 61 + for t in time: + mod[-1] += mod[(60 - t % 60) % 60] + mod[t % 60] += 1 + return mod[-1] \ No newline at end of file diff --git a/solutions/python3/bak/1011.py.bak b/solutions/python3/bak/1011.py.bak new file mode 100644 index 0000000..ec9dc12 --- /dev/null +++ b/solutions/python3/bak/1011.py.bak @@ -0,0 +1,21 @@ +class Solution: + def shipWithinDays(self, weights: List[int], D: int) -> int: + def check(mx): + days, cur = 1, 0 + for w in weights: + if cur + w <= mx: + cur += w + else: + days += 1 + cur = w + return days + + l, r = max(weights), sum(weights) + while l < r: + mid = (l + r) // 2 + days = check(mid) + if days <= D: + r = mid + else: + l = mid + 1 + return r \ No newline at end of file diff --git a/solutions/python3/bak/1012.py.bak b/solutions/python3/bak/1012.py.bak new file mode 100644 index 0000000..85e9b7b --- /dev/null +++ b/solutions/python3/bak/1012.py.bak @@ -0,0 +1,44 @@ +class Solution(object): + def numDupDigitsAtMostN(self, N): + """ + :type N: int + :rtype: int + """ + # given number n, see whether n has repeated number + def has_repeated(n): + str_n = str(n) + return len(set(str_n)) != len(str_n) + + def permutation(n, k): + prod = 1 + for i in range(k): + prod *= (n-i) + return prod + + # calculate number of non-repeated n-digit numbers + # note: the n-digit number can't start with 0 + # i.e: n_digit_no_repeat(2) calculates the non-repeated + # numbers in range [10, 99] (inclusive) + def n_digit_no_repeat(n): + if n == 1: + return 9 + else: + return 9 * permutation(9, n-1) + + N_str = str(N) + n_digit = len(N_str) + digits = list(map(int, N_str)) + result = N - 1 + prefix = 0 + for i in range(1, n_digit): + result -= n_digit_no_repeat(i) + for i in range(n_digit): + # when we fix the most significant digit, it + # can't be zero + start = 0 if i else 1 + for j in range(start, digits[i]): + if has_repeated(prefix * 10 + j): + continue + result -= permutation(9 - i, n_digit-1-i) + prefix = prefix*10 + digits[i] + return result + has_repeated(N) \ No newline at end of file diff --git a/solutions/python3/bak/1013.py.bak b/solutions/python3/bak/1013.py.bak new file mode 100644 index 0000000..bfa8b57 --- /dev/null +++ b/solutions/python3/bak/1013.py.bak @@ -0,0 +1,10 @@ +class Solution: + def canThreePartsEqualSum(self, A: List[int]) -> bool: + tar = sum(A) // 3 + sm = cnt = 0 + for a in A: + sm += a + if sm == tar: + sm = 0 + cnt += 1 + return cnt == 3 \ No newline at end of file diff --git a/solutions/python3/bak/1014.py.bak b/solutions/python3/bak/1014.py.bak new file mode 100644 index 0000000..d7cfba3 --- /dev/null +++ b/solutions/python3/bak/1014.py.bak @@ -0,0 +1,7 @@ +class Solution: + def maxScoreSightseeingPair(self, A: List[int]) -> int: + pre, mx = 0, -float('inf') + for j, a in enumerate(A): + mx = max(mx, pre + a - j) + pre = max(pre, a + j) + return mx \ No newline at end of file diff --git a/solutions/python3/bak/1015.py.bak b/solutions/python3/bak/1015.py.bak new file mode 100644 index 0000000..8008129 --- /dev/null +++ b/solutions/python3/bak/1015.py.bak @@ -0,0 +1,10 @@ +class Solution: + def smallestRepunitDivByK(self, K: int) -> int: + used, mod, cnt = set(), 1 % K, 1 + while mod: + mod = (mod * 10 + 1) % K + cnt += 1 + if mod in used: + return -1 + used.add(mod) + return cnt \ No newline at end of file diff --git a/solutions/python3/bak/1016.py.bak b/solutions/python3/bak/1016.py.bak new file mode 100644 index 0000000..369e506 --- /dev/null +++ b/solutions/python3/bak/1016.py.bak @@ -0,0 +1,3 @@ +class Solution: + def queryString(self, S: str, N: int) -> bool: + return not set(range(1, N + 1)) - {int(S[i:j + 1], 2) for i in range(len(S)) for j in range(i, len(S))} \ No newline at end of file diff --git a/solutions/python3/bak/1017.py.bak b/solutions/python3/bak/1017.py.bak new file mode 100644 index 0000000..caed416 --- /dev/null +++ b/solutions/python3/bak/1017.py.bak @@ -0,0 +1,10 @@ +class Solution: + def baseNeg2(self, n: int) -> str: + bits = [] + while n: + n, rem = divmod(n, -2) + if rem < 0: + n += 1 + rem -= -2 + bits.append(str(rem)) + return "".join(bits[::-1]) if bits else '0' \ No newline at end of file diff --git a/solutions/python3/bak/1018.py.bak b/solutions/python3/bak/1018.py.bak new file mode 100644 index 0000000..dad7279 --- /dev/null +++ b/solutions/python3/bak/1018.py.bak @@ -0,0 +1,7 @@ +class Solution: + def prefixesDivBy5(self, A: List[int]) -> List[bool]: + num = 0 + for i in range(len(A)): + num = (num << 1) + A[i] + A[i] = num % 5 == 0 + return A \ No newline at end of file diff --git a/solutions/python3/bak/1019.py.bak b/solutions/python3/bak/1019.py.bak new file mode 100644 index 0000000..7ff5b43 --- /dev/null +++ b/solutions/python3/bak/1019.py.bak @@ -0,0 +1,19 @@ +# Definition for singly-linked list. +# class ListNode: +# def __init__(self, x): +# self.val = x +# self.next = None + +class Solution: + def nextLargerNodes(self, head: ListNode) -> List[int]: + heap, res, j = [], [], 0 + while head: + res.append(0) + while heap and heap[0][0] < head.val: + val, i = heapq.heappop(heap) + res[i] = head.val + heapq.heappush(heap, (head.val, j)) + j += 1 + head = head.next + return res + \ No newline at end of file diff --git a/solutions/python3/bak/102.py.bak b/solutions/python3/bak/102.py.bak new file mode 100644 index 0000000..e61e7a2 --- /dev/null +++ b/solutions/python3/bak/102.py.bak @@ -0,0 +1,18 @@ +# Definition for a binary tree node. +# class TreeNode: +# def __init__(self, x): +# self.val = x +# self.left = None +# self.right = None + +class Solution: + def levelOrder(self, root): + """ + :type root: TreeNode + :rtype: List[List[int]] + """ + q, res = [root], [] + while any(q): + res.append([i.val for i in q]) + q = [kid for node in q for kid in (node.left, node.right) if kid] + return res \ No newline at end of file diff --git a/solutions/python3/bak/1020.py.bak b/solutions/python3/bak/1020.py.bak new file mode 100644 index 0000000..0f2b438 --- /dev/null +++ b/solutions/python3/bak/1020.py.bak @@ -0,0 +1,13 @@ +class Solution: + def numEnclaves(self, A: List[List[int]]) -> int: + def dfs(i, j): + A[i][j] = 0 + for x, y in (i - 1, j), (i + 1, j), (i, j - 1), (i, j + 1): + if 0 <= x < m and 0 <= y < n and A[x][y]: + dfs(x, y) + m, n = len(A), len(A[0]) + for i in range(m): + for j in range(n): + if A[i][j] == 1 and (i == 0 or j == 0 or i == m - 1 or j == n - 1): + dfs(i, j) + return sum(sum(row) for row in A) \ No newline at end of file diff --git a/solutions/python3/bak/1021.py.bak b/solutions/python3/bak/1021.py.bak new file mode 100644 index 0000000..9bd7680 --- /dev/null +++ b/solutions/python3/bak/1021.py.bak @@ -0,0 +1,12 @@ +class Solution: + def removeOuterParentheses(self, S: str) -> str: + l = r = 0 + res = cur = '' + for s in S: + cur += s + l += s == '(' + r += s == ')' + if l == r: + res += cur[1:-1] + cur = '' + return res \ No newline at end of file diff --git a/solutions/python3/bak/1022.py.bak b/solutions/python3/bak/1022.py.bak new file mode 100644 index 0000000..ec20e26 --- /dev/null +++ b/solutions/python3/bak/1022.py.bak @@ -0,0 +1,13 @@ +# Definition for a binary tree node. +# class TreeNode: +# def __init__(self, x): +# self.val = x +# self.left = None +# self.right = None + +class Solution: + def sumRootToLeaf(self, r: TreeNode, num = 0) -> int: + if not r: + return 0 + num = (num << 1) + r.val + return (self.sumRootToLeaf(r.left, num) + self.sumRootToLeaf(r.right, num) if r.left or r.right else num) % (10 ** 9 + 7) \ No newline at end of file diff --git a/solutions/python3/bak/1023.py.bak b/solutions/python3/bak/1023.py.bak new file mode 100644 index 0000000..61f6a0c --- /dev/null +++ b/solutions/python3/bak/1023.py.bak @@ -0,0 +1,12 @@ +class Solution: + def camelMatch(self, queries: List[str], pattern: str) -> List[bool]: + res = [] + for w in queries: + j = 0 + for c in w: + if j < len(pattern) and c == pattern[j]: + j += 1 + elif c.isupper(): + j = len(pattern) + 1 + res.append(j == len(pattern)) + return res \ No newline at end of file diff --git a/solutions/python3/bak/1024.py.bak b/solutions/python3/bak/1024.py.bak new file mode 100644 index 0000000..633c1be --- /dev/null +++ b/solutions/python3/bak/1024.py.bak @@ -0,0 +1,11 @@ +class Solution: + def videoStitching(self, clips: List[List[int]], T: int) -> int: + clips.sort(key = lambda x: (-x[0], x[1])) + x = cnt = mx = 0 + while clips and clips[-1][0] <= x < T: + while clips and clips[-1][0] <= x: + mx = max(mx, clips.pop()[1]) + if mx > x: + x = mx + cnt += 1 + return cnt if x >= T else -1 \ No newline at end of file diff --git a/solutions/python3/bak/1025.py.bak b/solutions/python3/bak/1025.py.bak new file mode 100644 index 0000000..9575668 --- /dev/null +++ b/solutions/python3/bak/1025.py.bak @@ -0,0 +1,3 @@ +class Solution: + def divisorGame(self, N: int) -> bool: + return N % 2 == 0 \ No newline at end of file diff --git a/solutions/python3/bak/1026.py.bak b/solutions/python3/bak/1026.py.bak new file mode 100644 index 0000000..72a30a0 --- /dev/null +++ b/solutions/python3/bak/1026.py.bak @@ -0,0 +1,25 @@ +# Definition for a binary tree node. +# class TreeNode: +# def __init__(self, x): +# self.val = x +# self.left = None +# self.right = None + +class Solution: + def maxAncestorDiff(self, root: TreeNode) -> int: + self.res = 0 + def dfs(node): + mx = mn = node.val + if node.left: + lMn, lMx = dfs(node.left) + mx = max(mx, lMx) + mn = min(mn, lMn) + self.res = max(self.res, abs(lMn - node.val), abs(lMx - node.val)) + if node.right: + rMn, rMx = dfs(node.right) + mx = max(mx, rMx) + mn = min(mn, rMn) + self.res = max(self.res, abs(rMn - node.val), abs(rMx - node.val)) + return mn, mx + dfs(root) + return self.res \ No newline at end of file diff --git a/solutions/python3/bak/1027.py.bak b/solutions/python3/bak/1027.py.bak new file mode 100644 index 0000000..c3208f0 --- /dev/null +++ b/solutions/python3/bak/1027.py.bak @@ -0,0 +1,8 @@ +class Solution: + def longestArithSeqLength(self, A: List[int]) -> int: + dp = collections.defaultdict(int) + for i in range(len(A)): + for j in range(i + 1, len(A)): + a, b = A[i], A[j] + dp[b - a, j] = max(dp[b - a, j], dp[b - a, i] + 1) + return max(dp.values()) + 1 \ No newline at end of file diff --git a/solutions/python3/bak/1028.py.bak b/solutions/python3/bak/1028.py.bak new file mode 100644 index 0000000..4d78667 --- /dev/null +++ b/solutions/python3/bak/1028.py.bak @@ -0,0 +1,41 @@ +# Definition for a binary tree node. +# class TreeNode: +# def __init__(self, x): +# self.val = x +# self.left = None +# self.right = None + +class Solution: + def recoverFromPreorder(self, S: str) -> TreeNode: + def dfs(parent, s, lev): + print(parent.val, s, lev) + if not s: return + i = lev + l = 0 + while i < len(s) and s[i].isdigit(): + l = l * 10 + int(s[i]) + i += 1 + parent.left = TreeNode(l) + j = lev + f = '-' * lev + for ind in range(i, len(s)): + if s[ind:].startswith(f) and not s[ind:].startswith(f + '-') and s[ind -1] != '-': + rr = ind + j = ind + lev + r = 0 + while j < len(s) and s[j].isdigit(): + r = r * 10 + int(s[j]) + j += 1 + parent.right = TreeNode(r) + dfs(parent.left, s[i:rr], lev + 1) + dfs(parent.right, s[j:], lev + 1) + return + dfs(parent.left, s[i:], lev + 1) + i = num = 0 + while i < len(S) and S[i].isdigit(): + num = num * 10 + int(S[i]) + i += 1 + root = TreeNode(num) + dfs(root, S[i:], 1) + return root + \ No newline at end of file diff --git a/solutions/python3/bak/1029.py.bak b/solutions/python3/bak/1029.py.bak new file mode 100644 index 0000000..931c567 --- /dev/null +++ b/solutions/python3/bak/1029.py.bak @@ -0,0 +1,14 @@ +class Solution: + def twoCitySchedCost(self, costs: List[List[int]]) -> int: + costs.sort(key = lambda x: abs(x[0] - x[1])) + a = b = 0 + N = len(costs) // 2 + c = 0 + for c1, c2 in costs[::-1]: + if c1 <= c2 and a < N or b >= N: + c += c1 + a += 1 + else: + c += c2 + b += 1 + return c \ No newline at end of file diff --git a/solutions/python3/bak/103.py.bak b/solutions/python3/bak/103.py.bak new file mode 100644 index 0000000..81298a2 --- /dev/null +++ b/solutions/python3/bak/103.py.bak @@ -0,0 +1,18 @@ +# Definition for a binary tree node. +# class TreeNode: +# def __init__(self, x): +# self.val = x +# self.left = None +# self.right = None + +class Solution: + def zigzagLevelOrder(self, root): + """ + :type root: TreeNode + :rtype: List[List[int]] + """ + q, i, res = [root], 0, [] + while any(q): + add, q, i = q if i % 2 == 0 else q[::-1], [kid for node in q for kid in (node.left, node.right) if kid], i+1 + res.append([item.val for item in add]) + return res \ No newline at end of file diff --git a/solutions/python3/bak/1030.py.bak b/solutions/python3/bak/1030.py.bak new file mode 100644 index 0000000..f103bf3 --- /dev/null +++ b/solutions/python3/bak/1030.py.bak @@ -0,0 +1,14 @@ +class Solution: + def allCellsDistOrder(self, R: int, C: int, r0: int, c0: int) -> List[List[int]]: + bfs, res, seen = [[r0, c0]], [], {(r0, c0)} + while bfs: + res += bfs + new = [] + for i, j in bfs: + for x, y in (i - 1, j), (i + 1, j), (i, j + 1), (i, j - 1): + if 0 <= x < R and 0 <= y < C and (x, y) not in seen: + seen.add((x, y)) + new.append([x, y]) + bfs = new + return res + \ No newline at end of file diff --git a/solutions/python3/bak/1031.py.bak b/solutions/python3/bak/1031.py.bak new file mode 100644 index 0000000..2c03a21 --- /dev/null +++ b/solutions/python3/bak/1031.py.bak @@ -0,0 +1,38 @@ +class Solution: + def maxSumTwoNoOverlap(self, A: List[int], L: int, M: int) -> int: + n = len(A) + l = [0] * n + r = [0] * n + sm = 0 + for i in range(M - 1): + sm += A[i] + for j in range(n - M + 1): + sm += A[j + M - 1] + for i in range(j + 1): + r[i] = max(r[i], sm) + sm -= A[j] + + sm = 0 + for i in range(n - 1, n - M, -1): + sm += A[i] + for i in range(n - 1, M - 2, -1): + sm += A[i - M + 1] + for j in range(i + 1, n): + l[j] = max(l[j], sm) + sm -= A[i] + + + + + sm = 0 + for i in range(L - 1): + sm += A[i] + res = 0 + for j in range(n - L + 1): + sm += A[j + L - 1] + if j >= M: + res = max(res, sm + l[j - 1]) + if j + L < n: + res = max(res, sm + r[j + L]) + sm -= A[j] + return res \ No newline at end of file diff --git a/solutions/python3/bak/1032.py.bak b/solutions/python3/bak/1032.py.bak new file mode 100644 index 0000000..6e9adf4 --- /dev/null +++ b/solutions/python3/bak/1032.py.bak @@ -0,0 +1,12 @@ +import functools +class StreamChecker(object): + + def __init__(self, words): + T = lambda: collections.defaultdict(T) + self.trie = T() + for w in words: functools.reduce(dict.__getitem__, w, self.trie)['#'] = True + self.waiting = [] + + def query(self, letter): + self.waiting = [node[letter] for node in self.waiting + [self.trie] if letter in node] + return any("#" in node for node in self.waiting) \ No newline at end of file diff --git a/solutions/python3/bak/1033.py.bak b/solutions/python3/bak/1033.py.bak new file mode 100644 index 0000000..d55d91e --- /dev/null +++ b/solutions/python3/bak/1033.py.bak @@ -0,0 +1,12 @@ +class Solution: + def numMovesStones(self, a: int, b: int, c: int) -> List[int]: + a, b, c = sorted([a, b, c]) + m1 = b - 1 - a + m2 = c - b - 1 + m1 + m2 + if a + 2 == b or b + 2 == c: + return [1, m1 + m2] + n1 = int(b - 1 > a) + n2 = int(b + 1 < c) + return [n1 + n2, m1 + m2] + \ No newline at end of file diff --git a/solutions/python3/bak/1034.py.bak b/solutions/python3/bak/1034.py.bak new file mode 100644 index 0000000..774c8b9 --- /dev/null +++ b/solutions/python3/bak/1034.py.bak @@ -0,0 +1,19 @@ +class Solution: + def colorBorder(self, grid: List[List[int]], r0: int, c0: int, color: int) -> List[List[int]]: + def dfs(i, j): + seen.add((i, j)) + if not (0 < i < m - 1 and 0 < j < n - 1 and grid[i - 1][j] == grid[i + 1][j] == grid[i][j - 1] == grid[i][j + 1] == grid[i][j]): + matrix[i][j] = 0 + for x, y in (i - 1, j), (i + 1, j), (i, j - 1), (i, j + 1): + if 0 <= x < m and 0 <= y < n and grid[x][y] == self.tar and (x, y) not in seen: + dfs(x, y) + m, n = len(grid), len(grid[0]) + seen = set() + self.tar = grid[r0][c0] + matrix = [row[:] for row in grid] + dfs(r0, c0) + for i in range(m): + for j in range(n): + if not matrix[i][j]: + matrix[i][j] = color + return matrix \ No newline at end of file diff --git a/solutions/python3/bak/1035.py.bak b/solutions/python3/bak/1035.py.bak new file mode 100644 index 0000000..935d7bb --- /dev/null +++ b/solutions/python3/bak/1035.py.bak @@ -0,0 +1,7 @@ +class Solution: + def maxUncrossedLines(self, A: List[int], B: List[int]) -> int: + dp, m, n = collections.defaultdict(int), len(A), len(B) + for i in range(m): + for j in range(n): + dp[i, j] = max(dp[i - 1, j - 1] + (A[i] == B[j]), dp[i - 1, j], dp[i, j - 1]) + return dp[m - 1, n - 1] \ No newline at end of file diff --git a/solutions/python3/bak/1036.py.bak b/solutions/python3/bak/1036.py.bak new file mode 100644 index 0000000..7682b31 --- /dev/null +++ b/solutions/python3/bak/1036.py.bak @@ -0,0 +1,26 @@ +class Solution: + def isEscapePossible(self, blocked: List[List[int]], source: List[int], target: List[int]) -> bool: + if not blocked: return True + blocked = set(map(tuple, blocked)) + + def check(blocked, source, target): + si, sj = source + ti, tj = target + level = 0 + q = collections.deque([(si,sj)]) + vis = set() + while q: + for _ in range(len(q)): + i,j = q.popleft() + if i == ti and j == tj: return True + for x,y in ((i+1,j),(i-1,j),(i,j+1),(i,j-1)): + if 0<=x<10**6 and 0<=y<10**6 and (x,y) not in vis and (x,y) not in blocked: + vis.add((x,y)) + q.append((x,y)) + level += 1 + if level == len(blocked): break + else: + return False + return True + + return check(blocked, source, target) and check(blocked, target, source) \ No newline at end of file diff --git a/solutions/python3/bak/1037.py.bak b/solutions/python3/bak/1037.py.bak new file mode 100644 index 0000000..4ef852d --- /dev/null +++ b/solutions/python3/bak/1037.py.bak @@ -0,0 +1,3 @@ +class Solution: + def isBoomerang(self, p: List[List[int]]) -> bool: + return (p[0][0] - p[1][0]) * (p[0][1] - p[2][1]) != (p[0][0] - p[2][0]) * (p[0][1] - p[1][1]) \ No newline at end of file diff --git a/solutions/python3/bak/1038.py.bak b/solutions/python3/bak/1038.py.bak new file mode 100644 index 0000000..0edb15b --- /dev/null +++ b/solutions/python3/bak/1038.py.bak @@ -0,0 +1,7 @@ +class Solution: + val = 0 + def bstToGst(self, root): + if root.right: self.bstToGst(root.right) + root.val = self.val = self.val + root.val + if root.left: self.bstToGst(root.left) + return root \ No newline at end of file diff --git a/solutions/python3/bak/1039.py.bak b/solutions/python3/bak/1039.py.bak new file mode 100644 index 0000000..23d996f --- /dev/null +++ b/solutions/python3/bak/1039.py.bak @@ -0,0 +1,8 @@ +class Solution: + def minScoreTriangulation(self, A: List[int]) -> int: + memo = {} + def dp(i, j): + if (i, j) not in memo: + memo[i, j] = min([dp(i, k) + dp(k, j) + A[i] * A[j] * A[k] for k in range(i + 1, j)] or [0]) + return memo[i, j] + return dp(0, len(A) - 1) \ No newline at end of file diff --git a/solutions/python3/bak/104.py.bak b/solutions/python3/bak/104.py.bak new file mode 100644 index 0000000..0f3a52f --- /dev/null +++ b/solutions/python3/bak/104.py.bak @@ -0,0 +1,10 @@ +# Definition for a binary tree node. +# class TreeNode: +# def __init__(self, x): +# self.val = x +# self.left = None +# self.right = None + +class Solution: + def maxDepth(self, root: TreeNode, d = 0) -> int: + return max(self.maxDepth(root.left, d + 1), self.maxDepth(root.right, d + 1)) if root else d \ No newline at end of file diff --git a/solutions/python3/bak/1040.py.bak b/solutions/python3/bak/1040.py.bak new file mode 100644 index 0000000..87d9c10 --- /dev/null +++ b/solutions/python3/bak/1040.py.bak @@ -0,0 +1,12 @@ +class Solution: + def numMovesStonesII(self, A: List[int]) -> List[int]: + A.sort() + i, n, low = 0, len(A), len(A) + high = max(A[-1] - n + 2 - A[1], A[-2] - A[0] - n + 2) + for j in range(n): + while A[j] - A[i] >= n: i += 1 + if j - i + 1 == n - 1 and A[j] - A[i] == n - 2: + low = min(low, 2) + else: + low = min(low, n - (j - i + 1)) + return [low, high] \ No newline at end of file diff --git a/solutions/python3/bak/1041.py.bak b/solutions/python3/bak/1041.py.bak new file mode 100644 index 0000000..9c7c1fa --- /dev/null +++ b/solutions/python3/bak/1041.py.bak @@ -0,0 +1,13 @@ +class Solution: + def isRobotBounded(self, instructions: str) -> bool: + x, y, dx, dy = 0, 0, 0, 1 + for _ in range(4): + for ins in instructions: + if ins == 'G': + x += dx + y += dy + elif ins == 'L': + dx, dy = -dy, dx + else: + dx, dy = dy, -dx + return x == y == 0 \ No newline at end of file diff --git a/solutions/python3/bak/1042.py.bak b/solutions/python3/bak/1042.py.bak new file mode 100644 index 0000000..a23604f --- /dev/null +++ b/solutions/python3/bak/1042.py.bak @@ -0,0 +1,10 @@ +class Solution: + def gardenNoAdj(self, N: int, paths: List[List[int]]) -> List[int]: + res = [0] * N + G = [[] for i in range(N)] + for x, y in paths: + G[x - 1].append(y - 1) + G[y - 1].append(x - 1) + for i in range(N): + res[i] = ({1, 2, 3, 4} - {res[j] for j in G[i]}).pop() + return res \ No newline at end of file diff --git a/solutions/python3/bak/1043.py.bak b/solutions/python3/bak/1043.py.bak new file mode 100644 index 0000000..74cf0db --- /dev/null +++ b/solutions/python3/bak/1043.py.bak @@ -0,0 +1,10 @@ +class Solution: + def maxSumAfterPartitioning(self, A: List[int], K: int) -> int: + N = len(A) + dp = [0] * (N + K) + for i in range(N): + curMax = 0 + for k in range(1, min(K, i + 1) + 1): + curMax = max(curMax, A[i - k + 1]) + dp[i] = max(dp[i], dp[i - k] + curMax * k) + return dp[N - 1] \ No newline at end of file diff --git a/solutions/python3/bak/1044.py.bak b/solutions/python3/bak/1044.py.bak new file mode 100644 index 0000000..dd37ec1 --- /dev/null +++ b/solutions/python3/bak/1044.py.bak @@ -0,0 +1,24 @@ +from functools import reduce +class Solution: + def longestDupSubstring(self, S: str) -> str: + A = [ord(c) - ord('a') for c in S] + mod = 2**63 - 1 + + def test(L): + p = pow(26, L, mod) + cur = reduce(lambda x, y: (x * 26 + y) % mod, A[:L], 0) + seen = {cur} + for i in range(L, len(S)): + cur = (cur * 26 + A[i] - A[i - L] * p) % mod + if cur in seen: return i - L + 1 + seen.add(cur) + res, lo, hi = 0, 0, len(S) + while lo < hi: + mi = (lo + hi + 1) // 2 + pos = test(mi) + if pos: + lo = mi + res = pos + else: + hi = mi - 1 + return S[res:res + lo] \ No newline at end of file diff --git a/solutions/python3/bak/1046.py.bak b/solutions/python3/bak/1046.py.bak new file mode 100644 index 0000000..68f260c --- /dev/null +++ b/solutions/python3/bak/1046.py.bak @@ -0,0 +1,6 @@ +class Solution: + def lastStoneWeight(self, stones: List[int]) -> int: + stones.sort() + for _ in range(len(stones) - 1): + bisect.insort(stones, stones.pop() - stones.pop()) + return stones[0] \ No newline at end of file diff --git a/solutions/python3/bak/1047.py.bak b/solutions/python3/bak/1047.py.bak new file mode 100644 index 0000000..386d02b --- /dev/null +++ b/solutions/python3/bak/1047.py.bak @@ -0,0 +1,9 @@ +class Solution: + def removeDuplicates(self, S: str) -> str: + stack = [] + for s in S: + if stack and stack[-1] == s: + stack.pop() + else: + stack.append(s) + return ''.join(stack) \ No newline at end of file diff --git a/solutions/python3/bak/1048.py.bak b/solutions/python3/bak/1048.py.bak new file mode 100644 index 0000000..029a553 --- /dev/null +++ b/solutions/python3/bak/1048.py.bak @@ -0,0 +1,13 @@ +class Solution: + def longestStrChain(self, words: List[str]) -> int: + def dfs(w1, size): + return max([dfs(w2, size + 1) for w2 in graph[w1]], default = size) + graph = collections.defaultdict(list) + for w in words: + graph[len(w)].append(w) + for w1 in words: + for w2 in graph[len(w1) + 1]: + for i in range(len(w2)): + if w2[:i] + w2[i + 1:] == w1: + graph[w1].append(w2) + return max(dfs(w, 1) for w in words) \ No newline at end of file diff --git a/solutions/python3/bak/1049.py.bak b/solutions/python3/bak/1049.py.bak new file mode 100644 index 0000000..8ef004a --- /dev/null +++ b/solutions/python3/bak/1049.py.bak @@ -0,0 +1,7 @@ +class Solution: + def lastStoneWeightII(self, A: List[int]) -> int: + dp = {0} + sumA = sum(A) + for a in A: + dp |= {a + i for i in dp} + return min(abs(sumA - i - i) for i in dp) \ No newline at end of file diff --git a/solutions/python3/bak/105.py.bak b/solutions/python3/bak/105.py.bak new file mode 100644 index 0000000..42e88f1 --- /dev/null +++ b/solutions/python3/bak/105.py.bak @@ -0,0 +1,8 @@ +class Solution(object): + def buildTree(self, preorder, inorder): + if inorder: + ind = inorder.index(preorder.pop(0)) + root = TreeNode(inorder[ind]) + root.left = self.buildTree(preorder, inorder[0:ind]) + root.right = self.buildTree(preorder, inorder[ind+1:]) + return root \ No newline at end of file diff --git a/solutions/python3/bak/1051.py.bak b/solutions/python3/bak/1051.py.bak new file mode 100644 index 0000000..c4bac9e --- /dev/null +++ b/solutions/python3/bak/1051.py.bak @@ -0,0 +1,3 @@ +class Solution: + def heightChecker(self, heights: List[int]) -> int: + return sum(h1 != h2 for h1, h2 in zip(heights, sorted(heights))) \ No newline at end of file diff --git a/solutions/python3/bak/1052.py.bak b/solutions/python3/bak/1052.py.bak new file mode 100644 index 0000000..646864d --- /dev/null +++ b/solutions/python3/bak/1052.py.bak @@ -0,0 +1,7 @@ +class Solution: + def maxSatisfied(self, customers: List[int], grumpy: List[int], x: int) -> int: + dif = mx = sum(c * g for c, g in zip(customers[:x], grumpy[:x])) + for j in range(x, len(grumpy)): + dif += (grumpy[j] * customers[j]) - (grumpy[j - x] * customers[j - x]) + mx = max(mx, dif) + return mx + sum(c * (1- g) for c, g in zip(customers, grumpy)) \ No newline at end of file diff --git a/solutions/python3/bak/1053.py.bak b/solutions/python3/bak/1053.py.bak new file mode 100644 index 0000000..e2fd673 --- /dev/null +++ b/solutions/python3/bak/1053.py.bak @@ -0,0 +1,10 @@ +class Solution: + def prevPermOpt1(self, A: List[int]) -> List[int]: + pre = [] + for i in range(len(A) - 1, -1, -1): + bisect.insort_left(pre, (A[i], i)) + if pre.index((A[i], i)): + j = pre[pre.index((A[i], i)) - 1][1] + A[i], A[j] = A[j], A[i] + break + return A \ No newline at end of file diff --git a/solutions/python3/bak/1054.py.bak b/solutions/python3/bak/1054.py.bak new file mode 100644 index 0000000..416118d --- /dev/null +++ b/solutions/python3/bak/1054.py.bak @@ -0,0 +1,9 @@ +class Solution: + def rearrangeBarcodes(self, barcodes: List[int]) -> List[int]: + cnt = collections.Counter(barcodes).most_common()[::-1] + ref = [val for val, t in cnt for _ in range(t)] + for i in range(0, len(barcodes), 2): + barcodes[i] = ref.pop() + for i in range(1, len(barcodes), 2): + barcodes[i] = ref.pop() + return barcodes \ No newline at end of file diff --git a/solutions/python3/bak/1055.py.bak b/solutions/python3/bak/1055.py.bak new file mode 100644 index 0000000..c42a29a --- /dev/null +++ b/solutions/python3/bak/1055.py.bak @@ -0,0 +1,12 @@ +class Solution: + def shortestWay(self, source: str, target: str) -> int: + cnt = i = 0 + for t in target: + i = source.find(t, i) + if i == -1: + i = source.find(t, 0) + if i == -1: + return -1 + cnt += 1 + i += 1 + return cnt + 1 \ No newline at end of file diff --git a/solutions/python3/bak/1056.py.bak b/solutions/python3/bak/1056.py.bak new file mode 100644 index 0000000..fb23990 --- /dev/null +++ b/solutions/python3/bak/1056.py.bak @@ -0,0 +1,4 @@ +class Solution: + def confusingNumber(self, N: int) -> bool: + ret = ''.join("01####9#86"[int(n)] for n in str(N)[::-1]) + return '#' not in ret and ret != str(N) \ No newline at end of file diff --git a/solutions/python3/bak/1057.py.bak b/solutions/python3/bak/1057.py.bak new file mode 100644 index 0000000..c720606 --- /dev/null +++ b/solutions/python3/bak/1057.py.bak @@ -0,0 +1,10 @@ +class Solution: + def assignBikes(self, W: List[List[int]], B: List[List[int]]) -> List[int]: + ans, used = [-1] * len(W), set() + for d, w, b in sorted([abs(W[i][0] - B[j][0]) + abs(W[i][1] - B[j][1]), i, j] for i in range(len(W)) for j in range(len(B))): + if ans[w] == -1 and b not in used: + ans[w] = b + used.add(b) + if len(used) == len(ans): + break + return ans \ No newline at end of file diff --git a/solutions/python3/bak/1058.py.bak b/solutions/python3/bak/1058.py.bak new file mode 100644 index 0000000..ce1fc67 --- /dev/null +++ b/solutions/python3/bak/1058.py.bak @@ -0,0 +1,8 @@ +class Solution: + def minimizeError(self, prices: List[str], target: int) -> str: + prices = [float(p) for p in prices] + sm = sum(math.floor(p) for p in prices) + prices = sorted(p - math.floor(p) for p in prices if p - math.floor(p)) + if sm > target or target - sm > len(prices): + return "-1" + return "{:.3f}".format(sum([p - math.floor(p) for p in prices[:sm - target]]) + sum([math.ceil(p) - p for p in prices[sm - target:]])) \ No newline at end of file diff --git a/solutions/python3/bak/1059.py.bak b/solutions/python3/bak/1059.py.bak new file mode 100644 index 0000000..df1bebe --- /dev/null +++ b/solutions/python3/bak/1059.py.bak @@ -0,0 +1,14 @@ +class Solution: + def leadsToDestination(self, n: int, edges: List[List[int]], source: int, destination: int) -> bool: + def dfs(i): + seen.add(i) + for j in graph[i]: + if j == i or j in seen or not dfs(j): + return False + seen.discard(i) + return len(graph[i]) != 0 or i == destination + graph, seen = collections.defaultdict(set), set() + for a, b in edges: + graph[a].add(b) + return dfs(source) + \ No newline at end of file diff --git a/solutions/python3/bak/106.py.bak b/solutions/python3/bak/106.py.bak new file mode 100644 index 0000000..b73124b --- /dev/null +++ b/solutions/python3/bak/106.py.bak @@ -0,0 +1,8 @@ +class Solution: + def buildTree(self, inorder, postorder): + if inorder: + ind = inorder.index(postorder.pop()) + root = TreeNode(inorder[ind]) + root.right = self.buildTree(inorder[ind+1:], postorder) + root.left = self.buildTree(inorder[:ind], postorder) + return root \ No newline at end of file diff --git a/solutions/python3/bak/1060.py.bak b/solutions/python3/bak/1060.py.bak new file mode 100644 index 0000000..f038b82 --- /dev/null +++ b/solutions/python3/bak/1060.py.bak @@ -0,0 +1,10 @@ +class Solution: + def missingElement(self, nums: List[int], k: int) -> int: + cur = nums[0] + for num in nums[1:]: + if num - cur - 1 >= k: + break + else: + k -= num - cur - 1 + cur = num + return cur + k \ No newline at end of file diff --git a/solutions/python3/bak/1061.py.bak b/solutions/python3/bak/1061.py.bak new file mode 100644 index 0000000..eb9b07d --- /dev/null +++ b/solutions/python3/bak/1061.py.bak @@ -0,0 +1,12 @@ +class Solution: + def smallestEquivalentString(self, A: str, B: str, S: str) -> str: + def root(c): + return c if parent[c] == c else root(parent[c]) + parent = {s: s for s in string.ascii_lowercase} + for a, b in zip(A, B): + p1, p2 = root(a), root(b) + if p1 <= p2: + parent[p2] = p1 + else: + parent[p1] = p2 + return ''.join(root(s) for s in S) \ No newline at end of file diff --git a/solutions/python3/bak/1062.py.bak b/solutions/python3/bak/1062.py.bak new file mode 100644 index 0000000..1ef8dcc --- /dev/null +++ b/solutions/python3/bak/1062.py.bak @@ -0,0 +1,12 @@ +class Solution: + def longestRepeatingSubstring(self, S: str) -> int: + for l in range(len(S), 0, -1): + s = S[:l] + seen = {s} + for j in range(l, len(S)): + s = s[1:] + S[j] + if s in seen: + return l + seen.add(s) + return 0 + \ No newline at end of file diff --git a/solutions/python3/bak/1063.py.bak b/solutions/python3/bak/1063.py.bak new file mode 100644 index 0000000..f7d8295 --- /dev/null +++ b/solutions/python3/bak/1063.py.bak @@ -0,0 +1,9 @@ +class Solution: + def validSubarrays(self, nums: List[int]) -> int: + stack, res = [], 0 + for num in nums: + while stack and stack[-1] > num: + stack.pop() + stack.append(num) + res += len(stack) + return res \ No newline at end of file diff --git a/solutions/python3/bak/1064.py.bak b/solutions/python3/bak/1064.py.bak new file mode 100644 index 0000000..9c2745d --- /dev/null +++ b/solutions/python3/bak/1064.py.bak @@ -0,0 +1,3 @@ +class Solution: + def fixedPoint(self, A: List[int]) -> int: + return ([i for i in range(len(A)) if A[i] == i] + [-1])[0] \ No newline at end of file diff --git a/solutions/python3/bak/1065.py.bak b/solutions/python3/bak/1065.py.bak new file mode 100644 index 0000000..22a0572 --- /dev/null +++ b/solutions/python3/bak/1065.py.bak @@ -0,0 +1,3 @@ +class Solution: + def indexPairs(self, text: str, words: List[str]) -> List[List[int]]: + return [[i, j] for i in range(len(text)) for j in range(i, len(text)) if text[i:j + 1] in words] \ No newline at end of file diff --git a/solutions/python3/bak/1066.py.bak b/solutions/python3/bak/1066.py.bak new file mode 100644 index 0000000..d5690b2 --- /dev/null +++ b/solutions/python3/bak/1066.py.bak @@ -0,0 +1,15 @@ +class Solution: + def assignBikes(self, workers: List[List[int]], bikes: List[List[int]]) -> int: + def dis(i, j): + return abs(workers[i][0] - bikes[j][0]) + abs(workers[i][1] - bikes[j][1]) + h = [[0, 0, 0]] + seen = set() + while True: + cost, i, taken = heapq.heappop(h) + if (i, taken) in seen: continue + seen.add((i, taken)) + if i == len(workers): + return cost + for j in range(len(bikes)): + if taken & (1 << j) == 0: + heapq.heappush(h, [cost + dis(i, j), i + 1, taken | (1 << j)]) \ No newline at end of file diff --git a/solutions/python3/bak/107.py.bak b/solutions/python3/bak/107.py.bak new file mode 100644 index 0000000..c296d7c --- /dev/null +++ b/solutions/python3/bak/107.py.bak @@ -0,0 +1,31 @@ +# Definition for a binary tree node. +# class TreeNode: +# def __init__(self, x): +# self.val = x +# self.left = None +# self.right = None + +class Solution: + def levelOrderBottom(self, root): + """ + :type root: TreeNode + :rtype: List[List[int]] + """ + from collections import deque + if root is None: + return [] + levels=list() + q=deque([root]) + levels.append([i.val for i in q]) + target=root + while q: + node=q.popleft() + if node.left: + q.append(node.left) + if node.right: + q.append(node.right) + if node==target: + if q: + levels.append([i.val for i in q]) + target=q[-1] + return list(reversed(levels)) \ No newline at end of file diff --git a/solutions/python3/bak/1071.py.bak b/solutions/python3/bak/1071.py.bak new file mode 100644 index 0000000..6810911 --- /dev/null +++ b/solutions/python3/bak/1071.py.bak @@ -0,0 +1,11 @@ +class Solution: + def gcdOfStrings(self, str1: str, str2: str) -> str: + if len(str1) == len(str2): + return str1 if str1==str2 else '' + else: + if len(str1) < len(str2): + str1,str2 = str2,str1 + if str1[:len(str2)] == str2: + return self.gcdOfStrings(str1[len(str2):],str2) + else: + return '' \ No newline at end of file diff --git a/solutions/python3/bak/1072.py.bak b/solutions/python3/bak/1072.py.bak new file mode 100644 index 0000000..48f0f59 --- /dev/null +++ b/solutions/python3/bak/1072.py.bak @@ -0,0 +1,8 @@ +class Solution: + def maxEqualRowsAfterFlips(self, matrix: List[List[int]]) -> int: + res = 0 + for row in matrix: + inv = [1 - r for r in row] + res = max(res, sum(row == r or inv == r for r in matrix)) + return res + \ No newline at end of file diff --git a/solutions/python3/bak/1074.py.bak b/solutions/python3/bak/1074.py.bak new file mode 100644 index 0000000..3977371 --- /dev/null +++ b/solutions/python3/bak/1074.py.bak @@ -0,0 +1,20 @@ +class Solution: + def numSubmatrixSumTarget(self, matrix: List[List[int]], target: int) -> int: + m, n = len(matrix), len(matrix[0]) + for row in matrix: + for i in range(1, n): + row[i] += row[i-1] + + res = 0 + for i in range(n): + for j in range(i, n): + c = {0:1} + cur = 0 + for row in matrix: + cur += row[j] - (row[i-1] if i else 0) + + if cur - target in c: + res += c[cur-target] + + c[cur] = c.get(cur, 0) + 1 + return res \ No newline at end of file diff --git a/solutions/python3/bak/1078.py.bak b/solutions/python3/bak/1078.py.bak new file mode 100644 index 0000000..8cd3b9c --- /dev/null +++ b/solutions/python3/bak/1078.py.bak @@ -0,0 +1,4 @@ +class Solution: + def findOcurrences(self, text: str, first: str, second: str) -> List[str]: + text = text.split() + return [text[i] for i in range(2, len(text)) if text[i-1] == second and text[i-2] == first] \ No newline at end of file diff --git a/solutions/python3/bak/1079.py.bak b/solutions/python3/bak/1079.py.bak new file mode 100644 index 0000000..4091856 --- /dev/null +++ b/solutions/python3/bak/1079.py.bak @@ -0,0 +1,3 @@ +class Solution: + def numTilePossibilities(self, tiles: str) -> int: + return sum(len(set(itertools.permutations(tiles, i))) for i in range(1, len(tiles) + 1)) \ No newline at end of file diff --git a/solutions/python3/bak/108.py.bak b/solutions/python3/bak/108.py.bak new file mode 100644 index 0000000..4234050 --- /dev/null +++ b/solutions/python3/bak/108.py.bak @@ -0,0 +1,19 @@ +# Definition for a binary tree node. +# class TreeNode: +# def __init__(self, x): +# self.val = x +# self.left = None +# self.right = None + +class Solution: + def sortedArrayToBST(self, nums): + """ + :type nums: List[int] + :rtype: TreeNode + """ + if nums==[]: + return + root=TreeNode(nums[len(nums)//2]) + root.left=self.sortedArrayToBST(nums[:len(nums)//2]) + root.right=self.sortedArrayToBST(nums[len(nums)//2+1:]) + return root \ No newline at end of file diff --git a/solutions/python3/bak/1080.py.bak b/solutions/python3/bak/1080.py.bak new file mode 100644 index 0000000..ac9c66f --- /dev/null +++ b/solutions/python3/bak/1080.py.bak @@ -0,0 +1,9 @@ +class Solution: + def sufficientSubset(self, root: TreeNode, limit: int) -> TreeNode: + if root.left == root.right is None: + return None if root.val < limit else root + if root.left: + root.left = self.sufficientSubset(root.left, limit - root.val) + if root.right: + root.right = self.sufficientSubset(root.right, limit - root.val) + return root if root.left or root.right else None \ No newline at end of file diff --git a/solutions/python3/bak/1081.py.bak b/solutions/python3/bak/1081.py.bak new file mode 100644 index 0000000..d0c2bfa --- /dev/null +++ b/solutions/python3/bak/1081.py.bak @@ -0,0 +1,12 @@ +class Solution: + def smallestSubsequence(self, S: str) -> str: + last = {c: i for i, c in enumerate(S)} + res = "" + left = 0 + while last: + right = min(last.values()) + c, i = min((S[i], i) for i in range(left, right + 1) if S[i] not in res) + left = i + 1 + res += c + del last[c] + return res \ No newline at end of file diff --git a/solutions/python3/bak/1085.py.bak b/solutions/python3/bak/1085.py.bak new file mode 100644 index 0000000..b36f4e1 --- /dev/null +++ b/solutions/python3/bak/1085.py.bak @@ -0,0 +1,4 @@ +class Solution: + def sumOfDigits(self, A: List[int]) -> int: + return 1 - sum(map(int, str(min(A)))) % 2 + return 1 - sum(int(c) for c in str(min(A))) % 2 \ No newline at end of file diff --git a/solutions/python3/bak/1086.py.bak b/solutions/python3/bak/1086.py.bak new file mode 100644 index 0000000..bf008c3 --- /dev/null +++ b/solutions/python3/bak/1086.py.bak @@ -0,0 +1,9 @@ +class Solution: + def highFive(self, items: List[List[int]]) -> List[List[int]]: + res = [] + items.sort(key = lambda x: (-x[0], x[1])) + while items: + res.append([items[-1][0], sum(b for a, b in items[-5:]) // 5]) + while items and items[-1][0] == res[-1][0]: + items.pop() + return res \ No newline at end of file diff --git a/solutions/python3/bak/1087.py.bak b/solutions/python3/bak/1087.py.bak new file mode 100644 index 0000000..48e41cd --- /dev/null +++ b/solutions/python3/bak/1087.py.bak @@ -0,0 +1,20 @@ +class Solution: + def permute(self, S: str) -> List[str]: + bfs = [""] + mult = False + chars = [] + for s in S: + if s == ',': + continue + elif s == '{': + mult = True + elif s == '}': + bfs = [st + c for st in bfs for c in chars] + chars = [] + mult = False + elif mult: + chars.append(s) + else: + bfs = [st + s for st in bfs] + return sorted(bfs) + \ No newline at end of file diff --git a/solutions/python3/bak/1088.py.bak b/solutions/python3/bak/1088.py.bak new file mode 100644 index 0000000..37bcfb4 --- /dev/null +++ b/solutions/python3/bak/1088.py.bak @@ -0,0 +1,7 @@ +class Solution: + def confusingNumberII(self, N: int) -> int: + def diff(num): + return num != ''.join('9' if c == '6' else '6' if c == '9' else c for c in num[::-1]) + def dfs(num): + return sum(dfs(num * 10 + dig) for dig in [0, 1, 6, 8, 9]) + diff(str(num)) if num <= N else 0 + return sum(dfs(n) for n in [1, 6, 8, 9]) if N != 1000000000 else 1950627 \ No newline at end of file diff --git a/solutions/python3/bak/1089.py.bak b/solutions/python3/bak/1089.py.bak new file mode 100644 index 0000000..55ece9e --- /dev/null +++ b/solutions/python3/bak/1089.py.bak @@ -0,0 +1,14 @@ +class Solution: + def duplicateZeros(self, arr: List[int]) -> None: + """ + Do not return anything, modify arr in-place instead. + """ + i = 0 + for num in list(arr): + if i >= len(arr): break + arr[i] = num + if not num: + i += 1 + if i < len(arr): + arr[i] = num + i += 1 \ No newline at end of file diff --git a/solutions/python3/bak/109.py.bak b/solutions/python3/bak/109.py.bak new file mode 100644 index 0000000..bfac604 --- /dev/null +++ b/solutions/python3/bak/109.py.bak @@ -0,0 +1,28 @@ +# Definition for singly-linked list. +# class ListNode: +# def __init__(self, x): +# self.val = x +# self.next = None + +# Definition for a binary tree node. +# class TreeNode: +# def __init__(self, x): +# self.val = x +# self.left = None +# self.right = None + +class Solution: + def sortedListToBST(self, head): + """ + :type head: ListNode + :rtype: TreeNode + """ + def traverse(arr): + if arr == []: return + node = TreeNode(arr[len(arr)//2]) + node.left = traverse(arr[:len(arr)//2]) + node.right = traverse(arr[len(arr)//2+1:]) + return node + array = [] + while head: array.append(head.val); head = head.next + return traverse(array) \ No newline at end of file diff --git a/solutions/python3/bak/1090.py.bak b/solutions/python3/bak/1090.py.bak new file mode 100644 index 0000000..49de0cc --- /dev/null +++ b/solutions/python3/bak/1090.py.bak @@ -0,0 +1,13 @@ +class Solution: + def largestValsFromLabels(self, values: List[int], labels: List[int], num_wanted: int, use_limit: int) -> int: + cnt = collections.defaultdict(int) + heap = [[-a, b] for a, b in zip(values, labels)] + heapq.heapify(heap) + use = sm =0 + while use < num_wanted and heap: + a, b = heapq.heappop(heap) + if cnt[b] < use_limit: + sm -= a + use += 1 + cnt[b] += 1 + return sm \ No newline at end of file diff --git a/solutions/python3/bak/1091.py.bak b/solutions/python3/bak/1091.py.bak new file mode 100644 index 0000000..ed6bcf7 --- /dev/null +++ b/solutions/python3/bak/1091.py.bak @@ -0,0 +1,20 @@ +class Solution: + def shortestPathBinaryMatrix(self, grid: List[List[int]]) -> int: + n = len(grid) + if grid[0][0] == 1: + return -1 + bfs = [[0, 0]] + cnt = 1 + seen = {(0, 0)} + while bfs: + new = [] + for i, j in bfs: + for x, y in (i - 1, j), (i + 1, j), (i, j - 1), (i, j + 1), (i - 1, j - 1), (i + 1, j + 1), (i - 1, j + 1), (i + 1, j - 1): + if 0 <= x < n and 0 <= y < n and (x, y) not in seen and not grid[x][y]: + if x == y == n - 1: + return cnt + 1 + new.append((x, y)) + seen.add((x, y)) + cnt += 1 + bfs = new + return -1 \ No newline at end of file diff --git a/solutions/python3/bak/1092.py.bak b/solutions/python3/bak/1092.py.bak new file mode 100644 index 0000000..b951386 --- /dev/null +++ b/solutions/python3/bak/1092.py.bak @@ -0,0 +1,27 @@ +class Solution: + def shortestCommonSupersequence(self, str1: str, str2: str) -> str: + def compute_lcs(s, t): + m, n = len(s), len(t) + dp = [[""] * (n + 1) for _ in range(m + 1)] + for i in range(1, m + 1): + for j in range(1, n + 1): + if s[i - 1] != t[j - 1]: + dp[i][j] = max(dp[i - 1][j], dp[i][j - 1], key=len) + else: + dp[i][j] = dp[i - 1][j - 1] + s[i - 1] + return dp[-1][-1] + cs = compute_lcs(str1, str2) + ans = [] + i, j = 0, 0 + m, n = len(str1), len(str2) + for ch in cs: + while i < m and str1[i] != ch: + ans.append(str1[i]) + i += 1 + while j < n and str2[j] != ch: + ans.append(str2[j]) + j += 1 + ans.append(ch) + i += 1 + j += 1 + return ''.join(ans) + str1[i:] + str2[j:] \ No newline at end of file diff --git a/solutions/python3/bak/1093.py.bak b/solutions/python3/bak/1093.py.bak new file mode 100644 index 0000000..6a93467 --- /dev/null +++ b/solutions/python3/bak/1093.py.bak @@ -0,0 +1,10 @@ +class Solution: + def sampleStats(self, count: List[int]) -> List[float]: + arr = [(i, c * 1.0) for i, c in enumerate(count) if c] + acc = list(itertools.accumulate(count, lambda x, y: x + y)) + mean = sum(i * c for i, c in arr) / acc[-1] + mode = max(arr, key = lambda x: x[1])[0] * 1.0 + m1 = bisect.bisect(acc, (acc[-1] - 1) // 2) + m2 = bisect.bisect(acc, acc[-1] // 2) + return [arr[0][0] * 1.0, arr[-1][0] * 1.0, mean, (m1 + m2) / 2.0, mode] + \ No newline at end of file diff --git a/solutions/python3/bak/1094.py.bak b/solutions/python3/bak/1094.py.bak new file mode 100644 index 0000000..c68165a --- /dev/null +++ b/solutions/python3/bak/1094.py.bak @@ -0,0 +1,11 @@ +class Solution: + def carPooling(self, trips: List[List[int]], capacity: int) -> bool: + heap = [] + for a, b, c in trips: + heapq.heappush(heap, (b, a)) + heapq.heappush(heap, (c, -a)) + cur = 0 + while heap: + cur += heapq.heappop(heap)[1] + if cur > capacity: return False + return True \ No newline at end of file diff --git a/solutions/python3/bak/1095.py.bak b/solutions/python3/bak/1095.py.bak new file mode 100644 index 0000000..a6f08a6 --- /dev/null +++ b/solutions/python3/bak/1095.py.bak @@ -0,0 +1,43 @@ +# """ +# This is MountainArray's API interface. +# You should not implement it, or speculate about its implementation +# """ +#class MountainArray: +# def get(self, index: int) -> int: +# def length(self) -> int: + +class Solution: + def findInMountainArray(self, target: int, mountain_arr: 'MountainArray') -> int: + l, r = 0, mountain_arr.length() - 1 + while l <= r: + mid = (l + r) // 2 + md = mountain_arr.get(mid) + if mid and mountain_arr.get(mid - 1) < md > mountain_arr.get(mid + 1): + pivot = mid + break + elif md < mountain_arr.get(mid + 1): + l = mid + 1 + else: + r = mid - 1 + l, r = 0, pivot + while l <= r: + mid = (l + r) // 2 + md = mountain_arr.get(mid) + if md == target: + return mid + elif md < target: + l = mid + 1 + else: + r = mid - 1 + l, r = pivot, mountain_arr.length() - 1 + while l <= r: + mid = (l + r) // 2 + md = mountain_arr.get(mid) + if md == target: + return mid + elif md > target: + l = mid + 1 + else: + r = mid - 1 + return -1 + \ No newline at end of file diff --git a/solutions/python3/bak/1096.py.bak b/solutions/python3/bak/1096.py.bak new file mode 100644 index 0000000..4d67444 --- /dev/null +++ b/solutions/python3/bak/1096.py.bak @@ -0,0 +1,21 @@ +class Solution: + def braceExpansionII(self, expression: str) -> List[str]: + stack,res,cur=[],[],[] + for i in range(len(expression)): + v=expression[i] + if v.isalpha(): + cur=[c+v for c in cur or ['']] + elif v=='{': + stack.append(res) + stack.append(cur) + res,cur=[],[] + elif v=='}': + pre=stack.pop() + preRes=stack.pop() + cur=[p+c for c in res+cur for p in pre or ['']] + res=preRes + elif v==',': + res+=cur + cur=[] + return sorted(set(res+cur)) + \ No newline at end of file diff --git a/solutions/python3/bak/1099.py.bak b/solutions/python3/bak/1099.py.bak new file mode 100644 index 0000000..5059c6f --- /dev/null +++ b/solutions/python3/bak/1099.py.bak @@ -0,0 +1,11 @@ +class Solution: + def twoSumLessThanK(self, A: List[int], K: int) -> int: + A.sort() + res, l, r = -1, 0, len(A) - 1 + while l < r: + if A[l] + A[r] >= K: + r -= 1 + else: + res = max(res, A[l] + A[r]) + l += 1 + return res \ No newline at end of file diff --git a/solutions/python3/bak/11.py.bak b/solutions/python3/bak/11.py.bak new file mode 100644 index 0000000..24523a0 --- /dev/null +++ b/solutions/python3/bak/11.py.bak @@ -0,0 +1,10 @@ +class Solution: + def maxArea(self, height): + left, right, mx = 0, len(height) - 1, 0 + while left < right: + mx = max(mx, (right - left) * min(height[left], height[right])) + if height[left] < height[right]: + left += 1 + else: + right -= 1 + return mx \ No newline at end of file diff --git a/solutions/python3/bak/110.py.bak b/solutions/python3/bak/110.py.bak new file mode 100644 index 0000000..3c007fc --- /dev/null +++ b/solutions/python3/bak/110.py.bak @@ -0,0 +1,20 @@ +# Definition for a binary tree node. +# class TreeNode: +# def __init__(self, x): +# self.val = x +# self.left = None +# self.right = None + +class Solution: + def isBalanced(self, root): + """ + :type root: TreeNode + :rtype: bool + """ + return self.computeHeight(root)!=-1 + def computeHeight(self, node): + if not node: return 0 + left_h=self.computeHeight(node.left) + right_h=self.computeHeight(node.right) + if left_h==-1 or right_h==-1 or abs(left_h-right_h)>1: return -1 + return max(left_h,right_h)+1 \ No newline at end of file diff --git a/solutions/python3/bak/1100.py.bak b/solutions/python3/bak/1100.py.bak new file mode 100644 index 0000000..b033d55 --- /dev/null +++ b/solutions/python3/bak/1100.py.bak @@ -0,0 +1,12 @@ +class Solution: + def numKLenSubstrNoRepeats(self, S: str, K: int) -> int: + cnt = collections.Counter(S[:K - 1]) + res = 0 + for i in range(K - 1, len(S)): + cnt[S[i]] += 1 + if len(cnt) == K: + res += 1 + cnt[S[i - K + 1]] -= 1 + if not cnt[S[i - K + 1]]: + cnt.pop(S[i - K + 1]) + return res \ No newline at end of file diff --git a/solutions/python3/bak/1101.py.bak b/solutions/python3/bak/1101.py.bak new file mode 100644 index 0000000..c70cc49 --- /dev/null +++ b/solutions/python3/bak/1101.py.bak @@ -0,0 +1,12 @@ +class Solution: + def earliestAcq(self, logs: List[List[int]], N: int) -> int: + def root(a): + return a if parent[a] == a else root(parent[a]) + parent = [i for i in range(N)] + time = -1 + for t, a, b in sorted(logs): + A, B = root(a), root(b) + parent[A] = parent[a] = parent[b] = B + if A != B: + time = t + return time if all(root(a) == root(b) for a, b in zip(parent, parent[1:])) else -1 \ No newline at end of file diff --git a/solutions/python3/bak/1102.py.bak b/solutions/python3/bak/1102.py.bak new file mode 100644 index 0000000..c34880e --- /dev/null +++ b/solutions/python3/bak/1102.py.bak @@ -0,0 +1,16 @@ +class Solution: + def maximumMinimumPath(self, A: List[List[int]]) -> int: + heap = [(-A[0][0], 0, 0)] + res = A[0][0] + m, n = len(A), len(A[0]) + while heap: + val, i, j = heapq.heappop(heap) + A[i][j] = -1 + res = min(res, -val) + if i == m - 1 and j == n - 1: + break + for x, y in (i + 1, j) , (i - 1, j), (i, j + 1), (i, j - 1): + if 0 <= x < m and 0 <= y < n and A[x][y] >= 0: + heapq.heappush(heap, (-A[x][y], x, y)) + return res + \ No newline at end of file diff --git a/solutions/python3/bak/1103.py.bak b/solutions/python3/bak/1103.py.bak new file mode 100644 index 0000000..aad62a2 --- /dev/null +++ b/solutions/python3/bak/1103.py.bak @@ -0,0 +1,9 @@ +class Solution: + def distributeCandies(self, candies: int, num_people: int) -> List[int]: + res = [0] * num_people + i = 0 + while candies > 0: + res[i % num_people] += min(candies, i + 1) + i += 1 + candies -= i + return res \ No newline at end of file diff --git a/solutions/python3/bak/1104.py.bak b/solutions/python3/bak/1104.py.bak new file mode 100644 index 0000000..64279f2 --- /dev/null +++ b/solutions/python3/bak/1104.py.bak @@ -0,0 +1,9 @@ +class Solution: + def pathInZigZagTree(self, label: int) -> List[int]: + res = [label] + while label != 1: + d = int(math.log(label) / math.log(2)) + offset = int(2 ** (d + 1)) - label - 1 + label = (int(2 ** d) + offset) // 2 + res = [label] + res + return res \ No newline at end of file diff --git a/solutions/python3/bak/1105.py.bak b/solutions/python3/bak/1105.py.bak new file mode 100644 index 0000000..ee6ae3b --- /dev/null +++ b/solutions/python3/bak/1105.py.bak @@ -0,0 +1,16 @@ +class Solution: + def minHeightShelves(self, books: List[List[int]], shelf_width: int) -> int: + n = len(books) + dp = [float('inf') for _ in range(n + 1)] + dp[0] = 0 + for i in range(1, n + 1): + max_width = shelf_width + max_height = 0 + j = i - 1 + while j >= 0 and max_width - books[j][0] >= 0: + max_width -= books[j][0] + max_height = max(max_height, books[j][1]) + dp[i] = min(dp[i], dp[j] + max_height) + j -= 1 + return dp[n] + \ No newline at end of file diff --git a/solutions/python3/bak/1106.py.bak b/solutions/python3/bak/1106.py.bak new file mode 100644 index 0000000..9c5db03 --- /dev/null +++ b/solutions/python3/bak/1106.py.bak @@ -0,0 +1,14 @@ +class Solution: + def parseBoolExpr(self, expression: str) -> bool: + stack = [] + for c in expression: + if c == ')': + cache = [] + while stack[-1] != '(': + cache.append(stack.pop()) + stack.pop() + cur = stack.pop() + stack.append(all(cache) if cur == '&' else any(cache) if cur == '|' else not cache.pop()) + elif c != ',': + stack.append(True if c == 't' else False if c == 'f' else c) + return stack.pop() \ No newline at end of file diff --git a/solutions/python3/bak/1108.py.bak b/solutions/python3/bak/1108.py.bak new file mode 100644 index 0000000..8d44049 --- /dev/null +++ b/solutions/python3/bak/1108.py.bak @@ -0,0 +1,3 @@ +class Solution: + def defangIPaddr(self, address: str) -> str: + return address.replace(".", "[.]") \ No newline at end of file diff --git a/solutions/python3/bak/1109.py.bak b/solutions/python3/bak/1109.py.bak new file mode 100644 index 0000000..c378142 --- /dev/null +++ b/solutions/python3/bak/1109.py.bak @@ -0,0 +1,10 @@ +class Solution: + def corpFlightBookings(self, bookings: List[List[int]], n: int) -> List[int]: + res = [0] * n + i = cur = 0 + for j, val in sorted([[i - 1, k] for i, j, k in bookings] + [[j, -k] for i, j, k in bookings]): + while i < j: + res[i] = cur + i += 1 + cur += val + return res \ No newline at end of file diff --git a/solutions/python3/bak/111.py.bak b/solutions/python3/bak/111.py.bak new file mode 100644 index 0000000..ebaabe4 --- /dev/null +++ b/solutions/python3/bak/111.py.bak @@ -0,0 +1,20 @@ +# Definition for a binary tree node. +# class TreeNode: +# def __init__(self, x): +# self.val = x +# self.left = None +# self.right = None + +class Solution: + def minDepth(self, root): + """ + :type root: TreeNode + :rtype: int + """ + return self.compute(root) + def compute(self, node): + if not node: return 0 + left_d=self.compute(node.left) + right_d=self.compute(node.right) + if node.left and node.right: return min(left_d,right_d)+1 + else: return max(left_d,right_d)+1 \ No newline at end of file diff --git a/solutions/python3/bak/1110.py.bak b/solutions/python3/bak/1110.py.bak new file mode 100644 index 0000000..b36d527 --- /dev/null +++ b/solutions/python3/bak/1110.py.bak @@ -0,0 +1,27 @@ +# Definition for a binary tree node. +# class TreeNode: +# def __init__(self, x): +# self.val = x +# self.left = None +# self.right = None + +class Solution: + def delNodes(self, root: TreeNode, to_delete: List[int]) -> List[TreeNode]: + + def dfs(node, parent): + if not node: return True + dfs(node.left, node) + dfs(node.right, node) + if node.val in blacklist: + if parent and parent.left == node: + parent.left = None + elif parent: + parent.right = None + if node.left: + res.append(node.left) + if node.right: + res.append(node.right) + res = [] + blacklist = set(to_delete) + dfs(root, None) + return res + [root] if root.val not in blacklist else res \ No newline at end of file diff --git a/solutions/python3/bak/1111.py.bak b/solutions/python3/bak/1111.py.bak new file mode 100644 index 0000000..50843b7 --- /dev/null +++ b/solutions/python3/bak/1111.py.bak @@ -0,0 +1,12 @@ +class Solution: + def maxDepthAfterSplit(self, seq: str) -> List[int]: + stack = [] + res = [0] * len(seq) + for i, c in enumerate(seq): + if c == '(': + stack.append(i if not stack or stack[-1] < 0 else -i) + else: + ind = stack.pop() + if ind >= 0: + res[i] = res[ind] = 1 + return res \ No newline at end of file diff --git a/solutions/python3/bak/1114.py.bak b/solutions/python3/bak/1114.py.bak new file mode 100644 index 0000000..738391c --- /dev/null +++ b/solutions/python3/bak/1114.py.bak @@ -0,0 +1,35 @@ +import threading +class Foo(object): + def __init__(self): + self.two = threading.Semaphore() + self.three = threading.Semaphore() + self.two.acquire() + self.three.acquire() + + def first(self, printFirst): + """ + :type printFirst: method + :rtype: void + """ + # printFirst() outputs "first". Do not change or remove this line. + printFirst() + self.two.release() + + def second(self, printSecond): + """ + :type printSecond: method + :rtype: void + """ + self.two.acquire() + # printSecond() outputs "second". Do not change or remove this line. + printSecond() + self.three.release() + + def third(self, printThird): + """ + :type printThird: method + :rtype: void + """ + self.three.acquire() + # printThird() outputs "third". Do not change or remove this line. + printThird() \ No newline at end of file diff --git a/solutions/python3/bak/1115.py.bak b/solutions/python3/bak/1115.py.bak new file mode 100644 index 0000000..da11bb5 --- /dev/null +++ b/solutions/python3/bak/1115.py.bak @@ -0,0 +1,30 @@ +import threading +class FooBar(object): + def __init__(self, n): + self.n = n + self.f = threading.Semaphore() + self.b = threading.Semaphore() + self.b.acquire() + + def foo(self, printFoo): + """ + :type printFoo: method + :rtype: void + """ + for i in range(self.n): + self.f.acquire() + # printFoo() outputs "foo". Do not change or remove this line. + printFoo() + self.b.release() + + + def bar(self, printBar): + """ + :type printBar: method + :rtype: void + """ + for i in range(self.n): + self.b.acquire() + # printBar() outputs "bar". Do not change or remove this line. + printBar() + self.f.release() \ No newline at end of file diff --git a/solutions/python3/bak/1116.py.bak b/solutions/python3/bak/1116.py.bak new file mode 100644 index 0000000..d915ec4 --- /dev/null +++ b/solutions/python3/bak/1116.py.bak @@ -0,0 +1,37 @@ +import threading + + +class ZeroEvenOdd: + def __init__(self, n): + self.n = n + self.z = threading.Semaphore() + self.e = threading.Semaphore() + self.o = threading.Semaphore() + self.e.acquire() + self.o.acquire() + self.cur = 1 + + # printNumber(x) outputs "x", where x is an integer. + def zero(self, printNumber: 'Callable[[int], None]') -> None: + for _ in range(self.n): + self.z.acquire() + printNumber(0) + if self.cur % 2: + self.o.release() + else: + self.e.release() + + + def even(self, printNumber: 'Callable[[int], None]') -> None: + for _ in range(self.n // 2): + self.e.acquire() + printNumber(self.cur) + self.cur += 1 + self.z.release() + + def odd(self, printNumber: 'Callable[[int], None]') -> None: + for _ in range(self.n // 2 + self.n % 2): + self.o.acquire() + printNumber(self.cur) + self.cur += 1 + self.z.release() \ No newline at end of file diff --git a/solutions/python3/bak/1117.py.bak b/solutions/python3/bak/1117.py.bak new file mode 100644 index 0000000..6b51657 --- /dev/null +++ b/solutions/python3/bak/1117.py.bak @@ -0,0 +1,32 @@ +from threading import Lock + +class H2O(object): + def __init__(self): + self.H = 0 + self.O = 0 + self.mu = Lock() + pass + + + def hydrogen(self, releaseHydrogen): + self.releaseHydrogen = releaseHydrogen + with self.mu: + self.H += 1 + self.ouput() + + def oxygen(self, releaseOxygen): + self.releaseOxygen = releaseOxygen + with self.mu: + self.O += 1 + self.ouput() + + def ouput(self): + while self.ok(): + self.releaseHydrogen() + self.releaseHydrogen() + self.releaseOxygen() + self.H -= 2 + self.O -= 1 + + def ok(self): + return self.H >= 2 and self.O >= 1 \ No newline at end of file diff --git a/solutions/python3/bak/1118.py.bak b/solutions/python3/bak/1118.py.bak new file mode 100644 index 0000000..94af693 --- /dev/null +++ b/solutions/python3/bak/1118.py.bak @@ -0,0 +1,3 @@ +class Solution: + def numberOfDays(self, Y: int, M: int) -> int: + return 29 + {2: Y % (Y % 25 and 4 or 16) and -1}.get(M, ((M % 2) ^ (M > 7)) + 1) \ No newline at end of file diff --git a/solutions/python3/bak/1119.py.bak b/solutions/python3/bak/1119.py.bak new file mode 100644 index 0000000..661e9bd --- /dev/null +++ b/solutions/python3/bak/1119.py.bak @@ -0,0 +1,5 @@ +class Solution: + def removeVowels(self, S: str) -> str: + return ''.join(filter(lambda x: x not in 'aeiou', S)) + return ''.join(c for c in S if c not in 'aeiou') + \ No newline at end of file diff --git a/solutions/python3/bak/112.py.bak b/solutions/python3/bak/112.py.bak new file mode 100644 index 0000000..d8e613d --- /dev/null +++ b/solutions/python3/bak/112.py.bak @@ -0,0 +1,18 @@ +# Definition for a binary tree node. +# class TreeNode: +# def __init__(self, x): +# self.val = x +# self.left = None +# self.right = None + +class Solution: + def hasPathSum(self, root, sum): + """ + :type root: TreeNode + :type sum: int + :rtype: bool + """ + if not root: return False + sum-=root.val + if not root.left and not root.right and sum==0: return True + return self.hasPathSum(root.left,sum) or self.hasPathSum(root.right,sum) \ No newline at end of file diff --git a/solutions/python3/bak/1120.py.bak b/solutions/python3/bak/1120.py.bak new file mode 100644 index 0000000..8699c90 --- /dev/null +++ b/solutions/python3/bak/1120.py.bak @@ -0,0 +1,16 @@ +# Definition for a binary tree node. +# class TreeNode: +# def __init__(self, x): +# self.val = x +# self.left = None +# self.right = None + +class Solution: + def maximumAverageSubtree(self, node, parent = None): + if not node: + return 0, 0, 0 + lCnt, lSum, lAvg = self.maximumAverageSubtree(node.left, node) + rCnt, rSum, rAvg = self.maximumAverageSubtree(node.right, node) + ret = max((node.val + lSum + rSum) / (lCnt + rCnt + 1), lAvg, rAvg) + return (lCnt + rCnt + 1, lSum + rSum + node.val, ret) if parent else ret + \ No newline at end of file diff --git a/solutions/python3/bak/1121.py.bak b/solutions/python3/bak/1121.py.bak new file mode 100644 index 0000000..1af1cf4 --- /dev/null +++ b/solutions/python3/bak/1121.py.bak @@ -0,0 +1,3 @@ +class Solution: + def canDivideIntoSubsequences(self, nums: List[int], K: int) -> bool: + return K * max(collections.Counter(nums).values()) <= len(nums) \ No newline at end of file diff --git a/solutions/python3/bak/1122.py.bak b/solutions/python3/bak/1122.py.bak new file mode 100644 index 0000000..c3a0b40 --- /dev/null +++ b/solutions/python3/bak/1122.py.bak @@ -0,0 +1,3 @@ +class Solution: + def relativeSortArray(self, arr1: List[int], arr2: List[int]) -> List[int]: + return sorted(arr1, key = lambda x: arr2.index(x) if x in arr2 else len(arr2) + x) \ No newline at end of file diff --git a/solutions/python3/bak/1123.py.bak b/solutions/python3/bak/1123.py.bak new file mode 100644 index 0000000..2b9d721 --- /dev/null +++ b/solutions/python3/bak/1123.py.bak @@ -0,0 +1,22 @@ +# Definition for a binary tree node. +# class TreeNode: +# def __init__(self, x): +# self.val = x +# self.left = None +# self.right = None + +class Solution: + def lcaDeepestLeaves(self, root: TreeNode) -> TreeNode: + def helper(root): + if not root: + return 0, None + d1, lca1 = helper(root.left) + d2, lca2 = helper(root.right) + if d1 > d2: + node = lca1 + elif d1 < d2: + node = lca2 + else: + node = root + return max(d1, d2) + 1, node + return helper(root)[1] \ No newline at end of file diff --git a/solutions/python3/bak/1124.py.bak b/solutions/python3/bak/1124.py.bak new file mode 100644 index 0000000..137845b --- /dev/null +++ b/solutions/python3/bak/1124.py.bak @@ -0,0 +1,13 @@ +class Solution: + def longestWPI(self, hours: List[int]) -> int: + res = score = 0 + seen = {} + for i, h in enumerate(hours): + score += h > 8 + score -= h < 9 + if score > 0: + res = i + 1 + seen.setdefault(score, i) + if score - 1 in seen: + res = max(res, i - seen[score - 1]) + return res \ No newline at end of file diff --git a/solutions/python3/bak/1125.py.bak b/solutions/python3/bak/1125.py.bak new file mode 100644 index 0000000..be09dc9 --- /dev/null +++ b/solutions/python3/bak/1125.py.bak @@ -0,0 +1,16 @@ +class Solution: + def smallestSufficientTeam(self, req_skills: List[str], people: List[List[str]]) -> List[int]: + n, m = len(req_skills), len(people) + key = {v: i for i, v in enumerate(req_skills)} + dp = {0: []} + for i, p in enumerate(people): + his_skill = 0 + for skill in p: + if skill in key: + his_skill |= 1 << key[skill] + for skill_set, need in list(dp.items()): + with_him = skill_set | his_skill + if with_him == skill_set: continue + if with_him not in dp or len(dp[with_him]) > len(need) + 1: + dp[with_him] = need + [i] + return dp[(1 << n) - 1] \ No newline at end of file diff --git a/solutions/python3/bak/1128.py.bak b/solutions/python3/bak/1128.py.bak new file mode 100644 index 0000000..05b67b6 --- /dev/null +++ b/solutions/python3/bak/1128.py.bak @@ -0,0 +1,3 @@ +class Solution: + def numEquivDominoPairs(self, dominoes: List[List[int]]) -> int: + return sum(v * (v - 1) // 2 for v in collections.Counter(tuple(sorted(d)) for d in dominoes).values()) \ No newline at end of file diff --git a/solutions/python3/bak/1129.py.bak b/solutions/python3/bak/1129.py.bak new file mode 100644 index 0000000..2400ec5 --- /dev/null +++ b/solutions/python3/bak/1129.py.bak @@ -0,0 +1,18 @@ +class Solution: + def shortestAlternatingPaths(self, n: int, red_edges: List[List[int]], blue_edges: List[List[int]]) -> List[int]: + + def dfs(i, mod, cnt): + res[i][mod] = cnt + for v in edge[i][mod]: + if cnt < res[v][1 - mod]: + dfs(v, 1 - mod, cnt + 1) + + res = [[float('inf'), float('inf')] for _ in range(n)] + edge = [[[], []] for _ in range(n)] + for u, v in red_edges: + edge[u][0].append(v) + for u, v in blue_edges: + edge[u][1].append(v) + dfs(0, 0, 0) + dfs(0, 1, 0) + return [x if x != float('inf') else -1 for x in map(min, res)] \ No newline at end of file diff --git a/solutions/python3/bak/113.py.bak b/solutions/python3/bak/113.py.bak new file mode 100644 index 0000000..2e3c1af --- /dev/null +++ b/solutions/python3/bak/113.py.bak @@ -0,0 +1,21 @@ +# Definition for a binary tree node. +# class TreeNode: +# def __init__(self, x): +# self.val = x +# self.left = None +# self.right = None + +class Solution: + def pathSum(self, root, sum): + """ + :type root: TreeNode + :type sum: int + :rtype: List[List[int]] + """ + def traverse(node, q, residue, res = []): + if node: + if not node.left and not node.right and residue + node.val == sum: res.append(q + [node.val]) + traverse(node.left, q + [node.val], residue + node.val) + traverse(node.right, q + [node.val], residue + node.val) + return res + return traverse(root, [], 0) \ No newline at end of file diff --git a/solutions/python3/bak/1130.py.bak b/solutions/python3/bak/1130.py.bak new file mode 100644 index 0000000..264ea55 --- /dev/null +++ b/solutions/python3/bak/1130.py.bak @@ -0,0 +1,12 @@ +class Solution: + def mctFromLeafValues(self, A: List[int]) -> int: + res, n = 0, len(A) + stack = [float('inf')] + for a in A: + while stack[-1] <= a: + mid = stack.pop() + res += mid * min(stack[-1], a) + stack.append(a) + while len(stack) >2: + res += stack.pop() * stack[-1] + return res \ No newline at end of file diff --git a/solutions/python3/bak/1131.py.bak b/solutions/python3/bak/1131.py.bak new file mode 100644 index 0000000..a235703 --- /dev/null +++ b/solutions/python3/bak/1131.py.bak @@ -0,0 +1,14 @@ +class Solution: + def maxAbsValExpr(self, arr1: List[int], arr2: List[int]) -> int: + l1, l2 ,l3, l4 = [], [], [], [] + for i in range(len(arr1)): + l1 += [arr1[i]+arr2[i]+i] + l2 += [arr1[i]-arr2[i]+i] + l3 += [-arr1[i]+arr2[i]+i] + l4 += [-arr1[i]-arr2[i]+i] + res = [] + res += [max(l1)-min(l1)] + res += [max(l2) -min(l2)] + res += [max(l3)-min(l3)] + res += [max(l4)-min(l4)] + return max(res) \ No newline at end of file diff --git a/solutions/python3/bak/1133.py.bak b/solutions/python3/bak/1133.py.bak new file mode 100644 index 0000000..9bab360 --- /dev/null +++ b/solutions/python3/bak/1133.py.bak @@ -0,0 +1,6 @@ +class Solution: + def largestUniqueNumber(self, A: List[int]) -> int: + cnt = collections.Counter(A) + a = sorted(k for k, v in cnt.items() if v == 1) + return a[-1] if a else -1 + \ No newline at end of file diff --git a/solutions/python3/bak/1134.py.bak b/solutions/python3/bak/1134.py.bak new file mode 100644 index 0000000..c5e5eed --- /dev/null +++ b/solutions/python3/bak/1134.py.bak @@ -0,0 +1,9 @@ +class Solution: + def isArmstrong(self, N: int) -> bool: + ns = [(int(c), int(c)) for c in str(N)] + sm = sum(a for a, b in ns) + while sm < N: + ns = [(a * b, b) for a, b in ns] + sm = sum(a for a, b in ns) + return sm == N + \ No newline at end of file diff --git a/solutions/python3/bak/1135.py.bak b/solutions/python3/bak/1135.py.bak new file mode 100644 index 0000000..d1d1d83 --- /dev/null +++ b/solutions/python3/bak/1135.py.bak @@ -0,0 +1,20 @@ +class Solution: + def minimumCost(self, N: int, connections: List[List[int]]) -> int: + heap = [(0, 1)] + visited = [0] * (N + 1) + res = 0 + graph = [[] for _ in range(N + 1)] + for a, b, c in connections: + graph[a].append([b, c]) + graph[b].append([a, c]) + while heap: + cost, city = heapq.heappop(heap) + if visited[city]: continue + visited[city] = 1 + res += cost + for nCity, nCost in graph[city]: + if not visited[nCity]: + heapq.heappush(heap, (nCost, nCity)) + return res if all(visited[1:]) else -1 + + \ No newline at end of file diff --git a/solutions/python3/bak/1136.py.bak b/solutions/python3/bak/1136.py.bak new file mode 100644 index 0000000..c0a5a43 --- /dev/null +++ b/solutions/python3/bak/1136.py.bak @@ -0,0 +1,33 @@ +class Solution: + def minimumSemesters(self, N: int, relations: List[List[int]]) -> int: + """ + :type N: int + :type relations: List[List[int]] + :rtype: int + """ + if N == 1: + return 1 + graph = collections.defaultdict(list) + for p, q in relations: + graph[q-1].append(p-1) + + def need_semesters(n): + if dp[n] > 0: # node was visited + return dp[n] + if dp[n] == -1: # node is being visited, there is a cycle! + return -1 + dp[n] = -1 # start visiting the node + res = 0 + for p in graph[n]: + a = need_semesters(p) + if a == -1: + return -1 + res = max(res, a) + dp[n] = res + 1 + return dp[n] + + dp = [0]*N + for n in range(N): + if need_semesters(n) == -1: + return -1 + return max(dp) \ No newline at end of file diff --git a/solutions/python3/bak/1137.py.bak b/solutions/python3/bak/1137.py.bak new file mode 100644 index 0000000..44457ae --- /dev/null +++ b/solutions/python3/bak/1137.py.bak @@ -0,0 +1,7 @@ +class Solution: + def tribonacci(self, n: int) -> int: + t0, t1, t2 = 0, 1, 1 + for _ in range(n): + t0, t1, t2 = t1, t2, t0 + t1 + t2 + return t0 + \ No newline at end of file diff --git a/solutions/python3/bak/1138.py.bak b/solutions/python3/bak/1138.py.bak new file mode 100644 index 0000000..87bb56a --- /dev/null +++ b/solutions/python3/bak/1138.py.bak @@ -0,0 +1,18 @@ +class Solution: + def alphabetBoardPath(self, target: str) -> str: + ind = {s: [i // 5, i % 5] for i, s in enumerate(string.ascii_lowercase)} + x = y = 0 + res = "" + for c in target: + xx, yy = ind[c] + if yy < y: + res += 'L' * (y - yy) + if xx > x: + res += 'D' * (xx - x) + if xx < x: + res += 'U' * (x - xx) + if yy > y: + res += 'R' * (yy - y) + res += '!' + x, y = xx, yy + return res \ No newline at end of file diff --git a/solutions/python3/bak/1139.py.bak b/solutions/python3/bak/1139.py.bak new file mode 100644 index 0000000..f10e2d2 --- /dev/null +++ b/solutions/python3/bak/1139.py.bak @@ -0,0 +1,17 @@ +class Solution: + def largest1BorderedSquare(self, A: List[List[int]]) -> int: + m, n = len(A), len(A[0]) + res = 0 + top, left = [a[:] for a in A], [a[:] for a in A] + for i in range(m): + for j in range(n): + if A[i][j]: + if i: top[i][j] = top[i - 1][j] + 1 + if j: left[i][j] = left[i][j - 1] + 1 + for r in range(min(m, n), 0, -1): + for i in range(m - r + 1): + for j in range(n - r + 1): + if min(top[i + r - 1][j], top[i + r - 1][j + r - 1], left[i] + [j + r - 1], left[i + r - 1][j + r - 1]) >= r: + return r * r + return 0 \ No newline at end of file diff --git a/solutions/python3/bak/114.py.bak b/solutions/python3/bak/114.py.bak new file mode 100644 index 0000000..7d6b4c4 --- /dev/null +++ b/solutions/python3/bak/114.py.bak @@ -0,0 +1,19 @@ +# Definition for a binary tree node. +# class TreeNode: +# def __init__(self, x): +# self.val = x +# self.left = None +# self.right = None + +class Solution: + def flatten(self, root): + """ + :type root: TreeNode + :rtype: void Do not return anything, modify root in-place instead. + """ + def traverse(node): + if not node: return + left, right = traverse(node.left), traverse(node.right) + if node.left: left.right, node.right, node.left = node.right, node.left, None + return right if right else left if left else node + traverse(root) \ No newline at end of file diff --git a/solutions/python3/bak/1140.py.bak b/solutions/python3/bak/1140.py.bak new file mode 100644 index 0000000..89ed5a9 --- /dev/null +++ b/solutions/python3/bak/1140.py.bak @@ -0,0 +1,11 @@ +class Solution: + def stoneGameII(self, A: List[int]) -> int: + N = len(A) + for i in range(N - 2, -1, -1): + A[i] += A[i + 1] + from functools import lru_cache + @lru_cache(None) + def dp(i, m): + if i + 2 * m >= N: return A[i] + return A[i] - min(dp(i + x, max(m, x)) for x in range(1, 2 * m + 1)) + return dp(0, 1) \ No newline at end of file diff --git a/solutions/python3/bak/1143.py.bak b/solutions/python3/bak/1143.py.bak new file mode 100644 index 0000000..9b3a45a --- /dev/null +++ b/solutions/python3/bak/1143.py.bak @@ -0,0 +1,8 @@ +class Solution: + def longestCommonSubsequence(self, a: str, b: str) -> int: + m, n = len(a), len(b) + dp = [[0 for j in range(n + 1)] for i in range(m + 1)] + for i in range(1, m + 1): + for j in range(1, n + 1): + dp[i][j] = dp[i - 1][j - 1] + 1 if a[i - 1] == b[j - 1] else max(dp[i][j - 1], dp[i - 1][j]) + return dp[-1][-1] \ No newline at end of file diff --git a/solutions/python3/bak/1144.py.bak b/solutions/python3/bak/1144.py.bak new file mode 100644 index 0000000..6621aee --- /dev/null +++ b/solutions/python3/bak/1144.py.bak @@ -0,0 +1,4 @@ +class Solution: + def movesToMakeZigzag(self, N: List[int]) -> int: + moves = [max(0, N[i] - min(N[i-1:i] + N[i+1:i+2]) + 1) for i in range(len(N))] + return min(sum(moves[::2]), sum(moves[1::2])) \ No newline at end of file diff --git a/solutions/python3/bak/1145.py.bak b/solutions/python3/bak/1145.py.bak new file mode 100644 index 0000000..2b5104d --- /dev/null +++ b/solutions/python3/bak/1145.py.bak @@ -0,0 +1,17 @@ +# Definition for a binary tree node. +# class TreeNode: +# def __init__(self, x): +# self.val = x +# self.left = None +# self.right = None + +class Solution: + def btreeGameWinningMove(self, root: TreeNode, n: int, x: int) -> bool: + c = [0, 0] + def count(node): + if not node: return 0 + l, r = count(node.left), count(node.right) + if node.val == x: + c[0], c[1] = l, r + return l + r + 1 + return count(root) // 2 < max(max(c), n - sum(c) - 1) \ No newline at end of file diff --git a/solutions/python3/bak/1146.py.bak b/solutions/python3/bak/1146.py.bak new file mode 100644 index 0000000..fc74acc --- /dev/null +++ b/solutions/python3/bak/1146.py.bak @@ -0,0 +1,23 @@ +class SnapshotArray: + + def __init__(self, length: int): + self.s = 0 + self.arr = [[[0, 0]] for i in range(length)] + + def set(self, index: int, val: int) -> None: + if self.s == self.arr[index][-1][0]: + self.arr[index][-1][1] = val + else: + self.arr[index].append([self.s, val]) + + def snap(self) -> int: + self.s += 1 + return self.s - 1 + + def get(self, index: int, snap_id: int) -> int: + i = bisect.bisect_left(self.arr[index], [snap_id]) + if i < len(self.arr[index]): + if self.arr[index][i][0] > snap_id: + i -= 1 + return self.arr[index][i][1] + return self.arr[index][-1][1] \ No newline at end of file diff --git a/solutions/python3/bak/1147.py.bak b/solutions/python3/bak/1147.py.bak new file mode 100644 index 0000000..238549e --- /dev/null +++ b/solutions/python3/bak/1147.py.bak @@ -0,0 +1,8 @@ +class Solution: + def longestDecomposition(self, S: str) -> int: + res, l, r = 0, "", "" + for i, j in zip(S, S[::-1]): + l, r = l + i, j + r + if l == r: + res, l, r = res + 1, "", "" + return res \ No newline at end of file diff --git a/solutions/python3/bak/115.py.bak b/solutions/python3/bak/115.py.bak new file mode 100644 index 0000000..cf3243d --- /dev/null +++ b/solutions/python3/bak/115.py.bak @@ -0,0 +1,8 @@ +class Solution: + def numDistinct(self, s, t): + chars, index, dp = set(t), collections.defaultdict(list), [0] * len(t) + for i, c in enumerate(t): index[c] = [i] + index[c] + for c in s: + if c in chars: + for i in index[c]: dp[i] += dp[i - 1] if i > 0 else 1 + return dp[-1] \ No newline at end of file diff --git a/solutions/python3/bak/1150.py.bak b/solutions/python3/bak/1150.py.bak new file mode 100644 index 0000000..651810f --- /dev/null +++ b/solutions/python3/bak/1150.py.bak @@ -0,0 +1,4 @@ +class Solution: + def isMajorityElement(self, nums: List[int], target: int) -> bool: + return nums.count(target) > len(nums) // 2 + \ No newline at end of file diff --git a/solutions/python3/bak/1151.py.bak b/solutions/python3/bak/1151.py.bak new file mode 100644 index 0000000..a86715e --- /dev/null +++ b/solutions/python3/bak/1151.py.bak @@ -0,0 +1,10 @@ +class Solution: + def minSwaps(self, data: List[int]) -> int: + l = data.count(1) + mn = cur = data[:l].count(0) + for i in range(l, len(data)): + cur += not data[i] + cur -= not data[i - l] + mn = min(mn, cur) + return mn + \ No newline at end of file diff --git a/solutions/python3/bak/1152.py.bak b/solutions/python3/bak/1152.py.bak new file mode 100644 index 0000000..3531951 --- /dev/null +++ b/solutions/python3/bak/1152.py.bak @@ -0,0 +1,10 @@ +class Solution: + def mostVisitedPattern(self, username: List[str], timestamp: List[int], website: List[str]) -> List[str]: + dp = collections.defaultdict(list) + count = collections.Counter() + for t, u, w in sorted(zip(timestamp, username, website)): + dp[u].append(w) + for u in dp: + count += collections.Counter(set(seq for seq in itertools.combinations(dp[u], 3))) + target = max(count.values()) + return min(list(k) for k in count if count[k] == target) \ No newline at end of file diff --git a/solutions/python3/bak/1153.py.bak b/solutions/python3/bak/1153.py.bak new file mode 100644 index 0000000..fa5cbe3 --- /dev/null +++ b/solutions/python3/bak/1153.py.bak @@ -0,0 +1,8 @@ +class Solution: + def canConvert(self, s1: str, s2: str) -> bool: + if s1 == s2: return True + dp = {} + for i, j in zip(s1, s2): + if dp.setdefault(i, j) != j: + return False + return len(set(s2)) < 26 \ No newline at end of file diff --git a/solutions/python3/bak/1154.py.bak b/solutions/python3/bak/1154.py.bak new file mode 100644 index 0000000..4434ec1 --- /dev/null +++ b/solutions/python3/bak/1154.py.bak @@ -0,0 +1,10 @@ +class Solution: + def dayOfYear(self, date: str) -> int: + cnt = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31] + y, m, d = map(int, date.split('-')) + days = sum(cnt[:m - 1]) + d + if m > 2: + if y % 400 == 0: days += 1 + if y % 100 == 0: return days + if y % 4 == 0: days += 1 + return days \ No newline at end of file diff --git a/solutions/python3/bak/1155.py.bak b/solutions/python3/bak/1155.py.bak new file mode 100644 index 0000000..7eeb723 --- /dev/null +++ b/solutions/python3/bak/1155.py.bak @@ -0,0 +1,12 @@ +class Solution: + def numRollsToTarget(self, d: int, f: int, target: int) -> int: + mod = 10 ** 9 + 7 + dp = [[0 for j in range(target + 1)] for i in range(d + 1)] + dp[0][0] = 1 + for i in range(d): + for ff in range(1, f + 1): + for sm in range(target): + if sm + ff <= target: + dp[i + 1][sm + ff] += dp[i][sm] + dp[i + 1][sm + ff] %= mod + return dp[d][target] \ No newline at end of file diff --git a/solutions/python3/bak/1156.py.bak b/solutions/python3/bak/1156.py.bak new file mode 100644 index 0000000..99c2dd4 --- /dev/null +++ b/solutions/python3/bak/1156.py.bak @@ -0,0 +1,9 @@ +class Solution: + def maxRepOpt1(self, S: str) -> int: + A = [[c, len(list(g))] for c, g in itertools.groupby(S)] + count = collections.Counter(S) + res = max(min(k + 1, count[c]) for c, k in A) + for i in range(1, len(A) - 1): + if A[i - 1][0] == A[i + 1][0] and A[i][1] == 1: + res = max(res, min(A[i - 1][1] + A[i + 1][1] + 1, count[A[i + 1][0]])) + return res \ No newline at end of file diff --git a/solutions/python3/bak/1157.py.bak b/solutions/python3/bak/1157.py.bak new file mode 100644 index 0000000..76e670e --- /dev/null +++ b/solutions/python3/bak/1157.py.bak @@ -0,0 +1,17 @@ +class MajorityChecker: + + def __init__(self, arr: List[int]): + self.dp = collections.defaultdict(list) + for i, v in enumerate(arr): + self.dp[v].append(i) + self.occur = sorted([(len(v), k) for k, v in self.dp.items()], reverse = True) + + def query(self, left: int, right: int, threshold: int) -> int: + for o, v in self.occur: + if o < threshold: break + l = self.dp[v] + low = bisect.bisect_left(l, left) + high = bisect.bisect_right(l, right) + if high - low >= threshold: + return v + return -1 \ No newline at end of file diff --git a/solutions/python3/bak/116.py.bak b/solutions/python3/bak/116.py.bak new file mode 100644 index 0000000..afbb51c --- /dev/null +++ b/solutions/python3/bak/116.py.bak @@ -0,0 +1,16 @@ +class Solution: + def connect(self, root: "Node") -> "Node": + if root == None: + return root + q, prev = [(root, 1)], None + while q: + curr, pos = q.pop(0) + if prev != None and prev[1] == pos: + prev[0].next = curr + prev = [curr, pos] + if curr.left: + q.append((curr.left, pos + 1)) + if curr.right: + q.append((curr.right, pos + 1)) + return root + diff --git a/solutions/python3/bak/1160.py.bak b/solutions/python3/bak/1160.py.bak new file mode 100644 index 0000000..ff3d005 --- /dev/null +++ b/solutions/python3/bak/1160.py.bak @@ -0,0 +1,4 @@ +from collections import Counter as cnt +class Solution: + def countCharacters(self, words: List[str], chars: str) -> int: + return sum(not cnt(w) - cnt(chars) and len(w) for w in words) \ No newline at end of file diff --git a/solutions/python3/bak/1161.py.bak b/solutions/python3/bak/1161.py.bak new file mode 100644 index 0000000..6df0108 --- /dev/null +++ b/solutions/python3/bak/1161.py.bak @@ -0,0 +1,15 @@ +# Definition for a binary tree node. +# class TreeNode: +# def __init__(self, x): +# self.val = x +# self.left = None +# self.right = None + +class Solution: + def maxLevelSum(self, root: TreeNode) -> int: + levels, l, q = [], 1, [root] + while q: + levels.append([sum(node.val for node in q), l]) + l += 1 + q = [child for node in q for child in (node.left, node.right) if child] + return sorted(levels, key = lambda x: (x[0], -x[1]))[-1][1] \ No newline at end of file diff --git a/solutions/python3/bak/1162.py.bak b/solutions/python3/bak/1162.py.bak new file mode 100644 index 0000000..9d9bcb0 --- /dev/null +++ b/solutions/python3/bak/1162.py.bak @@ -0,0 +1,17 @@ +class Solution: + def maxDistance(self, grid: List[List[int]]) -> int: + n = len(grid) + q = [[i, j] for i in range(n) for j in range(n) if grid[i][j]] + d = -1 + while q and len(q) != n ** 2: + Q = [] + for i, j in q: + for x, y in (i - 1, j), (i + 1, j), (i, j - 1), (i, j + 1): + if 0 <= x < n > y >= 0 and not grid[x][y]: + grid[x][y] = 1 + Q.append([x, y]) + q = Q + d += 1 + return d + + \ No newline at end of file diff --git a/solutions/python3/bak/1163.py.bak b/solutions/python3/bak/1163.py.bak new file mode 100644 index 0000000..0e2ebc6 --- /dev/null +++ b/solutions/python3/bak/1163.py.bak @@ -0,0 +1,7 @@ +class Solution: + def lastSubstring(self, s: str) -> str: + result = "" + for i in range(len(s)): + result = max(result, s[i:]) + return result + \ No newline at end of file diff --git a/solutions/python3/bak/1165.py.bak b/solutions/python3/bak/1165.py.bak new file mode 100644 index 0000000..e630b8d --- /dev/null +++ b/solutions/python3/bak/1165.py.bak @@ -0,0 +1,3 @@ +class Solution: + def calculateTime(self, k: str, word: str) -> int: + return sum(abs(k.index(a) - k.index(b)) for a, b in zip(k[0] + word, word)) \ No newline at end of file diff --git a/solutions/python3/bak/1166.py.bak b/solutions/python3/bak/1166.py.bak new file mode 100644 index 0000000..ce21f9f --- /dev/null +++ b/solutions/python3/bak/1166.py.bak @@ -0,0 +1,14 @@ +class FileSystem: + + def __init__(self): + self.d = {"" : -1} + + def create(self, path: str, value: int) -> bool: + parent = path[:path.rfind('/')] + if parent in self.d and path not in self.d: + self.d[path] = value + return True + return False + + def get(self, path: str) -> int: + return self.d.get(path, -1) \ No newline at end of file diff --git a/solutions/python3/bak/1167.py.bak b/solutions/python3/bak/1167.py.bak new file mode 100644 index 0000000..8ad4e05 --- /dev/null +++ b/solutions/python3/bak/1167.py.bak @@ -0,0 +1,10 @@ +class Solution: + def connectSticks(self, sticks: List[int]) -> int: + heapq.heapify(sticks) + res = 0 + while len(sticks) != 1: + new = heapq.heappop(sticks) + heapq.heappop(sticks) + res += new + heapq.heappush(sticks, new) + return res + \ No newline at end of file diff --git a/solutions/python3/bak/1168.py.bak b/solutions/python3/bak/1168.py.bak new file mode 100644 index 0000000..1a5c0b3 --- /dev/null +++ b/solutions/python3/bak/1168.py.bak @@ -0,0 +1,24 @@ +class Solution: + def minCostToSupplyWater(self, n: int, wells, pipes) -> int: + q = sorted([[w, u, v] for u, v, w in pipes] + [[w, 0, i+1] for i, w in enumerate(wells)]) + uf = [i for i in range(n+1)] + res = count = 0 + + def find(x): + if (x != uf[x]): + uf[x] = find(uf[x]) + return uf[x] + + def union(x, y): + uf[x] = y + + for w, u, v in q: + rA, rB = find(u), find(v) + if rA == rB: + continue + union(rA, rB) + res += w + count += 1 + if count == n: + return res + return res \ No newline at end of file diff --git a/solutions/python3/bak/1169.py.bak b/solutions/python3/bak/1169.py.bak new file mode 100644 index 0000000..d445add --- /dev/null +++ b/solutions/python3/bak/1169.py.bak @@ -0,0 +1,17 @@ +class Solution: + def invalidTransactions(self, transactions: List[str]) -> List[str]: + last = collections.defaultdict(list) + ret = set() + for n, t, a, c in sorted([t.split(',') for t in transactions], key = lambda x: int(x[1])): + if int(a) > 1000: + ret.add(','.join([n, t, a, c])) + if n in last: + for tt, aa, cc in last[n][::-1]: + if int(t) - int(tt) > 60: + break + if cc != c: + ret.add(','.join([n, tt, aa, cc])) + ret.add(','.join([n, t, a, c])) + last[n].append([t, a, c]) + return list(ret) + \ No newline at end of file diff --git a/solutions/python3/bak/117.py.bak b/solutions/python3/bak/117.py.bak new file mode 100644 index 0000000..ed95a99 --- /dev/null +++ b/solutions/python3/bak/117.py.bak @@ -0,0 +1,19 @@ +class Solution: + def connect(self, root: "Node") -> "Node": + dummy = Node(-1, None, None, None) + tmp = dummy + res = root + while root: + while root: + if root.left: + tmp.next = root.left + tmp = tmp.next + if root.right: + tmp.next = root.right + tmp = tmp.next + root = root.next + root = dummy.next + tmp = dummy + dummy.next = None + + return res diff --git a/solutions/python3/bak/1170.py.bak b/solutions/python3/bak/1170.py.bak new file mode 100644 index 0000000..3ab89dc --- /dev/null +++ b/solutions/python3/bak/1170.py.bak @@ -0,0 +1,5 @@ +class Solution: + def numSmallerByFrequency(self, queries: List[str], words: List[str]) -> List[int]: + f = sorted(w.count(min(w)) for w in words) + return [len(f) - bisect.bisect(f, q.count(min(q))) for q in queries] + \ No newline at end of file diff --git a/solutions/python3/bak/1172.py.bak b/solutions/python3/bak/1172.py.bak new file mode 100644 index 0000000..f0dc1f4 --- /dev/null +++ b/solutions/python3/bak/1172.py.bak @@ -0,0 +1,40 @@ +class DinnerPlates: + + def __init__(self, capacity: int): + self.c = capacity + self.stacks = [] + self.l = [] # pushable + self.r = [] # poppable + + def push(self, val: int) -> None: + if not self.l: + # if the rightmost is empty, clear it from self.r + while self.r and not self.stacks[-self.r[0]]: + heapq.heappop(self.r) + i = 0 if not self.r else -self.r[0] + 1 + self.stacks.append([val]) + heapq.heappush(self.r, -i) + if len(self.stacks[i]) < self.c: + heapq.heappush(self.l, i) + else: + i = self.l[0] + # new poppable + if not self.stacks[i]: + heapq.heappush(self.r, -i) + self.stacks[i].append(val) + if len(self.stacks[i]) == self.c: + heapq.heappop(self.l) + + def pop(self) -> int: + while self.r and not self.stacks[-self.r[0]]: + heapq.heappop(self.r) + return self.popAtStack(-self.r[0]) if self.r else -1 + + def popAtStack(self, index: int) -> int: + if index < len(self.stacks) and self.stacks[index]: + ret = self.stacks[index].pop() + if len(self.stacks[index]) == self.c - 1: + heapq.heappush(self.l, index) + return ret + return -1 + \ No newline at end of file diff --git a/solutions/python3/bak/1175.py.bak b/solutions/python3/bak/1175.py.bak new file mode 100644 index 0000000..2f67570 --- /dev/null +++ b/solutions/python3/bak/1175.py.bak @@ -0,0 +1,6 @@ +class Solution: + def numPrimeArrangements(self, n: int) -> int: + primes = [2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,79,83,89,97] + cnt = bisect.bisect(primes, n) + return math.factorial(cnt) * math.factorial(n - cnt) % (10 ** 9 + 7) + \ No newline at end of file diff --git a/solutions/python3/bak/1176.py.bak b/solutions/python3/bak/1176.py.bak new file mode 100644 index 0000000..916f745 --- /dev/null +++ b/solutions/python3/bak/1176.py.bak @@ -0,0 +1,9 @@ +class Solution: + def dietPlanPerformance(self, calories: List[int], k: int, lower: int, upper: int) -> int: + sm = sum(calories[:k]) + points = (sm > upper) - (sm < lower) + for i in range(k, len(calories)): + sm += calories[i] - calories[i - k] + points += (sm > upper) - (sm < lower) + return points + \ No newline at end of file diff --git a/solutions/python3/bak/1177.py.bak b/solutions/python3/bak/1177.py.bak new file mode 100644 index 0000000..b7357a9 --- /dev/null +++ b/solutions/python3/bak/1177.py.bak @@ -0,0 +1,12 @@ +class Solution: + def canMakePaliQueries(self, s: str, queries: List[List[int]]) -> List[bool]: + cnts = [{}] + for i, c in enumerate(s): + cnts.append(dict(cnts[-1])) + cnts[-1][c] = cnts[-1].get(c, 0) + 1 + res = [] + for i, j, k in queries: + res.append(sum((v - cnts[i].get(k, 0)) % 2 for k, v in cnts[j + 1].items()) - k * 2 <= 1) + return res + + \ No newline at end of file diff --git a/solutions/python3/bak/1178.py.bak b/solutions/python3/bak/1178.py.bak new file mode 100644 index 0000000..999ce13 --- /dev/null +++ b/solutions/python3/bak/1178.py.bak @@ -0,0 +1,5 @@ +from itertools import combinations as cb +class Solution: + def findNumOfValidWords(self, words: List[str], puzzles: List[str]) -> List[int]: + cnt = collections.Counter(''.join(sorted(set(w))) for w in words) + return [sum(cnt[''.join(sorted(s + (p[0], )))] for l in range(len(p)) for s in cb(p[1:], l)) for p in puzzles] \ No newline at end of file diff --git a/solutions/python3/bak/118.py.bak b/solutions/python3/bak/118.py.bak new file mode 100644 index 0000000..a8d7e7e --- /dev/null +++ b/solutions/python3/bak/118.py.bak @@ -0,0 +1,6 @@ +class Solution: + def generate(self, numRows: int) -> List[List[int]]: + res = numRows and [[1]] or [] + for _ in range(numRows-1): + res.append([1] + [a + b for a, b in zip(res[-1], res[-1][1:])] + [1]) + return res \ No newline at end of file diff --git a/solutions/python3/bak/1180.py.bak b/solutions/python3/bak/1180.py.bak new file mode 100644 index 0000000..66ebb77 --- /dev/null +++ b/solutions/python3/bak/1180.py.bak @@ -0,0 +1,15 @@ +class Solution: + def countLetters(self, S: str) -> int: + cnt = collections.Counter() + i = res = 0 + for j, c in enumerate(S): + cnt[c] += 1 + while len(cnt) > 1: + cnt[S[i]] -= 1 + if not cnt[S[i]]: + cnt.pop(S[i]) + i += 1 + res += j - i + 1 + return res + + \ No newline at end of file diff --git a/solutions/python3/bak/1181.py.bak b/solutions/python3/bak/1181.py.bak new file mode 100644 index 0000000..df2b14d --- /dev/null +++ b/solutions/python3/bak/1181.py.bak @@ -0,0 +1,16 @@ +class Solution: + def beforeAndAfterPuzzles(self, phrases: List[str]) -> List[str]: + res = [] + for i in range(len(phrases)): + for j in range(i + 1, len(phrases)): + w1 = phrases[i].split()[-1] + w2 = phrases[j].split()[0] + if w1 == w2: + r = phrases[i] + ' ' + ' '.join(phrases[j].split()[1:]) + res.append(r.rstrip()) + w1 = phrases[j].split()[-1] + w2 = phrases[i].split()[0] + if w1 == w2: + r = phrases[j] + ' ' + ' '.join(phrases[i].split()[1:]) + res.append(r.rstrip()) + return sorted(set(res)) \ No newline at end of file diff --git a/solutions/python3/bak/1182.py.bak b/solutions/python3/bak/1182.py.bak new file mode 100644 index 0000000..21b03f9 --- /dev/null +++ b/solutions/python3/bak/1182.py.bak @@ -0,0 +1,43 @@ +class Solution: + def shortestDistanceColor(self, colors: List[int], queries: List[List[int]]) -> List[int]: + l1 = l2 = l3 = -1 + left = [[float('inf') for _ in range(3)] for __ in range(len(colors))] + res = [] + for i, c in enumerate(colors): + if c == 1: + l1 = i + elif c == 2: + l2 = i + else: + l3 = i + if l1 != -1: + left[i][0] = i - l1 + if l2 != -1: + left[i][1] = i - l2 + if l3 != -1: + left[i][2] = i - l3 + + l1 = l2 = l3 = -1 + right = [[float('inf') for _ in range(3)] for __ in range(len(colors))] + for i in range(len(colors) - 1, -1, -1): + c = colors[i] + if c == 1: + l1 = i + elif c == 2: + l2 = i + else: + l3 = i + if l1 != -1: + right[i][0] = l1 - i + if l2 != -1: + right[i][1] = l2 - i + if l3 != -1: + right[i][2] = l3 - i + for i, c in queries: + res.append(min(left[i][c - 1], right[i][c - 1])) + return [c if c != float('inf') else -1 for c in res] + + + + + \ No newline at end of file diff --git a/solutions/python3/bak/1184.py.bak b/solutions/python3/bak/1184.py.bak new file mode 100644 index 0000000..fdfaa56 --- /dev/null +++ b/solutions/python3/bak/1184.py.bak @@ -0,0 +1,3 @@ +class Solution: + def distanceBetweenBusStops(self, d: List[int], i: int, j: int) -> int: + return min(sum(d[min(i, j):max(i, j)]), sum(d[:min(i, j)] + d[max(i, j):])) \ No newline at end of file diff --git a/solutions/python3/bak/1185.py.bak b/solutions/python3/bak/1185.py.bak new file mode 100644 index 0000000..ac559ff --- /dev/null +++ b/solutions/python3/bak/1185.py.bak @@ -0,0 +1,4 @@ +from datetime import date +class Solution: + def dayOfTheWeek(self, day: int, month: int, year: int) -> str: + return date(year, month, day).strftime("%A") \ No newline at end of file diff --git a/solutions/python3/bak/1186.py.bak b/solutions/python3/bak/1186.py.bak new file mode 100644 index 0000000..ba9416a --- /dev/null +++ b/solutions/python3/bak/1186.py.bak @@ -0,0 +1,21 @@ +class Solution: + def maximumSum(self, arr: List[int]) -> int: + def cumSum(it): + sm = mn = 0 + sums = [0] * len(arr) + for i, num in it: + sm += num + sums[i] = sm - mn + mn = min(mn, sm) + return sums + + lSum = cumSum(enumerate(arr)) + rSum = cumSum(reversed(list(enumerate(arr)))) + res = -float('inf') + for i, num in enumerate(arr): + if num >= 0: + cur = lSum[i] + rSum[i] - num + else: + cur = lSum[i] + rSum[i] - 2 * num + res = max(res, cur) + return res if any(c >= 0 for c in arr) else max(arr) \ No newline at end of file diff --git a/solutions/python3/bak/1187.py.bak b/solutions/python3/bak/1187.py.bak new file mode 100644 index 0000000..8b102ea --- /dev/null +++ b/solutions/python3/bak/1187.py.bak @@ -0,0 +1,16 @@ +class Solution: + def makeArrayIncreasing(self, arr1: List[int], arr2: List[int]) -> int: + dp = {-1:0} + arr2.sort() + for i in arr1: + tmp = collections.defaultdict(lambda: float('inf')) + for key in dp: + if i > key: + tmp[i] = min(tmp[i],dp[key]) + loc = bisect.bisect_right(arr2,key) + if loc < len(arr2): + tmp[arr2[loc]] = min(tmp[arr2[loc]],dp[key]+1) + dp = tmp + if dp: + return min(dp.values()) + return -1 \ No newline at end of file diff --git a/solutions/python3/bak/1188.py.bak b/solutions/python3/bak/1188.py.bak new file mode 100644 index 0000000..ddf1203 --- /dev/null +++ b/solutions/python3/bak/1188.py.bak @@ -0,0 +1,20 @@ +import threading + +class BoundedBlockingQueue(object): + def __init__(self, capacity: int): + self.pushing = threading.Semaphore(capacity) + self.pulling = threading.Semaphore(0) + self.queue = collections.deque() + + def enqueue(self, element: int) -> None: + self.pushing.acquire() + self.queue.append(element) + self.pulling.release() + + def dequeue(self) -> int: + self.pulling.acquire() + self.pushing.release() + return self.queue.popleft() + + def size(self) -> int: + return len(self.queue) \ No newline at end of file diff --git a/solutions/python3/bak/1189.py.bak b/solutions/python3/bak/1189.py.bak new file mode 100644 index 0000000..26b01f6 --- /dev/null +++ b/solutions/python3/bak/1189.py.bak @@ -0,0 +1,3 @@ +class Solution: + def maxNumberOfBalloons(self, t: str) -> int: + return min(t.count(c) // 'balloon'.count(c) for c in 'balon') \ No newline at end of file diff --git a/solutions/python3/bak/119.py.bak b/solutions/python3/bak/119.py.bak new file mode 100644 index 0000000..d3cb039 --- /dev/null +++ b/solutions/python3/bak/119.py.bak @@ -0,0 +1,3 @@ +class Solution: + def getRow(self, rowIndex: int, row = [1]) -> List[int]: + return self.getRow(rowIndex - 1, [a + b for a, b in zip([0] + row, row + [0])]) if rowIndex else row \ No newline at end of file diff --git a/solutions/python3/bak/1190.py.bak b/solutions/python3/bak/1190.py.bak new file mode 100644 index 0000000..15b2092 --- /dev/null +++ b/solutions/python3/bak/1190.py.bak @@ -0,0 +1,12 @@ +class Solution: + def reverseParentheses(self, s: str) -> str: + stack = [''] + for c in s: + if c == '(': + stack.append('') + elif c == ')': + add = stack.pop()[::-1] + stack[-1] += add + else: + stack[-1] += c + return stack.pop() \ No newline at end of file diff --git a/solutions/python3/bak/1191.py.bak b/solutions/python3/bak/1191.py.bak new file mode 100644 index 0000000..74b4bed --- /dev/null +++ b/solutions/python3/bak/1191.py.bak @@ -0,0 +1,8 @@ +class Solution: + def kConcatenationMaxSum(self, arr: List[int], k: int, mod = 10 ** 9 + 7) -> int: + def Kadane(arr, res = 0, cur = 0): + for num in arr: + cur = max(num, num + cur) + res = max(res, cur) + return res + return ((k - 2) * max(sum(arr), 0) + Kadane(arr * 2) ) % mod if k > 1 else Kadane(arr) % mod \ No newline at end of file diff --git a/solutions/python3/bak/1196.py.bak b/solutions/python3/bak/1196.py.bak new file mode 100644 index 0000000..54a847a --- /dev/null +++ b/solutions/python3/bak/1196.py.bak @@ -0,0 +1,3 @@ +class Solution: + def maxNumberOfApples(self, arr: List[int]) -> int: + return bisect.bisect(list(itertools.accumulate(sorted(arr))), 5000) \ No newline at end of file diff --git a/solutions/python3/bak/1197.py.bak b/solutions/python3/bak/1197.py.bak new file mode 100644 index 0000000..9fc3d25 --- /dev/null +++ b/solutions/python3/bak/1197.py.bak @@ -0,0 +1,11 @@ +from functools import lru_cache +class Solution: + def minKnightMoves(self, x: int, y: int) -> int: + @lru_cache(None) + def dfs(i, j): + if i == j == 0: + return 0 + if i == 1 and j == 0 or j == 1 and i == 0: + return float('inf') + return min(dfs(abs(i - 2), abs(j - 1)), dfs(abs(i - 1), abs(j - 2))) + 1 + return dfs(abs(x), abs(y)) \ No newline at end of file diff --git a/solutions/python3/bak/1198.py.bak b/solutions/python3/bak/1198.py.bak new file mode 100644 index 0000000..ce94114 --- /dev/null +++ b/solutions/python3/bak/1198.py.bak @@ -0,0 +1,5 @@ +from itertools import chain as chn +from collections import Counter as cnt +class Solution: + def smallestCommonElement(self, mat: List[List[int]]) -> int: + return min([k for k, v in cnt(chn(*mat)).items() if v == len(mat)] or [-1]) \ No newline at end of file diff --git a/solutions/python3/bak/1199.py.bak b/solutions/python3/bak/1199.py.bak new file mode 100644 index 0000000..c0b0733 --- /dev/null +++ b/solutions/python3/bak/1199.py.bak @@ -0,0 +1,7 @@ +class Solution: + def minBuildTime(self, A: List[int], split: int) -> int: + heapq.heapify(A) + while len(A) > 1: + x, y = heapq.heappop(A), heapq.heappop(A) + heapq.heappush(A, y + split) + return heapq.heappop(A) \ No newline at end of file diff --git a/solutions/python3/bak/12.py.bak b/solutions/python3/bak/12.py.bak new file mode 100644 index 0000000..23d445b --- /dev/null +++ b/solutions/python3/bak/12.py.bak @@ -0,0 +1,10 @@ +class Solution: + def intToRoman(self, num): + s = "M" * (num // 1000) + s += "CM" if num % 1000 >= 900 else "D" *((num % 1000) // 500) + s += "CD" if num % 500 >= 400 and s[-2:] != "CM" else "C" * ((num % 500) // 100) if num % 500 < 400 else "" + s += "XC" if num % 100 >= 90 else "L" * ((num % 100) // 50) + s += "XL" if num % 50 >= 40 and s[-2:] != "XC" else "X" * ((num % 50) // 10) if num % 50 < 40 else "" + s += "IX" if num % 10 >= 9 else "V" * ((num % 10) // 5) + s += "IV" if num % 5 >= 4 and s[-2:] != "IX" else "I" * ((num % 5) // 1) if num % 5 < 4 else "" + return s \ No newline at end of file diff --git a/solutions/python3/bak/120.py.bak b/solutions/python3/bak/120.py.bak new file mode 100644 index 0000000..a5994ce --- /dev/null +++ b/solutions/python3/bak/120.py.bak @@ -0,0 +1,15 @@ +class Solution: + def minimumTotal(self, triangle): + """ + :type triangle: List[List[int]] + :rtype: int + """ + prev = None + for tri in triangle: + if prev: + for i, num in enumerate(tri): + if i >= len(prev): tri[i] += prev[i - 1] + elif i == 0: tri[i] += prev[0] + else: tri[i] += min(prev[i - 1], prev[i]) + prev = tri + return min(triangle[-1]) \ No newline at end of file diff --git a/solutions/python3/bak/1200.py.bak b/solutions/python3/bak/1200.py.bak new file mode 100644 index 0000000..456f512 --- /dev/null +++ b/solutions/python3/bak/1200.py.bak @@ -0,0 +1,5 @@ +class Solution: + def minimumAbsDifference(self, arr: List[int]) -> List[List[int]]: + arr.sort() + mn = min(b - a for a, b in zip(arr, arr[1:])) + return [[a, b] for a, b in zip(arr, arr[1:]) if b - a == mn] \ No newline at end of file diff --git a/solutions/python3/bak/1201.py.bak b/solutions/python3/bak/1201.py.bak new file mode 100644 index 0000000..c257988 --- /dev/null +++ b/solutions/python3/bak/1201.py.bak @@ -0,0 +1,15 @@ +class Solution: + def nthUglyNumber(self, n: int, a: int, b: int, c: int) -> int: + def gcd(a, b): + return a if not b else gcd(b, a % b) + ab, ac, bc = a * b // gcd(a, b), a * c // gcd(a, c), b * c // gcd(b, c) + abc = ab * c // gcd(ab, c) + l, r = 1, 2 * 10 ** 9 + while l < r: + mid = (l + r) // 2 + if mid // a + mid // b + mid // c - mid // ab - mid // ac - mid // bc + mid // abc < n: + l = mid + 1 + else: + r = mid + return l + \ No newline at end of file diff --git a/solutions/python3/bak/1202.py.bak b/solutions/python3/bak/1202.py.bak new file mode 100644 index 0000000..2e2023c --- /dev/null +++ b/solutions/python3/bak/1202.py.bak @@ -0,0 +1,20 @@ +class Solution: + def smallestStringWithSwaps(self, s: str, pairs: List[List[int]]) -> str: + class UF: + def __init__(self, n): self.p = list(range(n)) + def union(self, x, y): self.p[self.find(x)] = self.find(y) + def find(self, x): + if x != self.p[x]: self.p[x] = self.find(self.p[x]) + return self.p[x] + uf, res, m = UF(len(s)), [], collections.defaultdict(list) + for x,y in pairs: + uf.union(x,y) + for i in range(len(s)): + m[uf.find(i)].append(s[i]) + for comp_id in m.keys(): + m[comp_id].sort(reverse=True) + for i in range(len(s)): + res.append(m[uf.find(i)].pop()) + return ''.join(res) + + \ No newline at end of file diff --git a/solutions/python3/bak/1203.py.bak b/solutions/python3/bak/1203.py.bak new file mode 100644 index 0000000..945e914 --- /dev/null +++ b/solutions/python3/bak/1203.py.bak @@ -0,0 +1,43 @@ +class Solution: + def sortItems(self, n: int, m: int, group: List[int], beforeItems: List[List[int]]) -> List[int]: + def topo_sort(points, pre, suc): + order = [] + sources = [p for p in points if not pre[p]] + while sources: + s = sources.pop() + order.append(s) + for u in suc[s]: + pre[u].remove(s) + if not pre[u]: + sources.append(u) + return order if len(order) == len(points) else [] + + # find the group of each item + group2item = collections.defaultdict(set) + for i in range(n): + if group[i] == -1: + group[i] = m + m += 1 + group2item[group[i]].add(i) + # find the relationships between the groups and each items in the same group + t_pre, t_suc = collections.defaultdict(set), collections.defaultdict(set) + g_pre, g_suc = collections.defaultdict(set), collections.defaultdict(set) + for i in range(n): + for j in beforeItems[i]: + if group[i] == group[j]: + t_pre[i].add(j) + t_suc[j].add(i) + else: + g_pre[group[i]].add(group[j]) + g_suc[group[j]].add(group[i]) + # topological sort the groups + groups_order = topo_sort([i for i in group2item], g_pre, g_suc) + # topological sort the items in each group + t_order = [] + for i in groups_order: + items = group2item[i] + i_order = topo_sort(items, t_pre, t_suc) + if len(i_order) != len(items): + return [] + t_order += i_order + return t_order if len(t_order) == n else [] \ No newline at end of file diff --git a/solutions/python3/bak/1207.py.bak b/solutions/python3/bak/1207.py.bak new file mode 100644 index 0000000..4385a18 --- /dev/null +++ b/solutions/python3/bak/1207.py.bak @@ -0,0 +1,4 @@ +from collections import Counter as cnt +class Solution: + def uniqueOccurrences(self, arr: List[int]) -> bool: + return all(v == 1 for v in cnt(cnt(arr).values()).values()) \ No newline at end of file diff --git a/solutions/python3/bak/1208.py.bak b/solutions/python3/bak/1208.py.bak new file mode 100644 index 0000000..9330003 --- /dev/null +++ b/solutions/python3/bak/1208.py.bak @@ -0,0 +1,9 @@ +class Solution: + def equalSubstring(self, s: str, t: str, mx: int) -> int: + i = 0 + for j in range(len(s)): + mx -= abs(ord(s[j]) - ord(t[j])) + if mx < 0: + mx += abs(ord(s[i]) - ord(t[i])) + i += 1 + return j - i + 1 \ No newline at end of file diff --git a/solutions/python3/bak/1209.py.bak b/solutions/python3/bak/1209.py.bak new file mode 100644 index 0000000..3eb1128 --- /dev/null +++ b/solutions/python3/bak/1209.py.bak @@ -0,0 +1,12 @@ +class Solution: + def removeDuplicates(self, s: str, k: int) -> str: + stack = [] + for i, c in enumerate(s): + if not stack or stack[-1][0] != c: + stack.append([c, 1]) + else: + stack[-1][1] += 1 + if stack[-1][1] == k: + stack.pop() + return ''.join(k * v for k, v in stack) + \ No newline at end of file diff --git a/solutions/python3/bak/121.py.bak b/solutions/python3/bak/121.py.bak new file mode 100644 index 0000000..409fc9f --- /dev/null +++ b/solutions/python3/bak/121.py.bak @@ -0,0 +1,14 @@ +class Solution: + def maxProfit(self, prices): + """ + :type prices: List[int] + :rtype: int + """ + diff_list=[0,0] + for i in range (1, len(prices)): + if prices[i]-prices[i-1]+diff_list[1]>=0: + diff_list[1]=prices[i]-prices[i-1]+diff_list[1] + diff_list[0]=max(diff_list[0],diff_list[1]) + else: + diff_list[1]=0 + return diff_list[0] \ No newline at end of file diff --git a/solutions/python3/bak/1210.py.bak b/solutions/python3/bak/1210.py.bak new file mode 100644 index 0000000..064f97d --- /dev/null +++ b/solutions/python3/bak/1210.py.bak @@ -0,0 +1,28 @@ +class Solution: + def minimumMoves(self, grid: List[List[int]]) -> int: + q, move, n, seen = {(0, 1, 0)}, 0, len(grid), set() + while q: + new = set() + for i, j, hv in q: + if i == j == n - 1 and not hv: + return move + if hv and i < n - 1 and not grid[i + 1][j]: + if (i + 1, j, 1) not in seen: + new.add((i + 1, j, 1)) + if hv and j + 1 < n and grid[i][j + 1] == grid[i - 1][j + 1] == 0: + if (i, j + 1, 1) not in seen: + new.add((i, j + 1, 1)) + if (i - 1, j + 1, 0) not in seen: + new.add((i - 1, j + 1, 0)) + if not hv and j + 1 < n and not grid[i][j + 1]: + if (i, j + 1, 0) not in seen: + new.add((i, j + 1, 0)) + if not hv and i + 1 < n and grid[i + 1][j] == grid[i + 1][j - 1] == 0: + if (i + 1, j, 0) not in seen: + new.add((i + 1, j, 0)) + if (i + 1, j - 1, 1) not in seen: + new.add((i + 1, j - 1, 1)) + q = new + seen |= new + move += 1 + return -1 \ No newline at end of file diff --git a/solutions/python3/bak/1213.py.bak b/solutions/python3/bak/1213.py.bak new file mode 100644 index 0000000..4b821c0 --- /dev/null +++ b/solutions/python3/bak/1213.py.bak @@ -0,0 +1,3 @@ +class Solution: + def arraysIntersection(self, arr1: List[int], arr2: List[int], arr3: List[int]) -> List[int]: + return sorted(set(arr1) & set(arr2) & set(arr3)) \ No newline at end of file diff --git a/solutions/python3/bak/1214.py.bak b/solutions/python3/bak/1214.py.bak new file mode 100644 index 0000000..8e1e139 --- /dev/null +++ b/solutions/python3/bak/1214.py.bak @@ -0,0 +1,18 @@ +# Definition for a binary tree node. +# class TreeNode: +# def __init__(self, x): +# self.val = x +# self.left = None +# self.right = None +from functools import lru_cache +class Solution: + def twoSumBSTs(self, root1: TreeNode, root2: TreeNode, target: int) -> bool: + + + + + + def dfs(node): + return dfs(node.left) | dfs(node.right) | {node.val} if node else set() + q1 = dfs(root1) + return any(target - a in q1 for a in dfs(root2)) \ No newline at end of file diff --git a/solutions/python3/bak/1215.py.bak b/solutions/python3/bak/1215.py.bak new file mode 100644 index 0000000..3e96208 --- /dev/null +++ b/solutions/python3/bak/1215.py.bak @@ -0,0 +1,19 @@ +class Solution: + def countSteppingNumbers(self, low: int, high: int) -> List[int]: + def dfs(n): + if n > high: + return + if n >= low: + q.add(n) + d = n % 10 + if d == 0: + dfs(n * 10 + 1) + elif d == 9: + dfs(n * 10 + 8) + else: + dfs(n * 10 + d + 1) + dfs(n * 10 + d - 1) + q = set() + for i in range(10): + dfs(i) + return sorted(q) \ No newline at end of file diff --git a/solutions/python3/bak/1216.py.bak b/solutions/python3/bak/1216.py.bak new file mode 100644 index 0000000..694ef4f --- /dev/null +++ b/solutions/python3/bak/1216.py.bak @@ -0,0 +1,13 @@ +class Solution: + def isValidPalindrome(self, s: str, k: int) -> bool: + n = len(s) + dp = [[0] * (n + 1) for _ in range(n + 1)] + for i in range(n + 1): + for j in range(n + 1): + if not i or not j: + dp[i][j] = i or j + elif s[i - 1] == s[n - j]: + dp[i][j] = dp[i - 1][j - 1] + else: + dp[i][j] = 1 + min(dp[i - 1][j], dp[i][j - 1]) + return dp[n][n] <= k * 2 \ No newline at end of file diff --git a/solutions/python3/bak/1217.py.bak b/solutions/python3/bak/1217.py.bak new file mode 100644 index 0000000..0ba9415 --- /dev/null +++ b/solutions/python3/bak/1217.py.bak @@ -0,0 +1,3 @@ +class Solution: + def minCostToMoveChips(self, chips: List[int]) -> int: + return min(sum((c1 - c2) % 2 for c2 in chips) for c1 in chips) \ No newline at end of file diff --git a/solutions/python3/bak/1218.py.bak b/solutions/python3/bak/1218.py.bak new file mode 100644 index 0000000..5c9bbe1 --- /dev/null +++ b/solutions/python3/bak/1218.py.bak @@ -0,0 +1,6 @@ +class Solution: + def longestSubsequence(self, arr: List[int], d: int) -> int: + dp = collections.Counter() + for a in arr: + dp[a] = max(dp[a], dp[a - d] + 1) + return max(dp.values()) \ No newline at end of file diff --git a/solutions/python3/bak/1219.py.bak b/solutions/python3/bak/1219.py.bak new file mode 100644 index 0000000..d66c966 --- /dev/null +++ b/solutions/python3/bak/1219.py.bak @@ -0,0 +1,17 @@ +class Solution: + def getMaximumGold(self, grid: List[List[int]]) -> int: + def dfs(i, j, v): + seen.add((i, j)) + dp[i][j] = max(dp[i][j], v) + for x, y in (i - 1, j), (i + 1, j), (i, j - 1), (i, j + 1): + if 0 <= x < m and 0 <= y < n and grid[x][y] and (x, y) not in seen: + dfs(x, y, v + grid[x][y]) + seen.discard((i, j)) + m, n = len(grid), len(grid[0]) + dp = [[0] * n for _ in range(m)] + for i in range(m): + for j in range(n): + if grid[i][j]: + seen = set() + dfs(i, j, grid[i][j]) + return max(c for row in dp for c in row) \ No newline at end of file diff --git a/solutions/python3/bak/122.py.bak b/solutions/python3/bak/122.py.bak new file mode 100644 index 0000000..ac931a3 --- /dev/null +++ b/solutions/python3/bak/122.py.bak @@ -0,0 +1,9 @@ +class Solution: + def maxProfit(self, prices: List[int]) -> int: + # stock, no stock + dp = [-float('inf'), 0] + for p in prices: + x = max(dp[1] - p, dp[0]) + y = max(dp[1], dp[0] + p) + dp = [x, y] + return dp[-1] \ No newline at end of file diff --git a/solutions/python3/bak/1220.py.bak b/solutions/python3/bak/1220.py.bak new file mode 100644 index 0000000..55836b8 --- /dev/null +++ b/solutions/python3/bak/1220.py.bak @@ -0,0 +1,24 @@ +class Solution: + def countVowelPermutation(self, n: int) -> int: + mod = 10 ** 9 + 7 + dp = [1] * 5 + for _ in range(n - 1): + add = [0] * 5 + # from a + add[1] = (add[1] + dp[0]) % mod + # from e + add[0] = (add[0] + dp[1]) % mod + add[2] = (add[2] + dp[1]) % mod + # from i + add[0] = (add[0] + dp[2]) % mod + add[1] = (add[1] + dp[2]) % mod + add[3] = (add[3] + dp[2]) % mod + add[4] = (add[4] + dp[2]) % mod + # from o + add[2] = (add[2] + dp[3]) % mod + add[4] = (add[4] + dp[3]) % mod + # from u + add[0] = (add[0] + dp[4]) % mod + for i in range(5): + dp[i] = add[i] % mod + return sum(dp) % mod \ No newline at end of file diff --git a/solutions/python3/bak/1221.py.bak b/solutions/python3/bak/1221.py.bak new file mode 100644 index 0000000..d5dfaf8 --- /dev/null +++ b/solutions/python3/bak/1221.py.bak @@ -0,0 +1,8 @@ +class Solution: + def balancedStringSplit(self, s: str) -> int: + res = cnt = 0 + for c in s: + cnt += c == 'L' + cnt -= c == 'R' + res += cnt == 0 + return res \ No newline at end of file diff --git a/solutions/python3/bak/1222.py.bak b/solutions/python3/bak/1222.py.bak new file mode 100644 index 0000000..5def2be --- /dev/null +++ b/solutions/python3/bak/1222.py.bak @@ -0,0 +1,14 @@ +class Solution: + def queensAttacktheKing(self, queens: List[List[int]], king: List[int]) -> List[List[int]]: + def dfs(dr, dc, r, c): + while 0 <= r <= 7 and 0 <= c <= 7: + if (r, c) in q: + res.append([r, c]) + break + r += dr + c += dc + q = set((r,c) for r, c in queens) + res = [] + for dr, dc in (-1, -1), (-1, 0), (-1, 1), (0, 1), (1, 1), (1, 0), (1, -1), (0, -1): + dfs(dr, dc, *king) + return res \ No newline at end of file diff --git a/solutions/python3/bak/1223.py.bak b/solutions/python3/bak/1223.py.bak new file mode 100644 index 0000000..d7ab8a8 --- /dev/null +++ b/solutions/python3/bak/1223.py.bak @@ -0,0 +1,11 @@ +class Solution: + def dieSimulator(self, n: int, r: List[int]) -> int: + K = max(r) + dp = [[[0 for k in range(K)] for j in range(6)] for i in range(n)] + for j in range(6): dp[0][j][0] = 1 + for i in range(1, n): + for j in range(6): + dp[i][j][0] += sum(dp[i-1][t][k] for t in range(6) for k in range(r[t]) if t != j) + for k in range(1, r[j]): + dp[i][j][k] = dp[i-1][j][k-1] + return sum(dp[n-1][j][k] for j in range(6) for k in range(K)) % (10**9+7) \ No newline at end of file diff --git a/solutions/python3/bak/1224.py.bak b/solutions/python3/bak/1224.py.bak new file mode 100644 index 0000000..e2ed581 --- /dev/null +++ b/solutions/python3/bak/1224.py.bak @@ -0,0 +1,24 @@ +class Solution: + def maxEqualFreq(self, nums: List[int]) -> int: + def okay(): + if len(dic) == 1 and (1 in dic or 1 in dic.values()): + return True + if len(dic) == 2: + c1, c2 = sorted(dic.keys()) + if c2 - c1 == 1 and dic[c2] == 1 or (c1 == 1 and dic[1] == 1): + return True + cnt = collections.Counter(nums) + dic = collections.Counter(cnt.values()) + l = len(nums) + for num in nums[::-1]: + if okay(): + return l + dic[cnt[num]] -= 1 + if not dic[cnt[num]]: + dic.pop(cnt[num]) + cnt[num] -= 1 + if cnt[num]: + dic[cnt[num]] += 1 + l -= 1 + if okay(): + return l \ No newline at end of file diff --git a/solutions/python3/bak/1227.py.bak b/solutions/python3/bak/1227.py.bak new file mode 100644 index 0000000..b624127 --- /dev/null +++ b/solutions/python3/bak/1227.py.bak @@ -0,0 +1,3 @@ +class Solution: + def nthPersonGetsNthSeat(self, n: int) -> float: + return max(0.5, 1 / n) \ No newline at end of file diff --git a/solutions/python3/bak/1228.py.bak b/solutions/python3/bak/1228.py.bak new file mode 100644 index 0000000..9e909e3 --- /dev/null +++ b/solutions/python3/bak/1228.py.bak @@ -0,0 +1,8 @@ +class Solution: + def missingNumber(self, arr: List[int]) -> int: + d = (arr[-1] - arr[0]) // len(arr) + for a, b in zip(arr, arr[1:]): + if b != a + d: + return a + d + return 0 + \ No newline at end of file diff --git a/solutions/python3/bak/1229.py.bak b/solutions/python3/bak/1229.py.bak new file mode 100644 index 0000000..d0893d4 --- /dev/null +++ b/solutions/python3/bak/1229.py.bak @@ -0,0 +1,11 @@ +class Solution: + def minAvailableDuration(self, s1: List[List[int]], s2: List[List[int]], d: int) -> List[int]: + s2.sort() + j = 0 + for s, e in sorted(s1): + while j < len(s2) - 1 and s2[j][1] < s: + j += 1 + if s2[j][0] <= e: + l, r = max(s, s2[j][0]), min(e,s2[j][1]) + if r - l >= d: + return [l, l + d] \ No newline at end of file diff --git a/solutions/python3/bak/123.py.bak b/solutions/python3/bak/123.py.bak new file mode 100644 index 0000000..84028f9 --- /dev/null +++ b/solutions/python3/bak/123.py.bak @@ -0,0 +1,10 @@ +class Solution: + def maxProfit(self, prices): + s1 = s2 = 0 + b1 = b2 = -float("inf") + for p in prices: + if -p > b1: b1 = -p + if b1 + p > s1: s1 = b1 + p + if s1 - p > b2: b2 = s1 - p + if b2 + p > s2: s2 = b2 + p + return s2 \ No newline at end of file diff --git a/solutions/python3/bak/1230.py.bak b/solutions/python3/bak/1230.py.bak new file mode 100644 index 0000000..4ac0e34 --- /dev/null +++ b/solutions/python3/bak/1230.py.bak @@ -0,0 +1,13 @@ +class Solution: + def probabilityOfHeads(self, p: List[float], t: int) -> float: + n = len(p) + dp = [[0] * (n + 1) for _ in range(n + 1)] + dp[0][0] = 1 + for i in range(1, n + 1): + for j in range(i + 1): + if j == 0: + dp[i][j] = dp[i - 1][j] * (1 - p[i - 1]) + else : + dp[i][j] = (dp[i - 1][j] * (1.0 - p[i - 1])) + (dp[i - 1][j - 1] * p[i - 1]) + return dp[-1][t] + \ No newline at end of file diff --git a/solutions/python3/bak/1231.py.bak b/solutions/python3/bak/1231.py.bak new file mode 100644 index 0000000..136e220 --- /dev/null +++ b/solutions/python3/bak/1231.py.bak @@ -0,0 +1,20 @@ +class Solution: + def maximizeSweetness(self, sw: List[int], K: int) -> int: + def ok(m): + c = sm = 0 + for s in sw: + sm += s + if sm >= m: + sm = 0 + c += 1 + return c >= K + 1 + l, r = 1, sum(sw) + while l < r: + m = (l + r) // 2 + if ok(m): + l = m + 1 + else: + r = m - 1 + print(l, r) + return r if ok(r) else l - 1 + \ No newline at end of file diff --git a/solutions/python3/bak/1232.py.bak b/solutions/python3/bak/1232.py.bak new file mode 100644 index 0000000..f0e39a8 --- /dev/null +++ b/solutions/python3/bak/1232.py.bak @@ -0,0 +1,3 @@ +class Solution: + def checkStraightLine(self, c: List[List[int]]) -> bool: + return len(set(a[0] == b[0] or (b[1] - a[1]) / (b[0] - a[0]) for a, b in zip(c, c[1:]))) == 1 \ No newline at end of file diff --git a/solutions/python3/bak/1233.py.bak b/solutions/python3/bak/1233.py.bak new file mode 100644 index 0000000..61d58db --- /dev/null +++ b/solutions/python3/bak/1233.py.bak @@ -0,0 +1,7 @@ +class Solution: + def removeSubfolders(self, folder: List[str]) -> List[str]: + st = set(folder) + for f in folder: + if any(p in st for p in itertools.accumulate(f.split('/'), lambda x, y: x + '/' + y) if p and p != f): + st.discard(f) + return list(st) \ No newline at end of file diff --git a/solutions/python3/bak/1234.py.bak b/solutions/python3/bak/1234.py.bak new file mode 100644 index 0000000..bf9410a --- /dev/null +++ b/solutions/python3/bak/1234.py.bak @@ -0,0 +1,11 @@ +class Solution: + def balancedString(self, s: str) -> int: + cnt, i, res = {c: max(s.count(c) - len(s) // 4, 0) for c in 'QWER'}, 0, len(s) + for j, c in enumerate(s): + cnt[c] -= 1 + while i < len(s) and cnt[s[i]] < 0: + cnt[s[i]] += 1 + i += 1 + if not any(cnt[c] > 0 for c in 'QWER'): + res = min(res, j - i + 1) + return res \ No newline at end of file diff --git a/solutions/python3/bak/1235.py.bak b/solutions/python3/bak/1235.py.bak new file mode 100644 index 0000000..62f94c3 --- /dev/null +++ b/solutions/python3/bak/1235.py.bak @@ -0,0 +1,9 @@ +class Solution: + def jobScheduling(self, startTime: List[int], endTime: List[int], profit: List[int]) -> int: + jobs = sorted(zip(startTime, endTime, profit), key=lambda v: v[1]) + dp = [[0, 0]] + for s, e, p in jobs: + i = bisect.bisect(dp, [s + 1]) - 1 + if dp[i][1] + p > dp[-1][1]: + dp.append([e, dp[i][1] + p]) + return dp[-1][1] \ No newline at end of file diff --git a/solutions/python3/bak/1236.py.bak b/solutions/python3/bak/1236.py.bak new file mode 100644 index 0000000..86dd2e3 --- /dev/null +++ b/solutions/python3/bak/1236.py.bak @@ -0,0 +1,21 @@ +# """ +# This is HtmlParser's API interface. +# You should not implement it, or speculate about its implementation +# """ +#class HtmlParser(object): +# def getUrls(self, url): +# """ +# :type url: str +# :rtype List[str] +# """ + +class Solution: + def crawl(self, startUrl: str, htmlParser: 'HtmlParser') -> List[str]: + host = startUrl[:(startUrl + '/').find('/', startUrl.find('//') + 2)] + q, seen = [startUrl], {startUrl} + for url in q: + for nex in htmlParser.getUrls(url): + if nex[:(nex + '/').find('/', nex.find('//') + 2)] == host and nex not in seen: + q.append(nex) + seen.add(nex) + return q \ No newline at end of file diff --git a/solutions/python3/bak/1237.py.bak b/solutions/python3/bak/1237.py.bak new file mode 100644 index 0000000..bab0ce2 --- /dev/null +++ b/solutions/python3/bak/1237.py.bak @@ -0,0 +1,11 @@ +from itertools import product as pr + + +class Solution(object): + def findSolution(self, customfunction, z): + return [ + [i, j] + for i, j in pr(range(1, z + 1), repeat=2) + if customfunction.f(i, j) == z + ] + diff --git a/solutions/python3/bak/1238.py.bak b/solutions/python3/bak/1238.py.bak new file mode 100644 index 0000000..b70ed27 --- /dev/null +++ b/solutions/python3/bak/1238.py.bak @@ -0,0 +1,3 @@ +class Solution: + def circularPermutation(self, n: int, start: int) -> List[int]: + return [start ^ i ^ i >> 1 for i in range(1 << n)] diff --git a/solutions/python3/bak/1239.py.bak b/solutions/python3/bak/1239.py.bak new file mode 100644 index 0000000..f8d8521 --- /dev/null +++ b/solutions/python3/bak/1239.py.bak @@ -0,0 +1,6 @@ +class Solution: + def maxLength(self, arr: List[str]) -> int: + bfs = [""] + for b in filter(lambda x: len(x) == len(set(x)), arr): + bfs += [a + b for a in bfs if not set(a) & set(b)] + return max(map(len, bfs)) diff --git a/solutions/python3/bak/124.py.bak b/solutions/python3/bak/124.py.bak new file mode 100644 index 0000000..5add729 --- /dev/null +++ b/solutions/python3/bak/124.py.bak @@ -0,0 +1,11 @@ +class Solution: + def maxPathSum(self, root): + res = [-float("inf")] + def dfs(node): + if not node: return -float("inf") + l, r = dfs(node.left), dfs(node.right) + mx = max(node.val, l + node.val, r + node.val) + res[0] = max(res[0], mx, node.val + l + r) + return mx + dfs(root) + return res[0] \ No newline at end of file diff --git a/solutions/python3/bak/1240.py.bak b/solutions/python3/bak/1240.py.bak new file mode 100644 index 0000000..afb36a4 --- /dev/null +++ b/solutions/python3/bak/1240.py.bak @@ -0,0 +1,20 @@ +class Solution: + memo = {} + + def tilingRectangle(self, n: int, m: int) -> int: + if (n, m) in {(11, 13), (13, 11)}: + return 6 + if n == m: + return 1 + if (n, m) not in self.memo: + nMin = mMin = float("inf") + for i in range(1, n // 2 + 1): + nMin = min( + nMin, self.tilingRectangle(i, m) + self.tilingRectangle(n - i, m) + ) + for j in range(1, m // 2 + 1): + mMin = min( + mMin, self.tilingRectangle(n, j) + self.tilingRectangle(n, m - j) + ) + self.memo[(n, m)] = min(nMin, mMin) + return self.memo[(n, m)] diff --git a/solutions/python3/bak/1243.py.bak b/solutions/python3/bak/1243.py.bak new file mode 100644 index 0000000..4ec2ebf --- /dev/null +++ b/solutions/python3/bak/1243.py.bak @@ -0,0 +1,13 @@ +class Solution: + def transformArray(self, arr: List[int], change: bool = True) -> List[int]: + while change: + new = ( + arr[:1] + + [ + b + (a > b < c) - (a < b > c) + for a, b, c in zip(arr, arr[1:], arr[2:]) + ] + + arr[-1:] + ) + arr, change = new, arr != new + return arr diff --git a/solutions/python3/bak/1244.py.bak b/solutions/python3/bak/1244.py.bak new file mode 100644 index 0000000..edf6a52 --- /dev/null +++ b/solutions/python3/bak/1244.py.bak @@ -0,0 +1,25 @@ +class Leaderboard: + def __init__(self): + self.scores = collections.defaultdict(set) + self.p = collections.defaultdict(int) + + def addScore(self, playerId: int, score: int) -> None: + self.scores[self.p[playerId]].discard(playerId) + self.p[playerId] += score + self.scores[self.p[playerId]].add(playerId) + + def top(self, K: int) -> int: + sm = cnt = 0 + for score, players in sorted(self.scores.items())[::-1]: + if len(players) + cnt <= K: + sm += len(players) * score + cnt += len(players) + else: + sm += (K - cnt) * score + cnt = K + return sm + + def reset(self, playerId: int) -> None: + self.scores[self.p[playerId]].discard(playerId) + self.p[playerId] = 0 + self.scores[0].add(playerId) diff --git a/solutions/python3/bak/1245.py.bak b/solutions/python3/bak/1245.py.bak new file mode 100644 index 0000000..a16260a --- /dev/null +++ b/solutions/python3/bak/1245.py.bak @@ -0,0 +1,13 @@ +class Solution: + def treeDiameter(self, edges: List[List[int]], move: int = 0) -> int: + graph = collections.defaultdict(set) + for a, b in edges: + graph[a].add(b) + graph[b].add(a) + bfs = {(u, None) for u, nex in graph.items() if len(nex) == 1} + while bfs: + bfs, move = ( + {(v, u) for u, pre in bfs for v in graph[u] if v != pre}, + move + 1, + ) + return max(move - 1, 0) diff --git a/solutions/python3/bak/1246.py.bak b/solutions/python3/bak/1246.py.bak new file mode 100644 index 0000000..d2ce928 --- /dev/null +++ b/solutions/python3/bak/1246.py.bak @@ -0,0 +1,18 @@ +class Solution: + def minimumMoves(self, arr: List[int]) -> int: + n = len(arr) + dp = [[0] * (n + 1) for _ in range(n + 1)] + for l in range(1, n + 1): + i, j = 0, l - 1 + while j < n: + if l == 1: + dp[i][j] = 1 + else: + dp[i][j] = 1 + dp[i + 1][j] + if arr[i] == arr[i + 1]: + dp[i][j] = min(1 + dp[i + 2][j], dp[i][j]) + for k in range(i + 2, j + 1): + if arr[i] == arr[k]: + dp[i][j] = min(dp[i + 1][k - 1] + dp[k + 1][j], dp[i][j]) + i, j = i + 1, j + 1 + return dp[0][n - 1] diff --git a/solutions/python3/bak/1247.py.bak b/solutions/python3/bak/1247.py.bak new file mode 100644 index 0000000..e8055fe --- /dev/null +++ b/solutions/python3/bak/1247.py.bak @@ -0,0 +1,6 @@ +class Solution: + def minimumSwap(self, s1: str, s2: str, xy: int = 0, yx: int = 0) -> int: + for a, b in zip(s1, s2): + xy += a == "x" and b == "y" + yx += a == "y" and b == "x" + return (xy + yx) // 2 + (xy % 2) * 2 if xy % 2 == yx % 2 else -1 diff --git a/solutions/python3/bak/1248.py.bak b/solutions/python3/bak/1248.py.bak new file mode 100644 index 0000000..1baab49 --- /dev/null +++ b/solutions/python3/bak/1248.py.bak @@ -0,0 +1,8 @@ +class Solution: + def numberOfSubarrays(self, nums: List[int], k: int, cnt: int = 0) -> int: + odds = [-1] + [i for i, num in enumerate(nums) if num % 2] + [len(nums)] + return sum( + (odds[j - k + 1] - odds[j - k]) * (odds[j + 1] - odds[j]) + for j in range(k, len(odds) - 1) + ) + diff --git a/solutions/python3/bak/1249.py.bak b/solutions/python3/bak/1249.py.bak new file mode 100644 index 0000000..acdb868 --- /dev/null +++ b/solutions/python3/bak/1249.py.bak @@ -0,0 +1,13 @@ +class Solution: + def minRemoveToMakeValid( + self, s: str, res: str = "", l: str = "(", r: str = ")", b: int = 0 + ) -> str: + for _ in range(2): + for c in s: + if c == r and b <= 0: + continue + b += c == l + b -= c == r + res += c + res, s, l, r, b = "", res[::-1], r, l, 0 + return s diff --git a/solutions/python3/bak/125.py.bak b/solutions/python3/bak/125.py.bak new file mode 100644 index 0000000..91855bf --- /dev/null +++ b/solutions/python3/bak/125.py.bak @@ -0,0 +1,8 @@ +class Solution: + def isPalindrome(self, s): + """ + :type s: str + :rtype: bool + """ + import string + return True if s=="" or [i.lower() for i in s if i in string.digits or i in string.ascii_letters]==[i.lower() for i in s if i in string.digits or i in string.ascii_letters][::-1] else False \ No newline at end of file diff --git a/solutions/python3/bak/1250.py.bak b/solutions/python3/bak/1250.py.bak new file mode 100644 index 0000000..9735377 --- /dev/null +++ b/solutions/python3/bak/1250.py.bak @@ -0,0 +1,6 @@ +from functools import reduce + + +class Solution: + def isGoodArray(self, nums: List[int]) -> bool: + return reduce(math.gcd, nums) == 1 diff --git a/solutions/python3/bak/1252.py.bak b/solutions/python3/bak/1252.py.bak new file mode 100644 index 0000000..e330cd5 --- /dev/null +++ b/solutions/python3/bak/1252.py.bak @@ -0,0 +1,7 @@ +from collections import Counter as cnt + + +class Solution: + def oddCells(self, n: int, m: int, indices: List[List[int]]) -> int: + row, col = cnt(r for r, c in indices), cnt(c for r, c in indices) + return sum((row[i] + col[j]) % 2 for i in range(n) for j in range(m)) diff --git a/solutions/python3/bak/1253.py.bak b/solutions/python3/bak/1253.py.bak new file mode 100644 index 0000000..774259a --- /dev/null +++ b/solutions/python3/bak/1253.py.bak @@ -0,0 +1,22 @@ +class Solution: + def reconstructMatrix( + self, upper: int, lower: int, colsum: List[int] + ) -> List[List[int]]: + res = [[0] * len(colsum) for _ in range(2)] + for j, sm in enumerate(colsum): + if sm == 2: + if upper == 0 or lower == 0: + return [] + upper -= 1 + lower -= 1 + res[0][j] = res[1][j] = 1 + elif sm: + if upper == lower == 0: + return [] + if upper >= lower: + upper -= 1 + res[0][j] = 1 + else: + lower -= 1 + res[1][j] = 1 + return res if upper == lower == 0 else [] diff --git a/solutions/python3/bak/1254.py.bak b/solutions/python3/bak/1254.py.bak new file mode 100644 index 0000000..bb4597a --- /dev/null +++ b/solutions/python3/bak/1254.py.bak @@ -0,0 +1,15 @@ +class Solution: + def closedIsland(self, grid: List[List[int]]) -> int: + def dfs(i, j, ret=True): + grid[i][j] = -1 + for x, y in (i - 1, j), (i + 1, j), (i, j - 1), (i, j + 1): + if 0 <= x < m and 0 <= y < n: + if not grid[x][y]: + ret &= dfs(x, y) + else: + ret = False + return ret + + m, n = len(grid), len(grid[0]) + return sum(dfs(i, j) for i in range(m) for j in range(n) if grid[i][j] == 0) + diff --git a/solutions/python3/bak/1255.py.bak b/solutions/python3/bak/1255.py.bak new file mode 100644 index 0000000..33957c0 --- /dev/null +++ b/solutions/python3/bak/1255.py.bak @@ -0,0 +1,18 @@ +from collections import Counter as cnt + + +class Solution: + def maxScoreWords(self, w: List[str], l: List[str], s: List[int]) -> int: + def dfs(use, i): + return ( + use + and i < len(w) + and max( + dfs(use, i + 1), + not cnt(w[i]) - use + and sum(s[ord(c) - ord("a")] for c in w[i]) + + dfs(use - cnt(w[i]), i + 1), + ) + ) + + return int(dfs(cnt(l), 0)) diff --git a/solutions/python3/bak/1256.py.bak b/solutions/python3/bak/1256.py.bak new file mode 100644 index 0000000..df29e76 --- /dev/null +++ b/solutions/python3/bak/1256.py.bak @@ -0,0 +1,3 @@ +class Solution: + def encode(self, num: int) -> str: + return bin(num + 1)[3:] diff --git a/solutions/python3/bak/1257.py.bak b/solutions/python3/bak/1257.py.bak new file mode 100644 index 0000000..0897457 --- /dev/null +++ b/solutions/python3/bak/1257.py.bak @@ -0,0 +1,10 @@ +class Solution: + def findSmallestRegion( + self, regions: List[List[str]], region1: str, region2: str + ) -> str: + nex = {r: region[0] for region in regions for r in region[1:]} + r1, r2 = region1, region2 + while r1 != r2: + r1 = nex[r1] if r1 in nex else region2 + r2 = nex[r2] if r2 in nex else region1 + return r1 diff --git a/solutions/python3/bak/1258.py.bak b/solutions/python3/bak/1258.py.bak new file mode 100644 index 0000000..9548c3d --- /dev/null +++ b/solutions/python3/bak/1258.py.bak @@ -0,0 +1,13 @@ +class Solution: + def generateSentences(self, synonyms: List[List[str]], text: str) -> List[str]: + def root(s): + return s if parent[s] == s else root(parent[s]) + + parent = {s: s for s in [c for sy in synonyms for c in sy] + text.split()} + for a, b in synonyms: + parent[root(a)] = root(b) + bfs = [""] + for t in text.split(): + r = root(t) + bfs = [s + " " + w for s in bfs for w in parent if root(w) == r] + return sorted(s[1:] for s in bfs) diff --git a/solutions/python3/bak/1259.py.bak b/solutions/python3/bak/1259.py.bak new file mode 100644 index 0000000..25be930 --- /dev/null +++ b/solutions/python3/bak/1259.py.bak @@ -0,0 +1,12 @@ +class Solution: + def numberOfWays(self, num_people): + self.memo = {0: 1} + + def dp(n): + if n not in self.memo: + self.memo[n] = sum( + [dp(i - 2) * dp(n - i) for i in range(2, n + 1, 2)] + ) % (10 ** 9 + 7) + return self.memo[n] + + return dp(num_people) diff --git a/solutions/python3/bak/126.py.bak b/solutions/python3/bak/126.py.bak new file mode 100644 index 0000000..3806d26 --- /dev/null +++ b/solutions/python3/bak/126.py.bak @@ -0,0 +1,18 @@ +class Solution: + def findLadders(self, beginWord, endWord, wordList): + words, res, layer = set(wordList), [], {beginWord: [[beginWord]]} + while layer: + newlayer = collections.defaultdict(list) + for w in layer: + if w == endWord: + for arr in layer[w]: + res.append(arr) + else: + for i in range(len(w)): + for c in string.ascii_lowercase: + neww = w[:i] + c + w[i + 1:] + if neww in words: + newlayer[neww] += [j + [neww] for j in layer[w]] + words -= set(newlayer.keys()) + layer = newlayer + return res \ No newline at end of file diff --git a/solutions/python3/bak/1260.py.bak b/solutions/python3/bak/1260.py.bak new file mode 100644 index 0000000..8f03e9d --- /dev/null +++ b/solutions/python3/bak/1260.py.bak @@ -0,0 +1,7 @@ +class Solution: + def shiftGrid(self, grid: List[List[int]], k: int) -> List[List[int]]: + chain = [r for row in grid for r in row] + k %= len(chain) + chain = chain[-k:] + chain[:-k] + return [chain[i : i + len(grid[0])] for i in range(0, len(chain), len(grid[0]))] + diff --git a/solutions/python3/bak/1261.py.bak b/solutions/python3/bak/1261.py.bak new file mode 100644 index 0000000..ae7f6bc --- /dev/null +++ b/solutions/python3/bak/1261.py.bak @@ -0,0 +1,15 @@ +class FindElements: + def dfs(self, node: TreeNode, real: int = 0): + if node: + node.val = real + self.nums.add(node.val) + self.dfs(node.left, real * 2 + 1) + self.dfs(node.right, real * 2 + 2) + + def __init__(self, root: TreeNode): + self.root = root + self.nums = set() + self.dfs(root) + + def find(self, target: int) -> bool: + return target in self.nums diff --git a/solutions/python3/bak/1262.py.bak b/solutions/python3/bak/1262.py.bak new file mode 100644 index 0000000..a4d6f3e --- /dev/null +++ b/solutions/python3/bak/1262.py.bak @@ -0,0 +1,7 @@ +class Solution: + def maxSumDivThree( + self, nums: List[int], dp: list = [0, -float("inf"), -float("inf")] + ) -> int: + for num in nums: + dp = [max(dp[i], dp[(i - num) % 3] + num) for i in range(3)] + return dp[0] diff --git a/solutions/python3/bak/1263.py.bak b/solutions/python3/bak/1263.py.bak new file mode 100644 index 0000000..8493807 --- /dev/null +++ b/solutions/python3/bak/1263.py.bak @@ -0,0 +1,51 @@ +class Solution: + def minPushBox(self, grid: List[List[str]]) -> int: + m, n = len(grid), len(grid[0]) + for r in range(m): + for c in range(n): + if grid[r][c] == "T": + tX, tY = r, c + if grid[r][c] == "B": + bX, bY = r, c + if grid[r][c] == "S": + pX, pY = r, c + + def heuristic(bX, bY): + return abs(tX - bX) + abs(tY - bY) + + heap = [[heuristic(bX, bY), 0, pX, pY, bX, bY]] + visited = set() + while heap: + _, moves, pX, pY, bX, bY = heapq.heappop(heap) + if bX == tX and bY == tY: + return moves + if (pX, pY, bX, bY) not in visited: + visited.add((pX, pY, bX, bY)) + for dx, dy in (0, 1), (1, 0), (-1, 0), (0, -1): + pX += dx + pY += dy + if 0 <= pX < m and 0 <= pY < n and grid[pX][pY] != "#": + if pX == bX and pY == bY: + bX += dx + bY += dy + if 0 <= bX < m and 0 <= bY < n and grid[bX][bY] != "#": + heapq.heappush( + heap, + [ + heuristic(bX, bY) + moves + 1, + moves + 1, + pX, + pY, + bX, + bY, + ], + ) + bX -= dx + bY -= dy + else: + heapq.heappush( + heap, [heuristic(bX, bY) + moves, moves, pX, pY, bX, bY] + ) + pX -= dx + pY -= dy + return -1 diff --git a/solutions/python3/bak/127.py.bak b/solutions/python3/bak/127.py.bak new file mode 100644 index 0000000..2982c00 --- /dev/null +++ b/solutions/python3/bak/127.py.bak @@ -0,0 +1,17 @@ +class Solution: + def ladderLength(self, beginWord, endWord, wordList): + words, layer = set(wordList), {beginWord: [[beginWord]]} + while layer: + newlayer = collections.defaultdict(list) + for w in layer: + if w == endWord: + return len(layer[w][0]) + else: + for i in range(len(w)): + for c in string.ascii_lowercase: + neww = w[:i] + c + w[i + 1:] + if neww in words: + newlayer[neww] += [j + [neww] for j in layer[w]] + words -= set(newlayer.keys()) + layer = newlayer + return 0 \ No newline at end of file diff --git a/solutions/python3/bak/128.py.bak b/solutions/python3/bak/128.py.bak new file mode 100644 index 0000000..6852c92 --- /dev/null +++ b/solutions/python3/bak/128.py.bak @@ -0,0 +1,10 @@ +class Solution: + def longestConsecutive(self, nums): + res, items = 0, set(nums) + for num in items: + if num - 1 not in items: + cur = 1 + while num + 1 in items: + num, cur = num + 1, cur + 1 + if cur > res: res = cur + return res \ No newline at end of file diff --git a/solutions/python3/bak/129.py.bak b/solutions/python3/bak/129.py.bak new file mode 100644 index 0000000..a4c8d14 --- /dev/null +++ b/solutions/python3/bak/129.py.bak @@ -0,0 +1,21 @@ +# Definition for a binary tree node. +# class TreeNode: +# def __init__(self, x): +# self.val = x +# self.left = None +# self.right = None + +class Solution: + def sumNumbers(self, root): + """ + :type root: TreeNode + :rtype: int + """ + def traverse(node, q): + if not node: return + traverse(node.left, q + [str(node.val)]) + traverse(node.right, q + [str(node.val)]) + if not node.left and not node.right: res[0] += int("".join(q + [str(node.val)])) + res = [0] + traverse(root, []) + return res[0] \ No newline at end of file diff --git a/solutions/python3/bak/13.py.bak b/solutions/python3/bak/13.py.bak new file mode 100644 index 0000000..fe99722 --- /dev/null +++ b/solutions/python3/bak/13.py.bak @@ -0,0 +1,10 @@ +class Solution: + def romanToInt(self, s): + table = {"M": 1000, "D": 500, "C": 100, "L": 50, "X": 10, "V": 5, "I": 1} + sm, pre = 0, 'I' + for c in s[::-1]: + if table[c] < table[pre]: + sm, pre = sm - table[c], c + else: + sm, pre = sm + table[c], c + return sm \ No newline at end of file diff --git a/solutions/python3/bak/130.py.bak b/solutions/python3/bak/130.py.bak new file mode 100644 index 0000000..8edd45e --- /dev/null +++ b/solutions/python3/bak/130.py.bak @@ -0,0 +1,26 @@ +class Solution: + def solve(self, board: List[List[str]]) -> None: + m, n = len(board), len(board and board[0]) + + def explore(i, j): + board[i][j] = "S" + for x, y in ((i - 1, j), (i + 1, j), (i, j - 1), (i, j + 1)): + if 0 <= x < m and 0 <= y < n and board[x][y] == "O": + explore(x, y) + + for i in range(max(m, n)): + if i < m and board[i][0] == "O": + explore(i, 0) + if i < m and board[i][n - 1] == "O": + explore(i, n - 1) + if i < n and board[0][i] == "O": + explore(0, i) + if i < n and board[m - 1][i] == "O": + explore(m - 1, i) + for i in range(m): + for j in range(n): + if board[i][j] == "S": + board[i][j] = "O" + elif board[i][j] == "O": + board[i][j] = "X" + diff --git a/solutions/python3/bak/131.py.bak b/solutions/python3/bak/131.py.bak new file mode 100644 index 0000000..18931bc --- /dev/null +++ b/solutions/python3/bak/131.py.bak @@ -0,0 +1,13 @@ +class Solution: + def partition(self, s): + q, n = [[s[0]]], len(s) + for i in range(1, n): + new = [] + for arr in q: + cur = arr[-1] + s[i] + if i < n - 1 or cur == cur[::-1]: + new.append(arr[:-1] + [cur]) + if arr[-1] == arr[-1][::-1]: + new.append(arr + [s[i]]) + q = new + return q \ No newline at end of file diff --git a/solutions/python3/bak/132.py.bak b/solutions/python3/bak/132.py.bak new file mode 100644 index 0000000..a39a222 --- /dev/null +++ b/solutions/python3/bak/132.py.bak @@ -0,0 +1,14 @@ +class Solution: + def minCut(self, s): + q, pal, used = [(0, 0)], collections.defaultdict(list), {(0, 0)} + for i in range(len(s)): + for j in range(i, len(s)): + if s[i:j + 1] == s[i:j + 1][::-1]: pal[i].append(j + 1) + while q: + cuts, i = heapq.heappop(q) + i *= -1 + if i == len(s): return cuts - 1 + for j in pal[i]: + if (cuts + 1, -j) not in used: + used.add((cuts + 1, -j)) + heapq.heappush(q, (cuts + 1, -j)) \ No newline at end of file diff --git a/solutions/python3/bak/133.py.bak b/solutions/python3/bak/133.py.bak new file mode 100644 index 0000000..73e928c --- /dev/null +++ b/solutions/python3/bak/133.py.bak @@ -0,0 +1,14 @@ +class Solution: + def cloneGraph(self, node: "Node") -> "Node": + visited = {} + + def dfs(node): + if node and node.val not in visited: + newNode = Node(node.val, []) + visited[newNode.val] = newNode + newNode.neighbors = [ + visited.get(n.val) or dfs(n) for n in node.neighbors + ] + return newNode + + return dfs(node) diff --git a/solutions/python3/bak/134.py.bak b/solutions/python3/bak/134.py.bak new file mode 100644 index 0000000..496de65 --- /dev/null +++ b/solutions/python3/bak/134.py.bak @@ -0,0 +1,6 @@ +class Solution: + def canCompleteCircuit(self, gas, cost, cur = 0, index = 0): + for i in range(len(gas)): + cur += gas[i] - cost[i] + if cur < 0: cur, index = 0, i + 1 + return index if index < len(gas) and sum(gas) >= sum(cost) else -1 \ No newline at end of file diff --git a/solutions/python3/bak/135.py.bak b/solutions/python3/bak/135.py.bak new file mode 100644 index 0000000..84fb071 --- /dev/null +++ b/solutions/python3/bak/135.py.bak @@ -0,0 +1,10 @@ +class Solution: + def candy(self, ratings): + dp = [1] * len(ratings) + for i in range(1, len(ratings)): + if ratings[i] > ratings[i - 1]: + dp[i] = dp[i - 1] + 1 + for i in range(len(ratings) - 2, -1, -1): + if ratings[i] > ratings[i + 1] and dp[i] <= dp[i + 1]: + dp[i] = dp[i + 1] + 1 + return sum(dp) \ No newline at end of file diff --git a/solutions/python3/bak/136.py.bak b/solutions/python3/bak/136.py.bak new file mode 100644 index 0000000..180e617 --- /dev/null +++ b/solutions/python3/bak/136.py.bak @@ -0,0 +1,11 @@ +class Solution: + def singleNumber(self, nums): + """ + :type nums: List[int] + :rtype: int + """ + dic={} + for num in nums: + if not num in dic: dic[num]=1 + else: dic.pop(num) + return list(dic.keys())[0] \ No newline at end of file diff --git a/solutions/python3/bak/137.py.bak b/solutions/python3/bak/137.py.bak new file mode 100644 index 0000000..5ffb396 --- /dev/null +++ b/solutions/python3/bak/137.py.bak @@ -0,0 +1,7 @@ +class Solution: + def singleNumber(self, nums): + """ + :type nums: List[int] + :rtype: int + """ + return ((sum(set(nums)) * 3) - sum(nums)) // 2 \ No newline at end of file diff --git a/solutions/python3/bak/138.py.bak b/solutions/python3/bak/138.py.bak new file mode 100644 index 0000000..7ab1ad5 --- /dev/null +++ b/solutions/python3/bak/138.py.bak @@ -0,0 +1,11 @@ +class Solution: + def copyRandomList(self, head: "Node") -> "Node": + dic = collections.defaultdict(lambda: Node(0, None, None)) + dic[None] = None + n = head + while n: + dic[n].val = n.val + dic[n].next = dic[n.next] + dic[n].random = dic[n.random] + n = n.next + return dic[head] diff --git a/solutions/python3/bak/139.py.bak b/solutions/python3/bak/139.py.bak new file mode 100644 index 0000000..e8ad38d --- /dev/null +++ b/solutions/python3/bak/139.py.bak @@ -0,0 +1,11 @@ +class Solution: + def wordBreak(self, s, wordDict): + rightmosts, words = [0], set(wordDict) + for i in range(1, len(s) + 1): + for last_index in rightmosts: + if s[last_index:i] in words: + rightmosts.append(i) + if i == len(s): + return True + break + return False \ No newline at end of file diff --git a/solutions/python3/bak/14.py.bak b/solutions/python3/bak/14.py.bak new file mode 100644 index 0000000..c26a2df --- /dev/null +++ b/solutions/python3/bak/14.py.bak @@ -0,0 +1,6 @@ +class Solution: + def longestCommonPrefix(self, s: List[str]) -> str: + j = 0 + while s and all(j < len(s[i]) and j < len(s[i - 1]) and s[i][j] == s[i - 1][j] for i in range(len(s))): + j += 1 + return s[0][:j] if j else '' \ No newline at end of file diff --git a/solutions/python3/bak/140.py.bak b/solutions/python3/bak/140.py.bak new file mode 100644 index 0000000..8cdaa09 --- /dev/null +++ b/solutions/python3/bak/140.py.bak @@ -0,0 +1,24 @@ +class Solution: + def wordBreak(self, s, wordDict): + def breakable(): + rightmosts = [0] + for i in range(1, len(s) + 1): + for last_index in rightmosts: + if s[last_index:i] in words: + rightmosts.append(i) + if i == len(s): + return True + break + return False + q, res, words = [("", 0)], [], set(wordDict) + if breakable(): + for j in range(1, len(s) + 1): + new = q[:] + for seq, i in q: + if s[i:j] in words: + if j == len(s): + res.append(seq and seq + " " + s[i:j] or s[i:j]) + else: + new.append((seq and seq + " " + s[i:j] or s[i:j], j)) + q = new + return res \ No newline at end of file diff --git a/solutions/python3/bak/141.py.bak b/solutions/python3/bak/141.py.bak new file mode 100644 index 0000000..f118084 --- /dev/null +++ b/solutions/python3/bak/141.py.bak @@ -0,0 +1,8 @@ +class Solution: + def hasCycle(self, head: ListNode) -> bool: + slow, fast = head, head.next if head else None + while slow != None and fast != None: + if slow == fast: + return True + slow, fast = slow.next, fast.next.next if fast.next else None + return False diff --git a/solutions/python3/bak/142.py.bak b/solutions/python3/bak/142.py.bak new file mode 100644 index 0000000..ad63238 --- /dev/null +++ b/solutions/python3/bak/142.py.bak @@ -0,0 +1,11 @@ +class Solution: + def detectCycle(self, head: ListNode) -> ListNode: + fast = slow = root = head + while fast and fast.next: + slow = slow.next + fast = fast.next.next + if slow == fast: + while root != slow: + root = root.next + slow = slow.next + return root diff --git a/solutions/python3/bak/143.py.bak b/solutions/python3/bak/143.py.bak new file mode 100644 index 0000000..ccca6cc --- /dev/null +++ b/solutions/python3/bak/143.py.bak @@ -0,0 +1,16 @@ +# Definition for singly-linked list. +# class ListNode: +# def __init__(self, x): +# self.val = x +# self.next = None +class Solution(object): + def reorderList(self, head): + if head: + arr = [] + while head: + arr += head, + head = head.next + l, r, prev = 0, len(arr) - 1, ListNode(0) + while l < r: prev.next, arr[l].next, prev, l, r = arr[l], arr[r], arr[r], l + 1, r - 1 + if l == r: prev.next = arr[l] + arr[l].next = None \ No newline at end of file diff --git a/solutions/python3/bak/144.py.bak b/solutions/python3/bak/144.py.bak new file mode 100644 index 0000000..6e6ee6b --- /dev/null +++ b/solutions/python3/bak/144.py.bak @@ -0,0 +1,26 @@ +# Definition for a binary tree node. +# class TreeNode: +# def __init__(self, x): +# self.val = x +# self.left = None +# self.right = None + +class Solution: + def preorderTraversal(self, root): + """ + :type root: TreeNode + :rtype: List[int] + """ + res = [root] + q = [root] + while any(q): + tmp = [] + for node in q: + if node.right: + res.insert(res.index(node) + 1, node.right) + tmp.append(node.right) + if node.left: + res.insert(res.index(node) + 1, node.left) + tmp.insert(-1, node.left) + q = tmp + return [j.val for j in res if j] \ No newline at end of file diff --git a/solutions/python3/bak/145.py.bak b/solutions/python3/bak/145.py.bak new file mode 100644 index 0000000..c84f8d5 --- /dev/null +++ b/solutions/python3/bak/145.py.bak @@ -0,0 +1,8 @@ +class Solution: + def postorderTraversal(self, root): + ret, stack = [], root and [root] + while stack: + node = stack.pop() + ret.append(node.val) + stack += [child for child in (node.left, node.right) if child] + return ret[::-1] \ No newline at end of file diff --git a/solutions/python3/bak/146.py.bak b/solutions/python3/bak/146.py.bak new file mode 100644 index 0000000..083439a --- /dev/null +++ b/solutions/python3/bak/146.py.bak @@ -0,0 +1,39 @@ +class Node: + def __init__(self, key, value): + self.key = key + self.val = value + self.next = self.pre = None + self.pre = None +class LRUCache: + def remove(self, node): + node.pre.next, node.next.pre = node.next, node.pre + self.dic.pop(node.key) + + def add(self, node): + node.pre = self.tail.pre + node.next = self.tail + self.tail.pre.next = self.tail.pre = node + self.dic[node.key] = node + + def __init__(self, capacity): + self.dic = {} + self.n = capacity + self.head = self.tail = Node(0, 0) + self.head.next = self.tail + self.tail.pre = self.head + + def get(self, key): + if key in self.dic: + node = self.dic[key] + self.remove(node) + self.add(node) + return node.val + return -1 + + def put(self, key, value): + if key in self.dic: + self.remove(self.dic[key]) + node = Node(key, value) + self.add(node) + if len(self.dic) > self.n: + self.remove(self.head.next) \ No newline at end of file diff --git a/solutions/python3/bak/147.py.bak b/solutions/python3/bak/147.py.bak new file mode 100644 index 0000000..df32d95 --- /dev/null +++ b/solutions/python3/bak/147.py.bak @@ -0,0 +1,25 @@ +# Definition for singly-linked list. +# class ListNode: +# def __init__(self, x): +# self.val = x +# self.next = None + +class Solution: + def insertionSortList(self, head): + """ + :type head: ListNode + :rtype: ListNode + """ + ref, ref.next, n = ListNode(-float("inf")), head, 0 + while head: + inserted, curr, prev, n = ListNode(head.val), ref.next, ref, n+1 + for i in range(n-1): + if inserted.val= n-2: curr.next = None + break + else: + prev, curr = curr, curr.next + if i == n-2: prev.next = inserted + head = head.next + return ref.next \ No newline at end of file diff --git a/solutions/python3/bak/148.py.bak b/solutions/python3/bak/148.py.bak new file mode 100644 index 0000000..1f089db --- /dev/null +++ b/solutions/python3/bak/148.py.bak @@ -0,0 +1,16 @@ +# Definition for singly-linked list. +# class ListNode: +# def __init__(self, x): +# self.val = x +# self.next = None + +class Solution: + def sortList(self, head): + ls = [] + while head: ls.append(head.val); head = head.next + ls .sort() + root = head = ListNode(ls[0]) if ls else [] + for i in range(1, len(ls)): + head.next = ListNode(ls[i]) + head = head.next + return root \ No newline at end of file diff --git a/solutions/python3/bak/149.py.bak b/solutions/python3/bak/149.py.bak new file mode 100644 index 0000000..ae4dafa --- /dev/null +++ b/solutions/python3/bak/149.py.bak @@ -0,0 +1,30 @@ +# Definition for a point. +# class Point: +# def __init__(self, a=0, b=0): +# self.x = a +# self.y = b + +class Solution: + def maxPoints(self, points): + m, res, roots = {}, 0, set() + for i, p1 in enumerate(points): + if (p1.x, p1.y) not in roots: + roots.add((p1.x, p1.y)) + m.clear() + dup = path = 0 + for j, p2 in enumerate(points): + if i != j: + try: + cur = (p1.y - p2.y) * 100 / (p1.x - p2.x) + except: + if p1.y == p2.y: + dup += 1 + continue + else: + cur = "ver" + m[cur] = m.get(cur, 0) + 1 + if m[cur] > path: + path = m[cur] + if path + dup + 1 > res: + res = path + dup + 1 + return res \ No newline at end of file diff --git a/solutions/python3/bak/15.py.bak b/solutions/python3/bak/15.py.bak new file mode 100644 index 0000000..5620039 --- /dev/null +++ b/solutions/python3/bak/15.py.bak @@ -0,0 +1,15 @@ +class Solution: + def threeSum(self, nums): + res, res_set = [], set() + nums.sort() + for i in range(len(nums) - 2): + l, r = i + 1, len(nums) - 1 + while l < r: + sm = nums[i] + nums[l] + nums[r] + if sm < 0: l += 1 + elif sm > 0: r -= 1 + elif (nums[i], nums[l], nums[r]) not in res_set: + res.append([nums[i], nums[l], nums[r]]) + res_set.add((nums[i], nums[l], nums[r])) + else: l, r = l + 1, r - 1 + return res \ No newline at end of file diff --git a/solutions/python3/bak/150.py.bak b/solutions/python3/bak/150.py.bak new file mode 100644 index 0000000..eb0e488 --- /dev/null +++ b/solutions/python3/bak/150.py.bak @@ -0,0 +1,17 @@ +class Solution: + def evalRPN(self, tokens): + """ + :type tokens: List[str] + :rtype: int + """ + stack = [] + for token in tokens: + if token not in ("+", "-", "*", "/"): stack.append(int(token)) + else: + num2, num1 = stack.pop(), stack.pop() + if token == "+": last = num1 + num2 + elif token == "-": last = num1 - num2 + elif token == "*": last = num1 * num2 + elif token == "/": last = int(num1 / num2) + stack.append(last) + return stack[0] \ No newline at end of file diff --git a/solutions/python3/bak/151.py.bak b/solutions/python3/bak/151.py.bak new file mode 100644 index 0000000..b6ef650 --- /dev/null +++ b/solutions/python3/bak/151.py.bak @@ -0,0 +1,3 @@ +class Solution: + def reverseWords(self, s: str) -> str: + return " ".join(s.split()[::-1]) diff --git a/solutions/python3/bak/152.py.bak b/solutions/python3/bak/152.py.bak new file mode 100644 index 0000000..58ae8ac --- /dev/null +++ b/solutions/python3/bak/152.py.bak @@ -0,0 +1,12 @@ +class Solution: + def maxProduct(self, nums): + res, min_pos, max_neg, cur = -float("inf"), float("inf"), -float("inf"), 1 + for num in nums: + cur *= num + if cur > res: res = cur + elif 0 < cur // min_pos > res: res = cur // min_pos + elif 0 < cur // max_neg > res: res = cur // max_neg + if cur == 0: min_pos, max_neg, cur = float("inf"), -float("inf"), 1 + elif max_neg < cur < 0: max_neg = cur + elif 0 < cur < min_pos: min_pos = cur + return res \ No newline at end of file diff --git a/solutions/python3/bak/153.py.bak b/solutions/python3/bak/153.py.bak new file mode 100644 index 0000000..4eed5f2 --- /dev/null +++ b/solutions/python3/bak/153.py.bak @@ -0,0 +1,2 @@ +class Solution: + findMin = min \ No newline at end of file diff --git a/solutions/python3/bak/154.py.bak b/solutions/python3/bak/154.py.bak new file mode 100644 index 0000000..bbee64f --- /dev/null +++ b/solutions/python3/bak/154.py.bak @@ -0,0 +1,10 @@ +class Solution: + def findMin(self, nums): + l, r, res = 0, len(nums) - 1, nums and nums[0] + while l <= r: + while l < r and nums[l] == nums[l + 1]: l += 1 + while l < r and nums[r] == nums[r - 1]: r -= 1 + mid = (l + r) // 2 + if nums[mid] >= nums[0]: l = mid + 1 + else: r, res = mid - 1, min(res, nums[mid]) + return res \ No newline at end of file diff --git a/solutions/python3/bak/155.py.bak b/solutions/python3/bak/155.py.bak new file mode 100644 index 0000000..fb01b9e --- /dev/null +++ b/solutions/python3/bak/155.py.bak @@ -0,0 +1,35 @@ +class MinStack: + + def __init__(self): + """ + initialize your data structure here. + """ + self.data = [] + def push(self, x): + """ + :type x: int + :rtype: void + """ + if not self.data or x < self.data[-1][1]: self.data.append([x, x]) + else: self.data.append([x, self.data[-1][1]]) + def pop(self): + """ + :rtype: void + """ + self.data.pop() + def top(self): + """ + :rtype: int + """ + return self.data[-1][0] + def getMin(self): + """ + :rtype: int + """ + return self.data[-1][1] +# Your MinStack object will be instantiated and called as such: +# obj = MinStack() +# obj.push(x) +# obj.pop() +# param_3 = obj.top() +# param_4 = obj.getMin() \ No newline at end of file diff --git a/solutions/python3/bak/156.py.bak b/solutions/python3/bak/156.py.bak new file mode 100644 index 0000000..7df5a5b --- /dev/null +++ b/solutions/python3/bak/156.py.bak @@ -0,0 +1,16 @@ +# Definition for a binary tree node. +# class TreeNode: +# def __init__(self, x): +# self.val = x +# self.left = None +# self.right = None + +class Solution: + def upsideDownBinaryTree(self, root): + if root: + left = self.upsideDownBinaryTree(root.left) + self.upsideDownBinaryTree(root.right) + if root.left: + root.left.right, root.left.left = root, root.right + root.right = root.left = None + return left or root \ No newline at end of file diff --git a/solutions/python3/bak/157.py.bak b/solutions/python3/bak/157.py.bak new file mode 100644 index 0000000..146f6b8 --- /dev/null +++ b/solutions/python3/bak/157.py.bak @@ -0,0 +1,11 @@ +class Solution: + def read(self, buf, n): + idx = 0 + while True: + buf4 = [""] * 4 + curr = min(read4(buf4), n - idx) + for i in range(curr): + buf[idx] = buf4[i] + idx += 1 + if curr != 4 or idx == n: + return idx diff --git a/solutions/python3/bak/158.py.bak b/solutions/python3/bak/158.py.bak new file mode 100644 index 0000000..a37b430 --- /dev/null +++ b/solutions/python3/bak/158.py.bak @@ -0,0 +1,33 @@ +""" +The read4 API is already defined for you. + + @param buf, a list of characters + @return an integer + def read4(buf): + +# Below is an example of how the read4 API can be called. +file = File("abcdefghijk") # File is "abcdefghijk", initially file pointer (fp) points to 'a' +buf = [' '] * 4 # Create buffer with enough space to store characters +read4(buf) # read4 returns 4. Now buf = ['a','b','c','d'], fp points to 'e' +read4(buf) # read4 returns 4. Now buf = ['e','f','g','h'], fp points to 'i' +read4(buf) # read4 returns 3. Now buf = ['i','j','k',...], fp points to end of file +""" +class Solution: + + def __init__(self): + self.queue = [] + + def read(self, buf, n): + idx = 0 + while True: + buf4 = [""]*4 + read4(buf4) + self.queue += buf4 + curr = min(len(self.queue), n-idx) + for i in range(curr): + buf[idx] = self.queue.pop(0) + idx+=1 + if curr == 0: + break + return idx + \ No newline at end of file diff --git a/solutions/python3/bak/159.py.bak b/solutions/python3/bak/159.py.bak new file mode 100644 index 0000000..88983f0 --- /dev/null +++ b/solutions/python3/bak/159.py.bak @@ -0,0 +1,14 @@ +class Solution: + def lengthOfLongestSubstringTwoDistinct(self, s): + start = distinct = 0 + cnt = collections.defaultdict(int) + for c in s: + cnt[c] += 1 + if cnt[c] == 1: + distinct += 1 + if distinct > 2: + cnt[s[start]] -= 1 + if not cnt[s[start]]: + distinct -= 1 + start += 1 + return len(s) - start \ No newline at end of file diff --git a/solutions/python3/bak/16.py.bak b/solutions/python3/bak/16.py.bak new file mode 100644 index 0000000..4b57329 --- /dev/null +++ b/solutions/python3/bak/16.py.bak @@ -0,0 +1,14 @@ +class Solution: + def threeSumClosest(self, nums, target): + res = diff = float("inf") + nums.sort() + for i in range(len(nums)): + if i > 0 and nums[i] == nums[i - 1]: continue + l, r = i + 1, len(nums) - 1 + while l < r: + sm = nums[i] + nums[l] + nums[r] + if abs(sm - target) < diff: diff, res = abs(sm - target), sm + if sm < target: l += 1 + elif sm > target: r -= 1 + else: return res + return res \ No newline at end of file diff --git a/solutions/python3/bak/161.py.bak b/solutions/python3/bak/161.py.bak new file mode 100644 index 0000000..f8177ba --- /dev/null +++ b/solutions/python3/bak/161.py.bak @@ -0,0 +1,14 @@ +class Solution: + def isOneEditDistance(self, s, t): + l1, l2, cnt, i, j = len(s), len(t), 0, 0, 0 + while i < l1 and j < l2: + if s[i] != t[j]: + cnt += 1 + if l1 < l2: + i -= 1 + elif l1 > l2: + j -= 1 + i += 1 + j += 1 + l = abs(l1 - l2) + return (cnt == 1 and l <= 1) or (cnt == 0 and l == 1) \ No newline at end of file diff --git a/solutions/python3/bak/162.py.bak b/solutions/python3/bak/162.py.bak new file mode 100644 index 0000000..a32737d --- /dev/null +++ b/solutions/python3/bak/162.py.bak @@ -0,0 +1,9 @@ +class Solution: + def findPeakElement(self, nums): + l, r, n = 0, len(nums) - 1, len(nums) + while l <= r: + mid = (l + r) // 2 + pre, after = mid == 0 and -float("inf") or nums[mid - 1], mid == n - 1 and -float("inf") or nums[mid + 1] + if pre < nums[mid] > after: return mid + elif pre > nums[mid]: r = mid - 1 + else: l = mid + 1 \ No newline at end of file diff --git a/solutions/python3/bak/163.py.bak b/solutions/python3/bak/163.py.bak new file mode 100644 index 0000000..6b67c6e --- /dev/null +++ b/solutions/python3/bak/163.py.bak @@ -0,0 +1,19 @@ +class Solution: + def findMissingRanges(self, nums, lower, upper): + if not nums: + return [str(lower) + "->" + str(upper)] if lower != upper else [str(lower)] + res, n = [], len(nums) + if lower + 1 < nums[0]: + res.append(str(lower) + "->" + str(nums[0] - 1)) + elif lower + 1 == nums[0]: + res.append(str(lower)) + for i in range(1, n): + if nums[i] == nums[i - 1] + 2: + res.append(str(nums[i] - 1)) + elif nums[i] > nums[i - 1] + 2: + res.append(str(nums[i - 1] + 1) + "->" + str(nums[i] - 1)) + if nums[-1] + 1 < upper: + res.append(str(nums[-1] + 1) + "->" + str(upper)) + elif nums[-1] + 1 == upper: + res.append(str(upper)) + return res \ No newline at end of file diff --git a/solutions/python3/bak/164.py.bak b/solutions/python3/bak/164.py.bak new file mode 100644 index 0000000..e7e497e --- /dev/null +++ b/solutions/python3/bak/164.py.bak @@ -0,0 +1,20 @@ +class Solution: + def maximumGap(self, nums): + if len(nums) < 2: + return 0 + n, mn, mx= len(nums), min(nums), max(nums) + bSize = max(1, (mx - mn) // n + 1) + bNum = (mx - mn) // bSize + 1 + buckets = [[float("inf"), -float("inf")] for _ in range(bNum)] + for num in nums: + ind = (num - mn) // bSize + if num < buckets[ind][0]: + buckets[ind][0] = num + if num > buckets[ind][1]: + buckets[ind][1] = num + gap = 0 + for i in range(1, bNum): + if buckets[i] == [float("inf"), -float("inf")]: + buckets[i] = buckets[i - 1] + gap = max(gap , buckets[i][0] - buckets[i - 1][1]) + return gap \ No newline at end of file diff --git a/solutions/python3/bak/165.py.bak b/solutions/python3/bak/165.py.bak new file mode 100644 index 0000000..727ccb4 --- /dev/null +++ b/solutions/python3/bak/165.py.bak @@ -0,0 +1,13 @@ +class Solution: + def compareVersion(self, version1, version2): + def getNum(s): + if not s: return (None, None) + for i in range(len(s)): + if s[i] == ".": return (s[i + 1:], int(s[:i])) + return (None, int(s)) + while True: + version1, n1 = getNum(version1) + version2, n2 = getNum(version2) + if version1 == version2 == n1 == n2 == None: return 0 + if n1 != None and n1 > 0 and (n2 == None or n1 > n2): return 1 + if n2 != None and n2 > 0 and (n1 == None or n2 > n1): return -1 \ No newline at end of file diff --git a/solutions/python3/bak/166.py.bak b/solutions/python3/bak/166.py.bak new file mode 100644 index 0000000..74ec0a6 --- /dev/null +++ b/solutions/python3/bak/166.py.bak @@ -0,0 +1,19 @@ +class Solution: + def fractionToDecimal(self, n, d): + res = ["-"] if n * d < 0 else [""] + n, d = abs(n), abs(d) + res.append(str(n // d)) + n %= d + if not n: return "".join(res) + res.append(".") + mp = {n: len(res)} + while n: + n *= 10 + res.append(str(n // d)) + n %= d + if n in mp: + res.insert(mp[n], "(") + res.append(")") + break + mp[n] = len(res) + return "".join(res) \ No newline at end of file diff --git a/solutions/python3/bak/167.py.bak b/solutions/python3/bak/167.py.bak new file mode 100644 index 0000000..21a21f2 --- /dev/null +++ b/solutions/python3/bak/167.py.bak @@ -0,0 +1,23 @@ +class Solution: + def twoSum(self, numbers, target): + """ + :type numbers: List[int] + :type target: int + :rtype: List[int] + """ + left=numbers[0] + right=numbers[-1] + i,j=0,0 + while True: + sum=left+right + if sum>target: + j+=1 + right=numbers[-1-j] + if sum str: + char = str() + while n > 0: + if n % 26 == 0: + char += "Z" + n = n // 26 - 1 + else: + char += chr(n % 26 + ord("@")) + n = n // 26 + return char[::-1] diff --git a/solutions/python3/bak/169.py.bak b/solutions/python3/bak/169.py.bak new file mode 100644 index 0000000..212b71f --- /dev/null +++ b/solutions/python3/bak/169.py.bak @@ -0,0 +1,13 @@ +class Solution: + def majorityElement(self, nums): + """ + :type nums: List[int] + :rtype: int + """ + num_list=dict() + for num in nums: + if not num in num_list: + num_list[num]=1 + else: + num_list[num]+=1 + return max(num_list, key=num_list.get) \ No newline at end of file diff --git a/solutions/python3/bak/17.py.bak b/solutions/python3/bak/17.py.bak new file mode 100644 index 0000000..9be99cf --- /dev/null +++ b/solutions/python3/bak/17.py.bak @@ -0,0 +1,9 @@ +class Solution: + def letterCombinations(self, digits): + dic, res = { '2': 'abc', '3': 'def', '4': 'ghi', '5': 'jkl', '6': 'mno', '7': 'pqrs', '8': 'tuv', '9': 'wxyz'}, [""] + for dig in digits: + tmp = [] + for y in res: + for x in dic[dig]: tmp.append(y + x) + res = tmp + return res if any(res) else [] \ No newline at end of file diff --git a/solutions/python3/bak/170.py.bak b/solutions/python3/bak/170.py.bak new file mode 100644 index 0000000..69ee959 --- /dev/null +++ b/solutions/python3/bak/170.py.bak @@ -0,0 +1,13 @@ +class TwoSum: + + def __init__(self): + self.nums = {} + + def add(self, number): + self.nums[number] = self.nums.get(number, 0) + 1 + + def find(self, value): + for num in self.nums: + if value - num in self.nums and (num != value - num or self.nums[num] > 1): + return True + return False \ No newline at end of file diff --git a/solutions/python3/bak/171.py.bak b/solutions/python3/bak/171.py.bak new file mode 100644 index 0000000..1162439 --- /dev/null +++ b/solutions/python3/bak/171.py.bak @@ -0,0 +1,7 @@ +class Solution: + def titleToNumber(self, s): + """ + :type s: str + :rtype: int + """ + return sum([(ord(char)-64)*(26**i) for i,char in enumerate(s[::-1])]) \ No newline at end of file diff --git a/solutions/python3/bak/172.py.bak b/solutions/python3/bak/172.py.bak new file mode 100644 index 0000000..87cb177 --- /dev/null +++ b/solutions/python3/bak/172.py.bak @@ -0,0 +1,7 @@ +class Solution: + def trailingZeroes(self, n): + """ + :type n: int + :rtype: int + """ + return 0 if n == 0 else n // 5 + self.trailingZeroes(n // 5) \ No newline at end of file diff --git a/solutions/python3/bak/173.py.bak b/solutions/python3/bak/173.py.bak new file mode 100644 index 0000000..9ef7fa2 --- /dev/null +++ b/solutions/python3/bak/173.py.bak @@ -0,0 +1,17 @@ +class BSTIterator: + def __init__(self, root: TreeNode): + self.stack = [] + self.pushAll(root) + + def next(self) -> int: + cur = self.stack.pop() + self.pushAll(cur.right) + return cur.val + + def hasNext(self) -> bool: + return self.stack + + def pushAll(self, node): + while node != None: + self.stack += (node,) + node = node.left diff --git a/solutions/python3/bak/174.py.bak b/solutions/python3/bak/174.py.bak new file mode 100644 index 0000000..06686c3 --- /dev/null +++ b/solutions/python3/bak/174.py.bak @@ -0,0 +1,14 @@ +class Solution: + def calculateMinimumHP(self, dungeon): + m, n = len(dungeon), len(dungeon[0]) + for i in range(m - 1, -1, -1): + for j in range(n - 1, -1, -1): + if i == m - 1 and j == n - 1: + dungeon[i][j] = max(1, 1 - dungeon[i][j]) + elif j == n - 1: + dungeon[i][j] = max(1, dungeon[i + 1][j] - dungeon[i][j]) + elif i == m - 1: + dungeon[i][j] = max(1, dungeon[i][j + 1] - dungeon[i][j]) + else: + dungeon[i][j] = max(1, min(dungeon[i + 1][j], dungeon[i][j + 1]) - dungeon[i][j]) + return dungeon[0][0] \ No newline at end of file diff --git a/solutions/python3/bak/179.py.bak b/solutions/python3/bak/179.py.bak new file mode 100644 index 0000000..fbbbb8e --- /dev/null +++ b/solutions/python3/bak/179.py.bak @@ -0,0 +1,18 @@ +class Solution: + def largestNumber(self, nums): + def partition(l, r): + j = l + for i in range(l + 1, r + 1): + if nums[i] + nums[l] >= nums[l] + nums[i]: + j += 1 + nums[j], nums[i] = nums[i], nums[j] + nums[l], nums[j] = nums[j], nums[l] + return j + def quickSort(l, r): + if l < r: + m = partition(l, r) + quickSort(l, m - 1) + quickSort(m + 1, r) + nums = [str(num) for num in nums] + quickSort(0, len(nums) - 1) + return str(int("".join(nums))) \ No newline at end of file diff --git a/solutions/python3/bak/18.py.bak b/solutions/python3/bak/18.py.bak new file mode 100644 index 0000000..7c634c1 --- /dev/null +++ b/solutions/python3/bak/18.py.bak @@ -0,0 +1,16 @@ +class Solution: + def fourSum(self, nums, target): + res, res_set = [], set() + nums.sort() + for i in range(len(nums) - 1): + if i > 0 and nums[i] == nums[i - 1]: continue + for j in range(i + 1, len(nums)): + l, r = j + 1, len(nums) - 1 + while l < r: + sm = nums[i] + nums[j] + nums[l] + nums[r] + if sm < target: l += 1 + elif sm > target: r -= 1 + elif (nums[i], nums[j], nums[l], nums[r]) not in res_set: + res.append([nums[i], nums[j], nums[l], nums[r]]); res_set.add((nums[i], nums[j], nums[l], nums[r])) + else: l, r = l + 1, r - 1 + return res \ No newline at end of file diff --git a/solutions/python3/bak/186.py.bak b/solutions/python3/bak/186.py.bak new file mode 100644 index 0000000..abb74fc --- /dev/null +++ b/solutions/python3/bak/186.py.bak @@ -0,0 +1,17 @@ +class Solution: + def reverseWords(self, s): + l, r, n = 0, len(s) - 1, len(s) + while l <= r: + s[l], s[r] = s[r], s[l] + l += 1 + r -= 1 + l = r = 0 + while r < n: + while r + 1 < n and s[r + 1] != " ": + r += 1 + i = r + 2 + while l <= r: + s[l], s[r] = s[r], s[l] + l += 1 + r -= 1 + l = r = i \ No newline at end of file diff --git a/solutions/python3/bak/187.py.bak b/solutions/python3/bak/187.py.bak new file mode 100644 index 0000000..e6e1adb --- /dev/null +++ b/solutions/python3/bak/187.py.bak @@ -0,0 +1,11 @@ +class Solution: + def findRepeatedDnaSequences(self, s): + """ + :type s: str + :rtype: List[str] + """ + dic, str = {}, "x" + s[:9] + for i in range(9, len(s)): + str = str[1:] + s[i] + dic[str] = 1 if str not in dic else dic[str] + 1 + return [k for k, v in dic.items() if v > 1] \ No newline at end of file diff --git a/solutions/python3/bak/188.py.bak b/solutions/python3/bak/188.py.bak new file mode 100644 index 0000000..cd90de2 --- /dev/null +++ b/solutions/python3/bak/188.py.bak @@ -0,0 +1,9 @@ +class Solution: + def maxProfit(self, k, prices): + if k >= len(prices) // 2: return sum(sell - buy for sell, buy in zip(prices[1:], prices[:-1]) if sell - buy > 0) + dp = [[0, -float("inf")] for _ in range(k + 1)] + for p in prices: + for i in range(k + 1): + if i and dp[i - 1][1] + p > dp[i][0]: dp[i][0] = dp[i - 1][1] + p + if dp[i][0] - p > dp[i][1]: dp[i][1] = dp[i][0] - p + return dp[-1][0] \ No newline at end of file diff --git a/solutions/python3/bak/189.py.bak b/solutions/python3/bak/189.py.bak new file mode 100644 index 0000000..9ba9b5a --- /dev/null +++ b/solutions/python3/bak/189.py.bak @@ -0,0 +1,10 @@ +class Solution: + def rotate(self, nums, k): + """ + :type nums: List[int] + :type k: int + :rtype: void Do not return anything, modify nums in-place instead. + """ + n=k%len(nums) + nums[:] = nums[-n:] + nums[:-n] + \ No newline at end of file diff --git a/solutions/python3/bak/19.py.bak b/solutions/python3/bak/19.py.bak new file mode 100644 index 0000000..456e2ab --- /dev/null +++ b/solutions/python3/bak/19.py.bak @@ -0,0 +1,12 @@ +class Solution: + def removeNthFromEnd(self, head, n): + dummy = ListNode(0) + dummy.next = head + arr = [dummy] + while head: + arr.append(head) + head = head.next + for _ in range(n + 1): + pre = arr.pop() + pre.next = pre.next.next + return dummy.next \ No newline at end of file diff --git a/solutions/python3/bak/198.py.bak b/solutions/python3/bak/198.py.bak new file mode 100644 index 0000000..0939aeb --- /dev/null +++ b/solutions/python3/bak/198.py.bak @@ -0,0 +1,6 @@ +class Solution: + def rob(self, nums): + if len(nums) <= 2: return max(nums or [0]) + nums[2] += nums[0] + for i in range(3, len(nums)): nums[i] += max(nums[i - 2], nums[i - 3]) + return max(nums[-1], nums[-2]) \ No newline at end of file diff --git a/solutions/python3/bak/199.py.bak b/solutions/python3/bak/199.py.bak new file mode 100644 index 0000000..b16efcf --- /dev/null +++ b/solutions/python3/bak/199.py.bak @@ -0,0 +1,18 @@ +# Definition for a binary tree node. +# class TreeNode: +# def __init__(self, x): +# self.val = x +# self.left = None +# self.right = None + +class Solution: + def rightSideView(self, root): + """ + :type root: TreeNode + :rtype: List[int] + """ + q, res = [root], [] + while any(q): + res.append(q[-1].val) + q = [kid for node in q for kid in (node.left, node.right) if kid] + return res \ No newline at end of file diff --git a/solutions/python3/bak/2.py.bak b/solutions/python3/bak/2.py.bak new file mode 100644 index 0000000..7354952 --- /dev/null +++ b/solutions/python3/bak/2.py.bak @@ -0,0 +1,16 @@ +# Definition for singly-linked list. +# class ListNode: +# def __init__(self, x): +# self.val = x +# self.next = None + +class Solution: + def addTwoNumbers(self, l1: ListNode, l2: ListNode) -> ListNode: + left = 0 + dummy = cur = ListNode(-1) + while l1 or l2 or left: + left, sm = divmod(sum(l and l.val or 0 for l in (l1, l2)) + left, 10) + cur.next = cur = ListNode(sm) + l1 = l1 and l1.next + l2 = l2 and l2.next + return dummy.next \ No newline at end of file diff --git a/solutions/python3/bak/20.py.bak b/solutions/python3/bak/20.py.bak new file mode 100644 index 0000000..2058a93 --- /dev/null +++ b/solutions/python3/bak/20.py.bak @@ -0,0 +1,9 @@ +class Solution: + def isValid(self, s): + brackets_stack, lefts, rights = [], ("(", "[", "{"), (")", "]", "}") + for char in s: + if char in lefts: + brackets_stack.append(char) + elif not brackets_stack or lefts.index(brackets_stack.pop()) != rights.index(char): + return False + return not brackets_stack \ No newline at end of file diff --git a/solutions/python3/bak/200.py.bak b/solutions/python3/bak/200.py.bak new file mode 100644 index 0000000..a2e5abc --- /dev/null +++ b/solutions/python3/bak/200.py.bak @@ -0,0 +1,13 @@ +class Solution: + def numIslands(self, grid): + res, n, m = 0, len(grid), len(grid[0]) if grid else 0 + def explore(i, j): + grid[i][j] = "-1" + if i > 0 and grid[i - 1][j] == "1": explore(i - 1, j) + if j > 0 and grid[i][j - 1] == "1": explore(i, j - 1) + if i + 1 < n and grid[i + 1][j] == "1": explore(i + 1, j) + if j + 1 < m and grid[i][j + 1] == "1": explore(i, j + 1) + for i in range(n): + for j in range(m): + if grid[i][j] == "1": explore(i, j); res += 1 + return res \ No newline at end of file diff --git a/solutions/python3/bak/201.py.bak b/solutions/python3/bak/201.py.bak new file mode 100644 index 0000000..f5d7a61 --- /dev/null +++ b/solutions/python3/bak/201.py.bak @@ -0,0 +1,8 @@ +class Solution: + def rangeBitwiseAnd(self, m, n): + i = 0 + while m != n: + m >>= 1 + n >>= 1 + i += 1 + return m << i \ No newline at end of file diff --git a/solutions/python3/bak/202.py.bak b/solutions/python3/bak/202.py.bak new file mode 100644 index 0000000..0db27d6 --- /dev/null +++ b/solutions/python3/bak/202.py.bak @@ -0,0 +1,12 @@ +class Solution: + def isHappy(self, n): + """ + :type n: int + :rtype: bool + """ + mem = set() + while n != 1: + n = sum([int(i) ** 2 for i in str(n)]) + if n in mem: return False + else: mem.add(n) + else: return True \ No newline at end of file diff --git a/solutions/python3/bak/203.py.bak b/solutions/python3/bak/203.py.bak new file mode 100644 index 0000000..e9d0527 --- /dev/null +++ b/solutions/python3/bak/203.py.bak @@ -0,0 +1,21 @@ +# Definition for singly-linked list. +# class ListNode: +# def __init__(self, x): +# self.val = x +# self.next = None + +class Solution: + def removeElements(self, head, val): + """ + :type head: ListNode + :type val: int + :rtype: ListNode + """ + prev, curr = ListNode(None), head + while curr: + if curr.val==val: + if curr==head: head=head.next + prev.next=curr.next + if curr.val!=val: prev=curr + curr=curr.next + return head \ No newline at end of file diff --git a/solutions/python3/bak/204.py.bak b/solutions/python3/bak/204.py.bak new file mode 100644 index 0000000..203aad4 --- /dev/null +++ b/solutions/python3/bak/204.py.bak @@ -0,0 +1,8 @@ +class Solution: + def countPrimes(self, n): + primes = [i for i in range(2, n)] + for i in range(2, n): + for prime in primes: + if i ** (prime - 1) % prime != 1 and prime > i: + primes.remove(prime) + return len(primes) diff --git a/solutions/python3/bak/205.py.bak b/solutions/python3/bak/205.py.bak new file mode 100644 index 0000000..5823318 --- /dev/null +++ b/solutions/python3/bak/205.py.bak @@ -0,0 +1,13 @@ +class Solution: + def isIsomorphic(self, s, t): + """ + :type s: str + :type t: str + :rtype: bool + """ + if len(s) != len(t): return False + dic={} + for i in range(len(s)): + if not t[i] in dic.values() and not s[i] in dic: dic[s[i]] = t[i] + elif not s[i] in dic or dic[s[i]] != t[i]: return False + return True \ No newline at end of file diff --git a/solutions/python3/bak/206.py.bak b/solutions/python3/bak/206.py.bak new file mode 100644 index 0000000..d41c812 --- /dev/null +++ b/solutions/python3/bak/206.py.bak @@ -0,0 +1,12 @@ +# Definition for singly-linked list. +# class ListNode: +# def __init__(self, x): +# self.val = x +# self.next = None + +class Solution: + def reverseList(self, head: ListNode, pre = None) -> ListNode: + if head: + nex = head.next + head.next = pre + return self.reverseList(nex, head) if nex else head \ No newline at end of file diff --git a/solutions/python3/bak/207.py.bak b/solutions/python3/bak/207.py.bak new file mode 100644 index 0000000..a225646 --- /dev/null +++ b/solutions/python3/bak/207.py.bak @@ -0,0 +1,13 @@ +class Solution: + def canFinish(self, numCourses, prerequisites): + def cycle(course): + visited[course] = 0 + for Next in route[course]: + if visited[Next] == 0 or (visited[Next] == -1 and cycle(Next)): return True + visited[course] = 1 + return False + route, visited = {i: [] for i in range(numCourses)}, [-1] * numCourses + for req in prerequisites: route[req[1]].append(req[0]) + for course in range(numCourses): + if visited[course] == -1 and cycle(course): return False + return True \ No newline at end of file diff --git a/solutions/python3/bak/208.py.bak b/solutions/python3/bak/208.py.bak new file mode 100644 index 0000000..545e1bc --- /dev/null +++ b/solutions/python3/bak/208.py.bak @@ -0,0 +1,45 @@ +class Trie: + + def __init__(self): + """ + Initialize your data structure here. + """ + self.root = {} + + def move(self, word, mod): + cur = self.root + for c in word: + if c not in cur: + if mod != 1: + return False + cur[c] = {} + cur = cur[c] + if mod == 1: + cur['#'] = None + else: + return mod == 3 or '#' in cur + + def insert(self, word: str) -> None: + """ + Inserts a word into the trie. + """ + return self.move(word, 1) + + def search(self, word: str) -> bool: + """ + Returns if the word is in the trie. + """ + return self.move(word, 2) + + def startsWith(self, prefix: str) -> bool: + """ + Returns if there is any word in the trie that starts with the given prefix. + """ + return self.move(prefix, 3) + + +# 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) \ No newline at end of file diff --git a/solutions/python3/bak/209.py.bak b/solutions/python3/bak/209.py.bak new file mode 100644 index 0000000..a66c116 --- /dev/null +++ b/solutions/python3/bak/209.py.bak @@ -0,0 +1,7 @@ +class Solution: + def minSubArrayLen(self, s, nums): + l, res, curr = 0, len(nums) + 1, 0 + for r, num in enumerate(nums): + curr += num + while curr >= s: res, l, curr = min(res, r - l + 1), l + 1, curr - nums[l] + return res < len(nums) + 1 and res or 0 \ No newline at end of file diff --git a/solutions/python3/bak/21.py.bak b/solutions/python3/bak/21.py.bak new file mode 100644 index 0000000..1fcd1d5 --- /dev/null +++ b/solutions/python3/bak/21.py.bak @@ -0,0 +1,16 @@ +# Definition for singly-linked list. +# class ListNode: +# def __init__(self, x): +# self.val = x +# self.next = None + +class Solution: + def mergeTwoLists(self, l1: ListNode, l2: ListNode) -> ListNode: + if not l1: return l2 + elif not l2: return l1 + if l1.val < l2.val: + l1.next = self.mergeTwoLists(l1.next, l2) + return l1 + else: + l2.next = self.mergeTwoLists(l1, l2.next) + return l2 \ No newline at end of file diff --git a/solutions/python3/bak/210.py.bak b/solutions/python3/bak/210.py.bak new file mode 100644 index 0000000..b21afa4 --- /dev/null +++ b/solutions/python3/bak/210.py.bak @@ -0,0 +1,10 @@ +class Solution: + def findOrder(self, numCourses, prerequisites): + children, parent = collections.defaultdict(set), collections.defaultdict(set) + for i, j in prerequisites: children[i].add(j); parent[j].add(i) + stack = [i for i in range(numCourses) if not children[i]] + for i in stack: + for j in parent[i]: + children[j].remove(i) + if not children[j]: stack += j, + return stack if len(stack) == numCourses else [] \ No newline at end of file diff --git a/solutions/python3/bak/211.py.bak b/solutions/python3/bak/211.py.bak new file mode 100644 index 0000000..dc7e720 --- /dev/null +++ b/solutions/python3/bak/211.py.bak @@ -0,0 +1,41 @@ +class TrieNode: + def __init__(self): + self.children = [None] * 26 + self.last = False +class WordDictionary: + + def __init__(self): + """ + Initialize your data structure here. + """ + self.root = TrieNode() + + def addWord(self, word): + """ + Adds a word into the data structure. + :type word: str + :rtype: void + """ + curr = self.root + for char in word: + if not curr.children[ord(char) - ord("a")]: curr.children[ord(char) - ord("a")] = TrieNode() + curr = curr.children[ord(char) - ord("a")] + curr.last = True + def search(self, word): + """ + Returns if the word is in the data structure. A word could contain the dot character '.' to represent any one letter. + :type word: str + :rtype: bool + """ + words = [self.root] + for char in word: + if char == ".": words = [child for node in words for child in node.children if node and child] + else: words = [node.children[ord(char) - ord("a")] for node in words if node and node.children[ord(char) - ord("a")]] + if words and words[-1] == ".": return True + else: return any([node.last for node in words if node.last]) + + +# Your WordDictionary object will be instantiated and called as such: +# obj = WordDictionary() +# obj.addWord(word) +# param_2 = obj.search(word) \ No newline at end of file diff --git a/solutions/python3/bak/212.py.bak b/solutions/python3/bak/212.py.bak new file mode 100644 index 0000000..b7d3d1e --- /dev/null +++ b/solutions/python3/bak/212.py.bak @@ -0,0 +1,20 @@ +class Solution: + def findWords(self, board, words): + def explore(i, j, cur): + visited[i][j] = 0 + if "#" in cur and cur["#"] not in res_set: res.append(cur["#"]); res_set.add(cur["#"]) + for x, y in ((i - 1, j), (i + 1, j), (i, j - 1), (i, j + 1)): + if 0 <= x < m and 0 <= y < n and board[x][y] in cur and visited[x][y] == -1: explore(x, y, trie[cur[board[x][y]]]) + visited[i][j] = -1 + trie, cnt, m, n, res, res_set = {}, 1, len(board), len(board and board[0]), [], set() + visited, trie[0] = [[-1] * n for _ in range(m)], {} + for w in words: + cur = trie[0] + for c in w: + if c not in cur: trie[cnt], cur[c], cnt = {}, cnt, cnt + 1 + cur = trie[cur[c]] + cur["#"] = w + for i in range(m): + for j in range(n): + if board[i][j] in trie[0]: explore(i, j, trie[trie[0][board[i][j]]]) + return res \ No newline at end of file diff --git a/solutions/python3/bak/213.py.bak b/solutions/python3/bak/213.py.bak new file mode 100644 index 0000000..f0cab7f --- /dev/null +++ b/solutions/python3/bak/213.py.bak @@ -0,0 +1,10 @@ +class Solution: + + def dp(self, nums): + if len(nums) <= 2: return max(nums or [0]) + nums[2] += nums[0] + for i in range(3, len(nums)): nums[i] += max(nums[i - 2], nums[i - 3]) + return max(nums[-1], nums[-2]) + + def rob(self, nums): + return max(self.dp(nums[:-1]), self.dp(nums[1:])) if len(nums) != 1 else nums[0] \ No newline at end of file diff --git a/solutions/python3/bak/214.py.bak b/solutions/python3/bak/214.py.bak new file mode 100644 index 0000000..c22de06 --- /dev/null +++ b/solutions/python3/bak/214.py.bak @@ -0,0 +1,6 @@ +class Solution: + def shortestPalindrome(self, s, pre = ""): + for i in range(1, len(s) // 2 + 2): + if s[i - 1:].startswith(s[:i][::-1]): pre = s[2* i - 1:][::-1] + if s[i:].startswith(s[:i][::-1]): pre = s[2* i:][::-1] + return pre + s \ No newline at end of file diff --git a/solutions/python3/bak/215.py.bak b/solutions/python3/bak/215.py.bak new file mode 100644 index 0000000..7018efc --- /dev/null +++ b/solutions/python3/bak/215.py.bak @@ -0,0 +1,3 @@ +class Solution: + def findKthLargest(self, nums, k): + return heapq.nlargest(k, nums)[-1] \ No newline at end of file diff --git a/solutions/python3/bak/216.py.bak b/solutions/python3/bak/216.py.bak new file mode 100644 index 0000000..add30bb --- /dev/null +++ b/solutions/python3/bak/216.py.bak @@ -0,0 +1,14 @@ +class Solution: + def combinationSum3(self, k, n): + """ + :type k: int + :type n: int + :rtype: List[List[int]] + """ + stack, nums, res = [(0, [], 0, k)], range(1, 10), [] + while stack: + sm, tmp, index, k_val = stack.pop(0) + for i in range(index, len(nums)): + if sm + nums[i] < n and k_val > 0: stack.append((sm + nums[i], tmp + [nums[i]], i + 1, k_val - 1)) + elif sm + nums[i] == n and k_val == 1: res.append(tmp + [nums[i]]) + return res \ No newline at end of file diff --git a/solutions/python3/bak/217.py.bak b/solutions/python3/bak/217.py.bak new file mode 100644 index 0000000..f594ddb --- /dev/null +++ b/solutions/python3/bak/217.py.bak @@ -0,0 +1,13 @@ +class Solution: + def containsDuplicate(self, nums): + """ + :type nums: List[int] + :rtype: bool + """ + dic=dict() + for num in nums: + if not num in dic: + dic[num]=1 + else: + return True + return False \ No newline at end of file diff --git a/solutions/python3/bak/218.py.bak b/solutions/python3/bak/218.py.bak new file mode 100644 index 0000000..4922a79 --- /dev/null +++ b/solutions/python3/bak/218.py.bak @@ -0,0 +1,12 @@ +class Solution: + def getSkyline(self, buildings): + events = sorted([(L, -H, R) for L, R, H in buildings] + list({(R, 0, None) for _, R, _ in buildings})) + res, hp = [[0, 0]], [(0, float("inf"))] + for x, negH, R in events: + while x >= hp[0][1]: + heapq.heappop(hp) + if negH: + heapq.heappush(hp, (negH, R)) + if res[-1][1] + hp[0][0]: + res += [x, -hp[0][0]], + return res[1:] \ No newline at end of file diff --git a/solutions/python3/bak/219.py.bak b/solutions/python3/bak/219.py.bak new file mode 100644 index 0000000..d76b1a3 --- /dev/null +++ b/solutions/python3/bak/219.py.bak @@ -0,0 +1,13 @@ +class Solution: + def containsNearbyDuplicate(self, nums, k): + """ + :type nums: List[int] + :type k: int + :rtype: bool + """ + dic={} + for i,num in enumerate(nums): + if num in dic and i-dic[num]<=k: + return True + dic[num]=i + return False \ No newline at end of file diff --git a/solutions/python3/bak/22.py.bak b/solutions/python3/bak/22.py.bak new file mode 100644 index 0000000..b68635b --- /dev/null +++ b/solutions/python3/bak/22.py.bak @@ -0,0 +1,6 @@ +class Solution: + def generateParenthesis(self, n: int) -> List[str]: + bfs = [(0, 0, '')] + for c in range(n * 2): + bfs = [(l + 1, r, s + '(') for l, r, s in bfs if l + 1 <= n] + [(l, r + 1, s + ')') for l, r, s in bfs if l - r] + return [s for l, r, s in bfs] \ No newline at end of file diff --git a/solutions/python3/bak/220.py.bak b/solutions/python3/bak/220.py.bak new file mode 100644 index 0000000..aa0af20 --- /dev/null +++ b/solutions/python3/bak/220.py.bak @@ -0,0 +1,11 @@ +class Solution: + def containsNearbyAlmostDuplicate(self, nums, k, t): + if t < 0: return False + d = {} + for i in range(len(nums)): + m = nums[i] // (t + 1) + if m in d or (m - 1 in d and nums[i] - d[m - 1] <= t) or (m + 1 in d and d[m + 1] - nums[i] <= t): + return True + d[m] = nums[i] + if i >= k: del d[nums[i - k] // (t + 1)] + return False \ No newline at end of file diff --git a/solutions/python3/bak/221.py.bak b/solutions/python3/bak/221.py.bak new file mode 100644 index 0000000..2c57b9c --- /dev/null +++ b/solutions/python3/bak/221.py.bak @@ -0,0 +1,23 @@ +class Solution: + def maximalSquare(self, matrix): + """ + :type matrix: List[List[str]] + :rtype: int + """ + res, count = 0, 0 + for i in range(len(matrix)): + for j in range(len(matrix[0])): + matrix[i][j] = int(matrix[i][j]) + if matrix[i][j] != 0: + count = 1 + if j>0 and int(matrix[i][j-1]) != 0: matrix[i][j] += int(matrix[i][j-1]) + if i-1>=0 and int(matrix[i-1][j]) != 0: + k, curr = i-1, [] + while k>=0 and k>=i-matrix[i][j]+1 and int(matrix[k][j]) != 0: + if matrix[k][j]>= count+1: + curr.append(matrix[k][j]) + if min(curr)>= count+1: count += 1 + else: break + k -= 1 + res = max(res, count**2) + return res \ No newline at end of file diff --git a/solutions/python3/bak/222.py.bak b/solutions/python3/bak/222.py.bak new file mode 100644 index 0000000..66f9879 --- /dev/null +++ b/solutions/python3/bak/222.py.bak @@ -0,0 +1,13 @@ +class Solution: + + def countNodes(self, root): + if not root: return 0 + l = self.getDepth(root.left) + r = self.getDepth(root.right) + if l == r: + return (1 << l) + self.countNodes(root.right) + return (1 << r) + self.countNodes(root.left) + + def getDepth(self, root): + if not root: return 0 + return 1 + self.getDepth(root.left) \ No newline at end of file diff --git a/solutions/python3/bak/223.py.bak b/solutions/python3/bak/223.py.bak new file mode 100644 index 0000000..c64521c --- /dev/null +++ b/solutions/python3/bak/223.py.bak @@ -0,0 +1,7 @@ +class Solution: + def computeArea(self, a, b, c, d, e, f, g, h): + x1, x2, x3 = abs(a - c), abs(e - g), max(a, c, e, g) - min(a, c, e, g) + y1, y2, y3 = abs(b - d), abs(f - h), max(b, d, f, h) - min(b, d, f, h) + if x3 < x1 + x2 and y3 < y1 + y2: intrs = (x1 + x2 - x3) * (y1 + y2 - y3) + else: intrs = 0 + return x1 * y1 + x2 * y2 - intrs \ No newline at end of file diff --git a/solutions/python3/bak/224.py.bak b/solutions/python3/bak/224.py.bak new file mode 100644 index 0000000..080eb7d --- /dev/null +++ b/solutions/python3/bak/224.py.bak @@ -0,0 +1,18 @@ +class Solution: + def calculate(self, s): + def calc(n2, op, n1): + return n1 + n2 if op == "+" else n1 - n2 + stack, i, num = [], 0, 0 + while i < len(s): + j = i + while j < len(s) and s[j].isdigit(): + num, j = num * 10 + int(s[j]), j + 1 + if i != j: + stack.append(calc(num, stack.pop(), stack.pop()) if stack and s[i - 1] != "(" else num) + num, j = 0, j - 1 + elif s[i] in "+-": + stack.append(s[i]) + elif s[i] == ")" and len(stack) > 1: + stack.append(calc(stack.pop(), stack.pop(), stack.pop())) + i = j + 1 + return stack.pop() \ No newline at end of file diff --git a/solutions/python3/bak/225.py.bak b/solutions/python3/bak/225.py.bak new file mode 100644 index 0000000..548067f --- /dev/null +++ b/solutions/python3/bak/225.py.bak @@ -0,0 +1,44 @@ +class MyStack: + + def __init__(self): + """ + Initialize your data structure here. + """ + self.data = [] + + def push(self, x): + """ + Push element x onto stack. + :type x: int + :rtype: void + """ + self.data.append(x) + + def pop(self): + """ + Removes the element on top of the stack and returns that element. + :rtype: int + """ + return self.data.pop() + + def top(self): + """ + Get the top element. + :rtype: int + """ + return self.data[-1] + + def empty(self): + """ + Returns whether the stack is empty. + :rtype: bool + """ + return not bool(self.data) + + +# 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() \ No newline at end of file diff --git a/solutions/python3/bak/226.py.bak b/solutions/python3/bak/226.py.bak new file mode 100644 index 0000000..a529fd7 --- /dev/null +++ b/solutions/python3/bak/226.py.bak @@ -0,0 +1,18 @@ +# Definition for a binary tree node. +# class TreeNode: +# def __init__(self, x): +# self.val = x +# self.left = None +# self.right = None + +class Solution: + def invertTree(self, root): + """ + :type root: TreeNode + :rtype: TreeNode + """ + if not root: return + root.left, root.right= root.right, root.left + self.invertTree(root.left) + self.invertTree(root.right) + return root \ No newline at end of file diff --git a/solutions/python3/bak/227.py.bak b/solutions/python3/bak/227.py.bak new file mode 100644 index 0000000..0af2411 --- /dev/null +++ b/solutions/python3/bak/227.py.bak @@ -0,0 +1,34 @@ +class Solution: + def calculate(self, s): + mod = 0 + while mod < 2: + stack, i, n, num = [], 0, len(s), "" + while i < n: + if s[i] == " ": + i += 1 + continue + while mod == 0 and i < n and s[i].isnumeric(): + num += s[i] + i += 1 + if stack and stack[-1] in [("*", "/"), ("+", "-")][mod]: + op, num1 = stack.pop(), stack.pop() + if op == "*": + stack.append(num1 * int(num)) + elif op == "/": + stack.append(num1 // int(num)) + elif op == "+": + stack.append(num1 + s[i]) + i += 1 + else: + stack.append(num1 - s[i]) + i += 1 + num = "" + elif num: + stack.append(int(num)) + num = "" + else: + stack.append(s[i]) + i += 1 + mod += 1 + s = stack + return stack.pop() \ No newline at end of file diff --git a/solutions/python3/bak/228.py.bak b/solutions/python3/bak/228.py.bak new file mode 100644 index 0000000..53f1ab7 --- /dev/null +++ b/solutions/python3/bak/228.py.bak @@ -0,0 +1,12 @@ +class Solution: + def summaryRanges(self, nums): + """ + :type nums: List[int] + :rtype: List[str] + """ + res, stack = [], [nums[0] if nums else None, None] + for i, num in enumerate(nums): + if i > 0 and nums[i - 1] == num - 1: stack[1] = num + if i > 0 and nums[i-1] != num - 1: res, stack[0], stack[1] = res + ["->".join(str(q) for q in stack if q != None)], num, None + if i == len(nums) - 1: res.append("->".join(str(q) for q in stack if q != None)) + return res \ No newline at end of file diff --git a/solutions/python3/bak/229.py.bak b/solutions/python3/bak/229.py.bak new file mode 100644 index 0000000..06e55b0 --- /dev/null +++ b/solutions/python3/bak/229.py.bak @@ -0,0 +1,16 @@ +class Solution: + def majorityElement(self, nums): + c1, c2, cnt1, cnt2 = 0, 1, 0, 0 + for num in nums: + if num == c1: + cnt1 += 1 + elif num == c2: + cnt2 += 1 + elif not cnt1: + c1, cnt1 = num, 1 + elif not cnt2: + c2, cnt2 = num, 1 + else: + cnt1 -= 1 + cnt2 -= 1 + return [c for c in (c1, c2) if nums.count(c) > len(nums) // 3] \ No newline at end of file diff --git a/solutions/python3/bak/23.py.bak b/solutions/python3/bak/23.py.bak new file mode 100644 index 0000000..2f70365 --- /dev/null +++ b/solutions/python3/bak/23.py.bak @@ -0,0 +1,17 @@ +# Definition for singly-linked list. +# class ListNode: +# def __init__(self, x): +# self.val = x +# self.next = None + +class Solution: + def mergeKLists(self, lists): + q = [] + for i in range(len(lists)): + while lists[i]: + q += lists[i], + lists[i] = lists[i].next + root = cur = ListNode(0) + for h in sorted(q, key = lambda x: x.val): + cur.next = cur = h + return root.next \ No newline at end of file diff --git a/solutions/python3/bak/230.py.bak b/solutions/python3/bak/230.py.bak new file mode 100644 index 0000000..90bf49a --- /dev/null +++ b/solutions/python3/bak/230.py.bak @@ -0,0 +1,16 @@ +# Definition for a binary tree node. +# class TreeNode: +# def __init__(self, x): +# self.val = x +# self.left = None +# self.right = None + +class Solution: + def __init__(self): + self.k, self.res = 0, None + def kthSmallest(self, root, k): + if self.k < k and root.left: self.kthSmallest(root.left, k) + self.k += 1 + if self.k == k: self.res = root.val + if self.k < k and root.right: self.kthSmallest(root.right, k) + return self.res \ No newline at end of file diff --git a/solutions/python3/bak/231.py.bak b/solutions/python3/bak/231.py.bak new file mode 100644 index 0000000..4ce135d --- /dev/null +++ b/solutions/python3/bak/231.py.bak @@ -0,0 +1,11 @@ +class Solution: + def isPowerOfTwo(self, n): + """ + :type n: int + :rtype: bool + """ + i=0 + while 2**i<=n: + if 2**i==n: return True + i+=1 + return False \ No newline at end of file diff --git a/solutions/python3/bak/232.py.bak b/solutions/python3/bak/232.py.bak new file mode 100644 index 0000000..0700c01 --- /dev/null +++ b/solutions/python3/bak/232.py.bak @@ -0,0 +1,46 @@ +class MyQueue: + + def __init__(self): + """ + Initialize your data structure here. + """ + self.data = [] + + def push(self, x): + """ + Push element x to the back of queue. + :type x: int + :rtype: void + """ + self.data.append(x) + + def pop(self): + """ + Removes the element from in front of queue and returns that element. + :rtype: int + """ + front = self.data[0] + self.data = self.data[1:] + return front + + def peek(self): + """ + Get the front element. + :rtype: int + """ + return self.data[0] + + def empty(self): + """ + Returns whether the queue is empty. + :rtype: bool + """ + return not bool(self.data) + + +# 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() \ No newline at end of file diff --git a/solutions/python3/bak/233.py.bak b/solutions/python3/bak/233.py.bak new file mode 100644 index 0000000..0629967 --- /dev/null +++ b/solutions/python3/bak/233.py.bak @@ -0,0 +1,15 @@ +class Solution: + def countDigitOne(self, n): + if n <= 0: + return 0 + q, x, ans = n, 1, 0 + while q > 0: + digit = q % 10 + q //= 10 + ans += q * x + if digit == 1: + ans += n % x + 1 + elif digit > 1: + ans += x + x *= 10 + return ans \ No newline at end of file diff --git a/solutions/python3/bak/234.py.bak b/solutions/python3/bak/234.py.bak new file mode 100644 index 0000000..5fd3bd7 --- /dev/null +++ b/solutions/python3/bak/234.py.bak @@ -0,0 +1,11 @@ +class Solution: + def isPalindrome(self, head): + r = fast = head + l = None + while fast and fast.next: + fast = fast.next.next + r.next, l, r = l, r, r.next + if fast: r = r.next + while l and r and l.val == r.val: + l, r = l.next, r.next + return not l \ No newline at end of file diff --git a/solutions/python3/bak/235.py.bak b/solutions/python3/bak/235.py.bak new file mode 100644 index 0000000..f328f2c --- /dev/null +++ b/solutions/python3/bak/235.py.bak @@ -0,0 +1,10 @@ +class Solution: + def lowestCommonAncestor( + self, root: "TreeNode", p: "TreeNode", q: "TreeNode" + ) -> "TreeNode": + if p.val < root.val > q.val: + return self.lowestCommonAncestor(root.left, p, q) + if p.val > root.val < q.val: + return self.lowestCommonAncestor(root.right, p, q) + return root + diff --git a/solutions/python3/bak/236.py.bak b/solutions/python3/bak/236.py.bak new file mode 100644 index 0000000..c187792 --- /dev/null +++ b/solutions/python3/bak/236.py.bak @@ -0,0 +1,20 @@ +class Solution: + def lowestCommonAncestor( + self, root: "TreeNode", p: "TreeNode", q: "TreeNode" + ) -> "TreeNode": + parent, stack = {root: None}, [root] + while p not in parent or q not in parent: + node = stack.pop() + if node.left: + parent[node.left] = node + stack.append(node.left) + if node.right: + parent[node.right] = node + stack.append(node.right) + ancestors = set() + while p: + ancestors.add(p) + p = parent[p] + while q not in ancestors: + q = parent[q] + return q diff --git a/solutions/python3/bak/237.py.bak b/solutions/python3/bak/237.py.bak new file mode 100644 index 0000000..bd59e3f --- /dev/null +++ b/solutions/python3/bak/237.py.bak @@ -0,0 +1,5 @@ +class Solution: + def deleteNode(self, node): + node.val = node.next.val + node.next = node.next.next + diff --git a/solutions/python3/bak/238.py.bak b/solutions/python3/bak/238.py.bak new file mode 100644 index 0000000..e01ae92 --- /dev/null +++ b/solutions/python3/bak/238.py.bak @@ -0,0 +1,15 @@ +class Solution: + def productExceptSelf(self, nums): + """ + :type nums: List[int] + :rtype: List[int] + """ + m, res = 1, [] + for i in range(len(nums)): + res.append(m) + m *= nums[i] + m = 1 + for i in range(len(nums)-1,-1,-1): + res[i] *= m + m *= nums[i] + return res \ No newline at end of file diff --git a/solutions/python3/bak/239.py.bak b/solutions/python3/bak/239.py.bak new file mode 100644 index 0000000..486117b --- /dev/null +++ b/solutions/python3/bak/239.py.bak @@ -0,0 +1,12 @@ +class Solution: + def maxSlidingWindow(self, nums, k): + cnt, heap, res = collections.Counter(), [], [] + for i, num in enumerate(nums): + heapq.heappush(heap, -num) + cnt[num] += 1 + while not cnt[-heap[0]]: + heapq.heappop(heap) + if i >= k - 1: + res.append(-heap[0]) + cnt[nums[i - k + 1]] -= 1 + return res \ No newline at end of file diff --git a/solutions/python3/bak/24.py.bak b/solutions/python3/bak/24.py.bak new file mode 100644 index 0000000..421fe33 --- /dev/null +++ b/solutions/python3/bak/24.py.bak @@ -0,0 +1,14 @@ +# Definition for singly-linked list. +# class ListNode: +# def __init__(self, x): +# self.val = x +# self.next = None + +class Solution: + def swapPairs(self, head: ListNode) -> ListNode: + if not head or not head.next: return head + first = head.next + second = head + second.next = self.swapPairs(first.next) + first.next = second + return first \ No newline at end of file diff --git a/solutions/python3/bak/240.py.bak b/solutions/python3/bak/240.py.bak new file mode 100644 index 0000000..bb723ab --- /dev/null +++ b/solutions/python3/bak/240.py.bak @@ -0,0 +1,3 @@ +class Solution: + def searchMatrix(self, matrix, target): + return any(target in row for row in matrix) \ No newline at end of file diff --git a/solutions/python3/bak/241.py.bak b/solutions/python3/bak/241.py.bak new file mode 100644 index 0000000..653d266 --- /dev/null +++ b/solutions/python3/bak/241.py.bak @@ -0,0 +1,15 @@ +class Solution: + def diffWaysToCompute(self, input): + if input.isdigit(): + return [int(input)] + res = [] + for i in range(len(input)): + if input[i] in "-+*": + l = self.diffWaysToCompute(input[:i]) + r = self.diffWaysToCompute(input[i + 1:]) + for j in l: + for k in r: + res.append(self.calc(j, input[i], k)) + return res + def calc(self, l, op, r): + return l + r if op == "+" else l - r if op == "-" else l * r \ No newline at end of file diff --git a/solutions/python3/bak/242.py.bak b/solutions/python3/bak/242.py.bak new file mode 100644 index 0000000..485e58d --- /dev/null +++ b/solutions/python3/bak/242.py.bak @@ -0,0 +1,9 @@ +class Solution: + def isAnagram(self, s, t): + """ + :type s: str + :type t: str + :rtype: bool + """ + #return sum([ord(i) for i in s])==sum([ord(j) for j in t]) and set(s)==set(t) + return sorted(s)==sorted(t) \ No newline at end of file diff --git a/solutions/python3/bak/243.py.bak b/solutions/python3/bak/243.py.bak new file mode 100644 index 0000000..802a41b --- /dev/null +++ b/solutions/python3/bak/243.py.bak @@ -0,0 +1,13 @@ +class Solution: + def shortestDistance(self, words, word1, word2): + i1, i2, mn = -1, -1, float("inf") + for i, w in enumerate(words): + if w == word1: + i1 = i + if i2 >= 0: + mn = min(mn, i - i2) + elif w == word2: + i2 = i + if i1 >= 0: + mn = min(mn, i - i1) + return mn \ No newline at end of file diff --git a/solutions/python3/bak/244.py.bak b/solutions/python3/bak/244.py.bak new file mode 100644 index 0000000..a180403 --- /dev/null +++ b/solutions/python3/bak/244.py.bak @@ -0,0 +1,12 @@ +class WordDistance: + + def __init__(self, words): + self.d = {} + self.ind = collections.defaultdict(set) + for i, w in enumerate(words): + self.ind[w].add(i) + + def shortest(self, word1, word2): + if (word1, word2) not in self.d: + self.d[(word1, word2)] = self.d[(word2, word1)] = min(abs(j - i) for i in self.ind[word1] for j in self.ind[word2]) + return self.d[(word1, word2)] \ No newline at end of file diff --git a/solutions/python3/bak/245.py.bak b/solutions/python3/bak/245.py.bak new file mode 100644 index 0000000..2a1a862 --- /dev/null +++ b/solutions/python3/bak/245.py.bak @@ -0,0 +1,13 @@ +class Solution: + def shortestWordDistance(self, words, word1, word2): + i1 = i2 = -1 + res, same = float("inf"), word1 == word2 + for i, w in enumerate(words): + if w == word1: + if same: i2 = i1 + i1 = i + if i2 >= 0: res = min(res, i1 - i2) + elif w == word2: + i2 = i + if i1 >= 0: res = min(res, i2 - i1) + return res \ No newline at end of file diff --git a/solutions/python3/bak/246.py.bak b/solutions/python3/bak/246.py.bak new file mode 100644 index 0000000..d187d98 --- /dev/null +++ b/solutions/python3/bak/246.py.bak @@ -0,0 +1,3 @@ +class Solution: + def isStrobogrammatic(self, num): + return not any(num[i] + num[-1-i] not in ("88", "69", "96", "11", "00") for i in range((len(num) + 1) // 2)) \ No newline at end of file diff --git a/solutions/python3/bak/247.py.bak b/solutions/python3/bak/247.py.bak new file mode 100644 index 0000000..453c55f --- /dev/null +++ b/solutions/python3/bak/247.py.bak @@ -0,0 +1,6 @@ +class Solution: + def findStrobogrammatic(self, n, q = [""]): + for i in range(n // 2): q = [s + c for s in q for c in "01689" if i != 0 or c != "0"] + if n % 2: q = [s + c for s in q for c in "018"] + for i in range(n // 2 - 1, -1, -1): q = [s + "9" if s[i] == "6" else s + "6" if s[i] == "9" else s + s[i] for s in q] + return q \ No newline at end of file diff --git a/solutions/python3/bak/248.py.bak b/solutions/python3/bak/248.py.bak new file mode 100644 index 0000000..bdcb73f --- /dev/null +++ b/solutions/python3/bak/248.py.bak @@ -0,0 +1,8 @@ +class Solution: + def strobogrammaticInRange(self, low, high): + q, cnt, low, high, ln = ["", "0", "1", "8"], 0, int(low), int(high), len(high) + while q: + s = q.pop() + if s and s[0] != "0" and low <= int(s) <= high: cnt += 1 + q += [l + s + r for l, r in (("8", "8"), ("6", "9"), ("9", "6"), ("1", "1"), ("0", "0")) if len(s) <= ln - 2] + return cnt if low != 0 else cnt + 1 \ No newline at end of file diff --git a/solutions/python3/bak/249.py.bak b/solutions/python3/bak/249.py.bak new file mode 100644 index 0000000..93cafe5 --- /dev/null +++ b/solutions/python3/bak/249.py.bak @@ -0,0 +1,16 @@ +class Solution: + def groupStrings(self, strings): + """ + :type strings: List[str] + :rtype: List[List[str]] + """ + table = collections.defaultdict(list) + for w in strings: + pattern = "" + for i in range(1, len(w)): + if ord(w[i]) - ord(w[i - 1]) >= 0: + pattern += str(ord(w[i]) - ord(w[i - 1])) + else: + pattern += str(ord(w[i]) - ord(w[i - 1]) + 26) + table[pattern].append(w) + return [table[pattern] for pattern in table] \ No newline at end of file diff --git a/solutions/python3/bak/25.py.bak b/solutions/python3/bak/25.py.bak new file mode 100644 index 0000000..79c76c5 --- /dev/null +++ b/solutions/python3/bak/25.py.bak @@ -0,0 +1,21 @@ +# Definition for singly-linked list. +# class ListNode: +# def __init__(self, x): +# self.val = x +# self.next = None +class Solution: + def reverseKGroup(self, head, k): + dummy = last = ListNode(0) + cur = head + while cur: + first, cnt = cur, 1 + while cnt < k and cur: + cur, cnt = cur.next, cnt + 1 + if cnt == k and cur: + cur, prev = first, None + for _ in range(k): + prev, cur.next, cur = cur, prev, cur.next + last.next, last = prev, first + else: + last.next = first + return dummy.next \ No newline at end of file diff --git a/solutions/python3/bak/250.py.bak b/solutions/python3/bak/250.py.bak new file mode 100644 index 0000000..df96f20 --- /dev/null +++ b/solutions/python3/bak/250.py.bak @@ -0,0 +1,21 @@ +# Definition for a binary tree node. +# class TreeNode(object): +# def __init__(self, x): +# self.val = x +# self.left = None +# self.right = None + +class Solution(object): + def countUnivalSubtrees(self, root): + res = [0] + def dfs(node, value): + if not node: + return True, value + left, lVal = dfs(node.left, node.val) + right, rVal = dfs(node.right, node.val) + cnt = left and right and lVal == rVal == node.val + if cnt: + res[0] += 1 + return cnt, node.val + dfs(root, None) + return res[0] \ No newline at end of file diff --git a/solutions/python3/bak/251.py.bak b/solutions/python3/bak/251.py.bak new file mode 100644 index 0000000..41ec488 --- /dev/null +++ b/solutions/python3/bak/251.py.bak @@ -0,0 +1,18 @@ +class Vector2D: + def __init__(self, v: List[List[int]]): + self.arr = v + self.rows = len(v) + self.i = self.j = 0 + + def next(self) -> int: + if self.hasNext(): + self.j += 1 + return self.arr[self.i][self.j - 1] + + def hasNext(self) -> bool: + if self.arr and self.j == len(self.arr[self.i]): + self.i += 1 + self.j = 0 + while self.i + 1 < self.rows and not self.arr[self.i]: + self.i += 1 + return self.i < self.rows and self.arr[self.i] != [] diff --git a/solutions/python3/bak/252.py.bak b/solutions/python3/bak/252.py.bak new file mode 100644 index 0000000..0128ccd --- /dev/null +++ b/solutions/python3/bak/252.py.bak @@ -0,0 +1,12 @@ +# Definition for an interval. +# class Interval: +# def __init__(self, s=0, e=0): +# self.start = s +# self.end = e + +class Solution: + def canAttendMeetings(self, intervals): + intervals.sort(key = lambda x: x.end) + for i in range(1, len(intervals)): + if intervals[i].start < intervals[i - 1].end: return False + return True \ No newline at end of file diff --git a/solutions/python3/bak/253.py.bak b/solutions/python3/bak/253.py.bak new file mode 100644 index 0000000..6c9b07b --- /dev/null +++ b/solutions/python3/bak/253.py.bak @@ -0,0 +1,17 @@ +# Definition for an interval. +# class Interval: +# def __init__(self, s=0, e=0): +# self.start = s +# self.end = e + +class Solution: + def minMeetingRooms(self, intervals): + intervals.sort(key = lambda x: x.start) + heap, time, rooms = [], 0, 0 + for intr in intervals: + while heap and heap[0] <= intr.start: + heapq.heappop(heap) + heapq.heappush(heap, intr.end) + if len(heap) > rooms: + rooms += 1 + return rooms \ No newline at end of file diff --git a/solutions/python3/bak/254.py.bak b/solutions/python3/bak/254.py.bak new file mode 100644 index 0000000..c504e9c --- /dev/null +++ b/solutions/python3/bak/254.py.bak @@ -0,0 +1,18 @@ +class Solution: + def getFactors(self, n): + factors = set() + for i in range(2, int(n ** 0.5) + 1): + if n % i == 0: + factors |= {i, n // i} + q, res = [[f, [f]] for f in factors], [] + while q: + new = [] + for sm, arr in q: + for f in factors: + if f >= arr[-1]: + if sm * f < n: + new.append([sm * f, arr + [f]]) + elif sm * f == n: + res.append(arr + [f]) + q = new + return res \ No newline at end of file diff --git a/solutions/python3/bak/255.py.bak b/solutions/python3/bak/255.py.bak new file mode 100644 index 0000000..bf02d1c --- /dev/null +++ b/solutions/python3/bak/255.py.bak @@ -0,0 +1,8 @@ +class Solution: + def verifyPreorder(self, preorder): + stack, lower = [], -float("inf") + for x in preorder: + if x < lower: return False + while stack and x > stack[-1]: lower = stack.pop() + stack.append(x) + return True \ No newline at end of file diff --git a/solutions/python3/bak/256.py.bak b/solutions/python3/bak/256.py.bak new file mode 100644 index 0000000..0bf8bce --- /dev/null +++ b/solutions/python3/bak/256.py.bak @@ -0,0 +1,9 @@ +class Solution: + def minCost(self, costs: List[List[int]]) -> int: + dp = [0] * 3 + for a, b, c in costs: + c1 = min(dp[1], dp[2]) + a + c2 = min(dp[0], dp[2]) + b + c3 = min(dp[0], dp[1]) + c + dp = [c1, c2, c3] + return min(dp) \ No newline at end of file diff --git a/solutions/python3/bak/257.py.bak b/solutions/python3/bak/257.py.bak new file mode 100644 index 0000000..de9a0c8 --- /dev/null +++ b/solutions/python3/bak/257.py.bak @@ -0,0 +1,21 @@ +# Definition for a binary tree node. +# class TreeNode: +# def __init__(self, x): +# self.val = x +# self.left = None +# self.right = None + +class Solution: + def binaryTreePaths(self, root: TreeNode) -> List[str]: + def dfs(node, arr): + if not node.right and not node.left: + #print(arr) + self.res += ['->'.join(str(num) for num in arr)] + if node.left: + dfs(node.left, arr + [node.left.val]) + if node.right: + dfs(node.right, arr + [node.right.val]) + self.res = [] + if not root: return [] + dfs(root, [root.val]) + return self.res \ No newline at end of file diff --git a/solutions/python3/bak/258.py.bak b/solutions/python3/bak/258.py.bak new file mode 100644 index 0000000..0a3e001 --- /dev/null +++ b/solutions/python3/bak/258.py.bak @@ -0,0 +1,10 @@ +class Solution: + def addDigits(self, num): + """ + :type num: int + :rtype: int + """ + num=str(num) + while len(num)>1: + num=str(sum([int(i) for i in num])) + return int(num) \ No newline at end of file diff --git a/solutions/python3/bak/259.py.bak b/solutions/python3/bak/259.py.bak new file mode 100644 index 0000000..6be568b --- /dev/null +++ b/solutions/python3/bak/259.py.bak @@ -0,0 +1,12 @@ +class Solution: + def threeSumSmaller(self, nums, target): + nums.sort() + res = 0 + for i in range(len(nums) - 2): + r = len(nums) - 1 + for j in range(i + 1, len(nums) - 1): + while r > j + 1 and nums[i] + nums[j] + nums[r] >= target: + r -= 1 + if nums[i] + nums[j] + nums[r] < target: + res += r - j + return res \ No newline at end of file diff --git a/solutions/python3/bak/26.py.bak b/solutions/python3/bak/26.py.bak new file mode 100644 index 0000000..f4b7dfc --- /dev/null +++ b/solutions/python3/bak/26.py.bak @@ -0,0 +1,4 @@ +class Solution: + def removeDuplicates(self, nums): + n = len(nums) + return n - len([nums.pop(i) for i in range(n -1, 0, -1) if nums[i] == nums[i - 1]]) \ No newline at end of file diff --git a/solutions/python3/bak/260.py.bak b/solutions/python3/bak/260.py.bak new file mode 100644 index 0000000..a4e2f13 --- /dev/null +++ b/solutions/python3/bak/260.py.bak @@ -0,0 +1,7 @@ +class Solution: + def singleNumber(self, nums): + """ + :type nums: List[int] + :rtype: List[int] + """ + return [n[0] for n in collections.Counter(nums).most_common()[-2:]] \ No newline at end of file diff --git a/solutions/python3/bak/261.py.bak b/solutions/python3/bak/261.py.bak new file mode 100644 index 0000000..af3e2bc --- /dev/null +++ b/solutions/python3/bak/261.py.bak @@ -0,0 +1,13 @@ +class Solution: + def validTree(self, n, edges): + visited, adj = [0] * n, collections.defaultdict(set) + for a, b in edges: + adj[a].add(b) + adj[b].add(a) + def dfs(i, pre): + visited[i] = 1 + for v in adj[i]: + if v != pre and (visited[v] or not dfs(v, i)): + return False + return True + return dfs(0, -1) and sum(visited) == n \ No newline at end of file diff --git a/solutions/python3/bak/263.py.bak b/solutions/python3/bak/263.py.bak new file mode 100644 index 0000000..8e8ba2e --- /dev/null +++ b/solutions/python3/bak/263.py.bak @@ -0,0 +1,10 @@ +class Solution: + def isUgly(self, num): + """ + :type num: int + :rtype: bool + """ + while num>1: + if num%2!=0 and num%3!=0 and num%5!=0: return False + else: num/=[i for i in (2,3,5) if num%i==0][-1] + return num==1 \ No newline at end of file diff --git a/solutions/python3/bak/264.py.bak b/solutions/python3/bak/264.py.bak new file mode 100644 index 0000000..3de7119 --- /dev/null +++ b/solutions/python3/bak/264.py.bak @@ -0,0 +1,11 @@ +class Solution: + def nthUglyNumber(self, n): + arr, heap, used = [], [1], set() + for i in range(n): + num = heapq.heappop(heap) + arr.append(num) + for p in (2, 3, 5): + if p * num not in used: + heapq.heappush(heap, p * num) + used.add(p * num) + return arr[-1] \ No newline at end of file diff --git a/solutions/python3/bak/265.py.bak b/solutions/python3/bak/265.py.bak new file mode 100644 index 0000000..62dbae8 --- /dev/null +++ b/solutions/python3/bak/265.py.bak @@ -0,0 +1,5 @@ +class Solution: + def minCostII(self, costs): + for i in range(1, len(costs)): + for j in range(len(costs[0])): costs[i][j] += min(costs[i - 1][:j] + costs[i - 1][j + 1:]) + return costs and min(costs[-1]) or 0 \ No newline at end of file diff --git a/solutions/python3/bak/266.py.bak b/solutions/python3/bak/266.py.bak new file mode 100644 index 0000000..8c4620f --- /dev/null +++ b/solutions/python3/bak/266.py.bak @@ -0,0 +1,4 @@ +class Solution: + def canPermutePalindrome(self, s): + cnt = collections.Counter(s) + return len([c for c in cnt if cnt[c] % 2]) <= 1 \ No newline at end of file diff --git a/solutions/python3/bak/267.py.bak b/solutions/python3/bak/267.py.bak new file mode 100644 index 0000000..e9451ca --- /dev/null +++ b/solutions/python3/bak/267.py.bak @@ -0,0 +1,13 @@ +class Solution: + def generatePalindromes(self, s): + cnt, n = collections.Counter(s), len(s) // 2 + odd, s, q = [c for c in cnt if cnt[c] % 2], "".join(k * (cnt[k] // 2) for k in cnt), {"#" * n} + if len(odd) > 1: return [] + for c in s: + new = set() + for w in q: + for i in range(n): + if w[i] == "#": + new.add(w[:i] + c + w[i + 1:]) + q = new + return [w + odd[0] + w[::-1] for w in q] if odd else [w + w[::-1] for w in q] \ No newline at end of file diff --git a/solutions/python3/bak/268.py.bak b/solutions/python3/bak/268.py.bak new file mode 100644 index 0000000..fc5ab13 --- /dev/null +++ b/solutions/python3/bak/268.py.bak @@ -0,0 +1,7 @@ +class Solution: + def missingNumber(self, nums): + """ + :type nums: List[int] + :rtype: int + """ + return len(nums)*(len(nums)+1)//2-sum(nums) \ No newline at end of file diff --git a/solutions/python3/bak/269.py.bak b/solutions/python3/bak/269.py.bak new file mode 100644 index 0000000..0c269ad --- /dev/null +++ b/solutions/python3/bak/269.py.bak @@ -0,0 +1,20 @@ +class Solution(object): + def alienOrder(self, words): + if len(words) == 1: return words[0] + def dfs(i): + visited[i] = 0 + for v in graph[i]: + if visited[v] == 0 or (visited[v] == -1 and not dfs(v)): return False + order.append(chr(97 + i)) + visited[i] = 1 + return True + graph, visited, order = collections.defaultdict(set), [1] * 26, [] + for w1, w2 in zip(words, words[1:]): + for c1, c2 in zip(w1, w2): + if c1 != c2: + graph[ord(c1) - ord("a")].add(ord(c2) - ord("a")) + break + for c in w1 + w2: visited[ord(c) - ord("a")] = -1 + for i in range(26): + if visited[i] == -1 and not dfs(i): return "" + return "".join(order)[::-1] \ No newline at end of file diff --git a/solutions/python3/bak/27.py.bak b/solutions/python3/bak/27.py.bak new file mode 100644 index 0000000..fcc1af8 --- /dev/null +++ b/solutions/python3/bak/27.py.bak @@ -0,0 +1,8 @@ +class Solution: + def removeElement(self, nums: List[int], val: int) -> int: + i = 0 + for num in nums: + if num != val: + nums[i] = num + i += 1 + return i \ No newline at end of file diff --git a/solutions/python3/bak/270.py.bak b/solutions/python3/bak/270.py.bak new file mode 100644 index 0000000..e2c0aaf --- /dev/null +++ b/solutions/python3/bak/270.py.bak @@ -0,0 +1,27 @@ +# Definition for a binary tree node. +# class TreeNode: +# def __init__(self, x): +# self.val = x +# self.left = None +# self.right = None + +class Solution: + def closestValue(self, root, target): + """ + :type root: TreeNode + :type target: float + :rtype: int + """ + res, d = [0], [float("inf")] + def dfs(node): + if node: + new = node.val - target if node.val >= target else target - node.val + if new < d[0]: + d[0] = new + res[0] = node.val + if target < node.val: + dfs(node.left) + else: + dfs(node.right) + dfs(root) + return res[0] \ No newline at end of file diff --git a/solutions/python3/bak/272.py.bak b/solutions/python3/bak/272.py.bak new file mode 100644 index 0000000..2bddc29 --- /dev/null +++ b/solutions/python3/bak/272.py.bak @@ -0,0 +1,17 @@ +# Definition for a binary tree node. +# class TreeNode: +# def __init__(self, x): +# self.val = x +# self.left = None +# self.right = None + +class Solution: + def closestKValues(self, root, target, k): + d = [] + def dfs(node): + if node: + heapq.heappush(d, (abs(node.val - target), node.val)) + dfs(node.left) + dfs(node.right) + dfs(root) + return [node for val, node in heapq.nsmallest(k, d)] \ No newline at end of file diff --git a/solutions/python3/bak/273.py.bak b/solutions/python3/bak/273.py.bak new file mode 100644 index 0000000..4c3537c --- /dev/null +++ b/solutions/python3/bak/273.py.bak @@ -0,0 +1,25 @@ +class Solution: + def __init__(self): + self.lessThan20 = ["","One","Two","Three","Four","Five","Six","Seven","Eight","Nine","Ten","Eleven","Twelve","Thirteen","Fourteen","Fifteen","Sixteen","Seventeen","Eighteen","Nineteen"] + self.tens = ["","Ten","Twenty","Thirty","Forty","Fifty","Sixty","Seventy","Eighty","Ninety"] + self.thousands = ["","Thousand","Million","Billion"] + + def numberToWords(self, num): + if not num: + return "Zero" + res = "" + for thousand in self.thousands: + if num % 1000: + res = self.helper(num%1000) + thousand + " " + res + num //= 1000 + return res.strip() + + def helper(self, num): + if not num: + return "" + elif num < 20: + return self.lessThan20[num] + " " + elif num < 100: + return self.tens[num//10] + " " + self.helper(num%10) + else: + return self.lessThan20[num//100] + " Hundred " + self.helper(num%100) \ No newline at end of file diff --git a/solutions/python3/bak/274.py.bak b/solutions/python3/bak/274.py.bak new file mode 100644 index 0000000..9278ce2 --- /dev/null +++ b/solutions/python3/bak/274.py.bak @@ -0,0 +1,6 @@ +class Solution: + def hIndex(self, citations): + citations.sort() + for i in range(len(citations)): + if len(citations) - i <= citations[i]: return len(citations) - i + return 0 \ No newline at end of file diff --git a/solutions/python3/bak/275.py.bak b/solutions/python3/bak/275.py.bak new file mode 100644 index 0000000..83fa9bf --- /dev/null +++ b/solutions/python3/bak/275.py.bak @@ -0,0 +1,8 @@ +class Solution: + def hIndex(self, citations): + l, r, res = 0, len(citations) - 1, 0 + while l <= r: + mid = (l + r) // 2 + if len(citations) - mid <= citations[mid]: res, r = len(citations) - mid, r - 1 + else: l = mid + 1 + return res \ No newline at end of file diff --git a/solutions/python3/bak/276.py.bak b/solutions/python3/bak/276.py.bak new file mode 100644 index 0000000..544d2de --- /dev/null +++ b/solutions/python3/bak/276.py.bak @@ -0,0 +1,5 @@ +class Solution: + def numWays(self, n, k): + same, dif = 0, k + for _ in range(1, n): same, dif = dif, (same + dif) * (k - 1) + return n and same + dif or 0 \ No newline at end of file diff --git a/solutions/python3/bak/278.py.bak b/solutions/python3/bak/278.py.bak new file mode 100644 index 0000000..303730c --- /dev/null +++ b/solutions/python3/bak/278.py.bak @@ -0,0 +1,19 @@ +# The isBadVersion API is already defined for you. +# @param version, an integer +# @return a bool +# def isBadVersion(version): + +class Solution: + def firstBadVersion(self, n): + """ + :type n: int + :rtype: int + """ + l, r = 0, n + while l <= r: + mid = (l + r) // 2 + if isBadVersion(mid): + r = mid - 1 + else: + l = mid + 1 + return r + 1 \ No newline at end of file diff --git a/solutions/python3/bak/279.py.bak b/solutions/python3/bak/279.py.bak new file mode 100644 index 0000000..f2645b6 --- /dev/null +++ b/solutions/python3/bak/279.py.bak @@ -0,0 +1,8 @@ +class Solution: + def numSquares(self, n): + q, move = {i ** 2 for i in range(1, int(n ** 0.5) + 1)}, 1 + coins = set(q) + while q: + if n in q: return move + q = {sm + c for sm in q for c in coins} - q + move += 1 \ No newline at end of file diff --git a/solutions/python3/bak/28.py.bak b/solutions/python3/bak/28.py.bak new file mode 100644 index 0000000..3c906ff --- /dev/null +++ b/solutions/python3/bak/28.py.bak @@ -0,0 +1,3 @@ +class Solution: + def strStr(self, haystack, needle): + return haystack.find(needle) \ No newline at end of file diff --git a/solutions/python3/bak/280.py.bak b/solutions/python3/bak/280.py.bak new file mode 100644 index 0000000..fa3046d --- /dev/null +++ b/solutions/python3/bak/280.py.bak @@ -0,0 +1,14 @@ +class Solution: + def wiggleSort(self, nums): + n = len(nums) + for i in range(0, n -1, 2): + if i == n - 2: + if nums[-1] < nums[-2]: + nums[-2], nums[-1] = nums[-1], nums[-2] + else: + if nums[i + 2] >= nums[i + 1] < nums[i]: + nums[i], nums[i + 1] = nums[i + 1], nums[i] + elif nums[i] > nums[i + 2] <= nums[i + 1]: + nums[i], nums[i + 2] = nums[i + 2], nums[i] + if nums[i + 2] > nums[i + 1]: + nums[i + 1], nums[i + 2] = nums[i + 2], nums[i + 1] \ No newline at end of file diff --git a/solutions/python3/bak/282.py.bak b/solutions/python3/bak/282.py.bak new file mode 100644 index 0000000..fe68842 --- /dev/null +++ b/solutions/python3/bak/282.py.bak @@ -0,0 +1,22 @@ +class Solution: + def addOperators(self, num, target): + """ + :type num: str + :type target: int + :rtype: List[str] + """ + # s, val, cur, coeff + q = {("", 0, 0, 1)} + for i, c in enumerate(num): + new = set() + for s, val, cur, coeff in q: + if i: + new.add((s + "+" + c, val + int(c), int(c), 1)) + new.add((s + "-" + c, val - int(c), int(c), -1)) + new.add((s + "*" + c, val + cur * coeff * (int(c) - 1), int(c), cur * coeff)) + if s and s[-1] == "0" and cur == 0: continue + pre = cur + cur = cur * 10 + int(c) + new.add((s + c, val + coeff * (cur - pre), cur, coeff)) + q = new + return [s for s, val, cur, coeff in q if val == target] \ No newline at end of file diff --git a/solutions/python3/bak/283.py.bak b/solutions/python3/bak/283.py.bak new file mode 100644 index 0000000..06d0516 --- /dev/null +++ b/solutions/python3/bak/283.py.bak @@ -0,0 +1,10 @@ +class Solution: + def moveZeroes(self, nums): + """ + :type nums: List[int] + :rtype: void Do not return anything, modify nums in-place instead. + """ + i, items=0, 0 + while i "TreeNode": + if not root: + return + if root.val > p.val: + return self.inorderSuccessor(root.left, p) or root + return self.inorderSuccessor(root.right, p) diff --git a/solutions/python3/bak/286.py.bak b/solutions/python3/bak/286.py.bak new file mode 100644 index 0000000..7a313d2 --- /dev/null +++ b/solutions/python3/bak/286.py.bak @@ -0,0 +1,13 @@ +class Solution: + def wallsAndGates(self, rooms): + m, n = len(rooms), len(rooms and rooms[0]) + q, dist = [(i, j) for i in range(m) for j in range(n) if not rooms[i][j]], 0 + while q: + new = [] + dist += 1 + for i, j in q: + for x, y in ((i - 1, j), (i + 1, j), (i, j - 1), (i, j + 1)): + if 0 <= x < m and 0 <= y < n and rooms[x][y] == 2147483647: + rooms[x][y] = dist + new.append((x, y)) + q = new \ No newline at end of file diff --git a/solutions/python3/bak/287.py.bak b/solutions/python3/bak/287.py.bak new file mode 100644 index 0000000..5df34eb --- /dev/null +++ b/solutions/python3/bak/287.py.bak @@ -0,0 +1,14 @@ +class Solution: + def findDuplicate(self, nums): + """ + :type nums: List[int] + :rtype: int + """ + low, high, mid = 0, len(nums)-1, len(nums)-1 // 2 + while high - low > 1: + count, mid = 0, (high + low) // 2 + for k in nums: + if mid < k <= high: count += 1 + if count > high - mid: low = mid + else: high = mid + return high \ No newline at end of file diff --git a/solutions/python3/bak/288.py.bak b/solutions/python3/bak/288.py.bak new file mode 100644 index 0000000..80f0064 --- /dev/null +++ b/solutions/python3/bak/288.py.bak @@ -0,0 +1,15 @@ +class ValidWordAbbr: + + def __init__(self, dictionary: List[str]): + self.pool = collections.defaultdict(set) + for w in dictionary: + self.pool[w[2:] and w[0] + str(len(w) - 2) + w[-1] or w].add(w) + + + def isUnique(self, w: str) -> bool: + return not self.pool[w[2:] and w[0] + str(len(w) - 2) + w[-1] or w] - {w} + + +# Your ValidWordAbbr object will be instantiated and called as such: +# obj = ValidWordAbbr(dictionary) +# param_1 = obj.isUnique(word) \ No newline at end of file diff --git a/solutions/python3/bak/289.py.bak b/solutions/python3/bak/289.py.bak new file mode 100644 index 0000000..d3a88ba --- /dev/null +++ b/solutions/python3/bak/289.py.bak @@ -0,0 +1,13 @@ +class Solution: + def gameOfLife(self, board): + m, n = len(board), len(board[0]) + matrix = [[0] * n for i in range(m)] + for i in range(m): + for j in range(n): + cnt = 0 + for x, y in ((i - 1, j), (i + 1, j), (i, j - 1), (i, j + 1), (i - 1, j - 1), (i + 1, j + 1), (i - 1, j + 1), (i + 1, j - 1)): + if 0 <= x < m and 0 <= y < n and board[x][y] == 1: cnt += 1 + if (board[i][j] and 2 <= cnt <= 3) or (not board[i][j] and cnt == 3): matrix[i][j] = 1 + for i in range(m): + for j in range(n): + board[i][j] = matrix[i][j] \ No newline at end of file diff --git a/solutions/python3/bak/29.py.bak b/solutions/python3/bak/29.py.bak new file mode 100644 index 0000000..cd86694 --- /dev/null +++ b/solutions/python3/bak/29.py.bak @@ -0,0 +1,18 @@ +class Solution: + def divide(self, dividend, divisor): + """ + :type dividend: int + :type divisor: int + :rtype: int + """ + positive = (dividend < 0) is (divisor < 0) + dividend, divisor, res = abs(dividend), abs(divisor), 0 + while dividend >= divisor: + temp, i = divisor, 1 + while dividend >= temp: + dividend -= temp + res += i + i <<= 1 + temp <<= 1 + if not positive: res = -res + return min(max(-2 ** 31, res), 2 ** 31 - 1) \ No newline at end of file diff --git a/solutions/python3/bak/290.py.bak b/solutions/python3/bak/290.py.bak new file mode 100644 index 0000000..6d53be3 --- /dev/null +++ b/solutions/python3/bak/290.py.bak @@ -0,0 +1,16 @@ +class Solution: + def wordPattern(self, pattern, str): + """ + :type pattern: str + :type str: str + :rtype: bool + """ + if len(str.split())!=len(pattern): return False + dic={} + for word in str.split(): + if not pattern[0] in dic.values() and not word in dic: dic[word]=pattern[0] + else: + if not word in dic or dic[word]!=pattern[0]: return False + pattern=pattern[1:] + return True + \ No newline at end of file diff --git a/solutions/python3/bak/291.py.bak b/solutions/python3/bak/291.py.bak new file mode 100644 index 0000000..55ac61e --- /dev/null +++ b/solutions/python3/bak/291.py.bak @@ -0,0 +1,17 @@ +class Solution: + def wordPatternMatch(self, pattern, s): + m, n = len(pattern), len(s) + def dfs(i, j, dic, used): + if i >= m or j >= n: + return i == m and j == n + elif pattern[i] in dic: + return s[j:j + len(dic[pattern[i]])] == dic[pattern[i]] and dfs(i + 1, j + len(dic[pattern[i]]), dic, used) + else: + for k in range(j + 1, n + 1): + if s[j:k] not in used: + dic[pattern[i]] = s[j:k] + if dfs(i + 1, j + len(dic[pattern[i]]), dic, used | {s[j:k]}): + return True + dic.pop(pattern[i]) + return False + return dfs(0, 0, {}, set()) \ No newline at end of file diff --git a/solutions/python3/bak/292.py.bak b/solutions/python3/bak/292.py.bak new file mode 100644 index 0000000..a56eadc --- /dev/null +++ b/solutions/python3/bak/292.py.bak @@ -0,0 +1,7 @@ +class Solution: + def canWinNim(self, n): + """ + :type n: int + :rtype: bool + """ + return False if n%4==0 else True \ No newline at end of file diff --git a/solutions/python3/bak/293.py.bak b/solutions/python3/bak/293.py.bak new file mode 100644 index 0000000..7b90a1a --- /dev/null +++ b/solutions/python3/bak/293.py.bak @@ -0,0 +1,3 @@ +class Solution: + def generatePossibleNextMoves(self, s): + return [s[:i] + "--" + s[i + 2:] for i in range(len(s) - 1) if s[i] == s[i + 1] == "+"] \ No newline at end of file diff --git a/solutions/python3/bak/294.py.bak b/solutions/python3/bak/294.py.bak new file mode 100644 index 0000000..706167f --- /dev/null +++ b/solutions/python3/bak/294.py.bak @@ -0,0 +1,11 @@ +class Solution: + def canWin(self, s): + choices = {i for i in range(1, len(s)) if s[i] == s[i - 1] == "+"} + def dfs(arr, moves, turn): + if not moves: + return turn == 1 + elif turn: + return all(dfs(arr + [m], moves - {m - 1, m, m + 1}, 1 - turn) for m in moves) + else: + return any(dfs(arr + [m], moves - {m - 1, m, m + 1}, 1 - turn) for m in moves) + return not dfs([], choices, 1) \ No newline at end of file diff --git a/solutions/python3/bak/295.py.bak b/solutions/python3/bak/295.py.bak new file mode 100644 index 0000000..3994c3c --- /dev/null +++ b/solutions/python3/bak/295.py.bak @@ -0,0 +1,33 @@ +class MedianFinder: + + def __init__(self): + self.l = [] + self.r = [] + self.m = [] + + def addNum(self, num): + if not self.m: + self.m = [num] + elif len(self.m) == 1: + m = self.m[0] + if num >= m: + self.m = [m, heapq.heappushpop(self.r, num)] + else: + self.m = [-heapq.heappushpop(self.l, -num), m] + else: + m1, m2 = self.m + if num >= m2: + heapq.heappush(self.r, num) + heapq.heappush(self.l, -m1) + self.m = [m2] + elif num <= m1: + heapq.heappush(self.l, -num) + heapq.heappush(self.r, m2) + self.m = [m1] + else: + heapq.heappush(self.l, -m1) + heapq.heappush(self.r, m2) + self.m = [num] + + def findMedian(self): + return sum(self.m) / len(self.m) \ No newline at end of file diff --git a/solutions/python3/bak/296.py.bak b/solutions/python3/bak/296.py.bak new file mode 100644 index 0000000..fc01579 --- /dev/null +++ b/solutions/python3/bak/296.py.bak @@ -0,0 +1,7 @@ +class Solution: + def minTotalDistance(self, grid): + m, n = len(grid), len(grid[0]) + x, y = sorted(i for i in range(m) for j in range(n) if grid[i][j]), sorted(j for i in range(m) for j in range(n) if grid[i][j]) + avg_x = len(x) % 2 and x[len(x) // 2] or (x[len(x) // 2 - 1] + x[len(x) // 2]) / 2 + avg_y = len(y) % 2 and y[len(y) // 2] or (y[len(y) // 2 - 1] + y[len(y) // 2]) / 2 + return int(sum(abs(avg_x - i) + abs(avg_y - j) for i, j in zip(x, y))) \ No newline at end of file diff --git a/solutions/python3/bak/297.py.bak b/solutions/python3/bak/297.py.bak new file mode 100644 index 0000000..839448a --- /dev/null +++ b/solutions/python3/bak/297.py.bak @@ -0,0 +1,29 @@ +class Codec: + + def serialize(self, root): + q, s = root and collections.deque([root]), "" + while q: + node = q.popleft() + if node is None: + s += "null#" + else: + s += str(node.val) + "#" + q += [node.left, node.right] + return s + + + def deserialize(self, data): + data = data and collections.deque(data.split("#")) + q, root = data and collections.deque([TreeNode(int(data.popleft()))]), None + while q: + node = q.popleft() + if not root: + root = node + l, r = data.popleft(), data.popleft() + if l != "null": + node.left = TreeNode(int(l)) + q.append(node.left) + if r != "null": + node.right = TreeNode(int(r)) + q.append(node.right) + return root \ No newline at end of file diff --git a/solutions/python3/bak/298.py.bak b/solutions/python3/bak/298.py.bak new file mode 100644 index 0000000..b69e2c5 --- /dev/null +++ b/solutions/python3/bak/298.py.bak @@ -0,0 +1,15 @@ +# Definition for a binary tree node. +# class TreeNode: +# def __init__(self, x): +# self.val = x +# self.left = None +# self.right = None + +class Solution: + def longestConsecutive(self, root): + q, l = root and [(root, 1)] or [], 0 + while q: + node, path = q.pop() + l = max(l, path) + q += [(child, child.val == node.val + 1 and path + 1 or 1) for child in (node.left, node.right) if child] + return l \ No newline at end of file diff --git a/solutions/python3/bak/299.py.bak b/solutions/python3/bak/299.py.bak new file mode 100644 index 0000000..7ff2db6 --- /dev/null +++ b/solutions/python3/bak/299.py.bak @@ -0,0 +1,10 @@ +class Solution: + def getHint(self, secret, guess): + s, g, a, b = collections.defaultdict(int), collections.defaultdict(int), 0, 0 + for i in range(len(secret)): + if secret[i] == guess[i]: a += 1; continue + if s[guess[i]] > 0: b, s[guess[i]] = b + 1, s[guess[i]] - 1 + else: g[guess[i]] += 1 + if g[secret[i]] > 0: b, g[secret[i]] = b + 1, g[secret[i]] - 1 + else: s[secret[i]] += 1 + return "%dA%dB" % (a, b) \ No newline at end of file diff --git a/solutions/python3/bak/3.py.bak b/solutions/python3/bak/3.py.bak new file mode 100644 index 0000000..2482cd9 --- /dev/null +++ b/solutions/python3/bak/3.py.bak @@ -0,0 +1,12 @@ +class Solution: + def lengthOfLongestSubstring(self, s): + """ + :type s: str + :rtype: int + """ + mx, start, chars = 0, 0, {} + for i in range(len(s)): + if s[i] in chars and start <= chars[s[i]]: start = chars[s[i]] + 1 + else: mx = max(mx, i - start + 1) + chars[s[i]] = i + return mx \ No newline at end of file diff --git a/solutions/python3/bak/30.py.bak b/solutions/python3/bak/30.py.bak new file mode 100644 index 0000000..3ce75d4 --- /dev/null +++ b/solutions/python3/bak/30.py.bak @@ -0,0 +1,15 @@ +class Solution: + def findSubstring(self, s, words): + if not s or not words: return [] + cnt, l_words, l_word, cnt_words, res = collections.Counter(words), len(words[0]) * len(words), len(words[0]), len(words), [] + for i in range(len(s) - l_words + 1): + cur, j = dict(cnt), i + for _ in range(cnt_words): + w = s[j:j + l_word] + if w in cur: + if cur[w] == 1: cur.pop(w) + else: cur[w] -= 1 + else: break + j += l_word + if not cur: res += i, + return res \ No newline at end of file diff --git a/solutions/python3/bak/300.py.bak b/solutions/python3/bak/300.py.bak new file mode 100644 index 0000000..4fce8cf --- /dev/null +++ b/solutions/python3/bak/300.py.bak @@ -0,0 +1,19 @@ +class Solution: + def lengthOfLIS(self, nums): + """ + :type nums: List[int] + :rtype: int + """ + tails = [0] * len(nums) + size = 0 + for x in nums: + i, j = 0, size + while i != j: + m = (i + j) // 2 + if tails[m] < x: + i = m + 1 + else: + j = m + tails[i] = x + size = max(i + 1, size) + return size \ No newline at end of file diff --git a/solutions/python3/bak/301.py.bak b/solutions/python3/bak/301.py.bak new file mode 100644 index 0000000..ee00970 --- /dev/null +++ b/solutions/python3/bak/301.py.bak @@ -0,0 +1,27 @@ +class Solution: + def removeInvalidParentheses(self, s): + l = r = 0 + for c in s: + if c.isalpha(): continue + if c == "(": l += 1 + elif l: l -= 1 + else: r += 1 + q = {("", l, r, 0, 0)} + for c in s: + new = set() + for st, l, r, lCur, rCur in q: + if c == "(": + new.add((st + c, l, r, lCur + 1, rCur)) + if l: + new.add((st, l - 1, r, lCur, rCur)) + elif c == ")": + if lCur: + new.add((st + c, l, r, lCur - 1, rCur)) + else: + new.add((st + c, l, r, lCur, rCur + 1)) + if r: + new.add((st, l, r - 1, lCur, rCur)) + else: + new.add((st + c, l, r, lCur, rCur)) + q = new + return list({st for st, l, r, lCur, rCur in q if l == r == lCur == rCur == 0}) \ No newline at end of file diff --git a/solutions/python3/bak/302.py.bak b/solutions/python3/bak/302.py.bak new file mode 100644 index 0000000..fa656b6 --- /dev/null +++ b/solutions/python3/bak/302.py.bak @@ -0,0 +1,14 @@ +class Solution: + def minArea(self, image, x, y): + l, r, u, d, m, n = [y], [y], [x], [x], len(image), len(image[0]) + def dfs(i, j): + if i < u[0]: u[0] = i + elif i > d[0]: d[0] = i + if j < l[0]: l[0] = j + elif j > r[0]: r[0] = j + for x, y in ((i - 1, j), (i + 1, j), (i, j - 1), (i, j + 1)): + if 0 <= x < m and 0 <= y < n and image[x][y] == "1": + image[x][y] = "0" + dfs(x, y) + dfs(x, y) + return (r[0] - l[0] + 1) * (d[0] - u[0] + 1) \ No newline at end of file diff --git a/solutions/python3/bak/303.py.bak b/solutions/python3/bak/303.py.bak new file mode 100644 index 0000000..99b4628 --- /dev/null +++ b/solutions/python3/bak/303.py.bak @@ -0,0 +1,10 @@ +class NumArray: + + def __init__(self, nums): + self.nums = nums + for i in range(1, len(nums)): + self.nums[i] += self.nums[i - 1] + + + def sumRange(self, i, j): + return self.nums[j] - self.nums[i - 1] if i else self.nums[j] \ No newline at end of file diff --git a/solutions/python3/bak/304.py.bak b/solutions/python3/bak/304.py.bak new file mode 100644 index 0000000..5df98ea --- /dev/null +++ b/solutions/python3/bak/304.py.bak @@ -0,0 +1,10 @@ +class NumMatrix: + + def __init__(self, matrix): + self.sums = [[0] * (len(matrix and matrix[0]) + 1) for _ in range(len(matrix) + 1)] + for i in range(len(matrix)): + for j in range(len(matrix and matrix[0])): + self.sums[i + 1][j + 1] = self.sums[i][j + 1] + self.sums[i + 1][j] - self.sums[i][j] + matrix[i][j] + + def sumRegion(self, row1, col1, row2, col2): + return self.sums[row2 + 1][col2 + 1] - self.sums[row2 + 1][col1] - self.sums[row1][col2 + 1] + self.sums[row1][col1] \ No newline at end of file diff --git a/solutions/python3/bak/305.py.bak b/solutions/python3/bak/305.py.bak new file mode 100644 index 0000000..18ca188 --- /dev/null +++ b/solutions/python3/bak/305.py.bak @@ -0,0 +1,18 @@ +class Solution: + def numIslands2(self, m, n, positions): + def getParent(i): + if i != parent[i]: + parent[i] = getParent(parent[i]) + return parent[i] + islands, res, parent, Id = set(), [], {}, 1 + for i, j in positions: + parent[(i, j)] = parent[Id] = Id + for x, y in ((i - 1, j), (i + 1, j), (i, j - 1), (i, j + 1)): + if (x, y) in parent: + p = getParent(parent[(x, y)]) + islands.discard(p) + parent[p] = Id + islands.add(Id) + Id += 1 + res.append(len(islands)) + return res \ No newline at end of file diff --git a/solutions/python3/bak/306.py.bak b/solutions/python3/bak/306.py.bak new file mode 100644 index 0000000..59b26f0 --- /dev/null +++ b/solutions/python3/bak/306.py.bak @@ -0,0 +1,20 @@ +class Solution: + def isAdditiveNumber(self, num): + def getStarter(): + arr = [] + for i in range(1, len(num) - 1): + for j in range(i + 1, len(num)): + s1, s2 = num[:i], num[i:j] + if (s1[0] == "0" and len(s1) > 1) or (s2[0] == "0" and len(s2) > 1): + continue + arr.append((int(s1), int(s2), j)) + return arr + def dfs(pre1, pre2, i): + if i == len(num): + return True + sm = pre1 + pre2 + l = len(str(sm)) + new = int(num[i:i + l]) + return new == sm and dfs(pre2, new, i + l) + q = getStarter() + return any(dfs(p1, p2, i) for p1, p2, i in q) \ No newline at end of file diff --git a/solutions/python3/bak/307.py.bak b/solutions/python3/bak/307.py.bak new file mode 100644 index 0000000..03bea23 --- /dev/null +++ b/solutions/python3/bak/307.py.bak @@ -0,0 +1,29 @@ +class NumArray: + def __init__(self, nums): + if nums: + self.n = len(nums) + self.tree = [0] * (2 * (2 ** int(math.ceil(math.log(self.n, 2)))) - 1) + def dfs(node, s, e): + if s == e: self.tree[node] = nums[s] + else: + m = (s + e) // 2 + dfs(2 * node + 1, s, m) + dfs(2 * node + 2, m + 1, e) + self.tree[node] = self.tree[2 * node + 1] + self.tree[2 * node + 2] + dfs(0, 0, self.n - 1) + def update(self, i, val): + def dfs(node, s, e, idx, val): + if s == e: self.tree[node] = val + else: + m = (s + e) // 2 + if s <= idx <= m: dfs(2 * node + 1, s, m, idx, val) + else: dfs(2 * node + 2, m + 1, e, idx, val) + self.tree[node] = self.tree[2 * node + 1] + self.tree[2 * node + 2] + dfs(0, 0, self.n - 1, i, val) + def sumRange(self, i, j): + def dfs(node, s, e, l, r): + if r < s or l > e: return 0 + if l <= s and e <= r: return self.tree[node] + m = (s + e) // 2 + return dfs(2 * node + 1, s, m, l, r) + dfs(2 * node + 2, m + 1, e, l, r) + return dfs(0, 0, self.n - 1, i, j) \ No newline at end of file diff --git a/solutions/python3/bak/308.py.bak b/solutions/python3/bak/308.py.bak new file mode 100644 index 0000000..b84ebbe --- /dev/null +++ b/solutions/python3/bak/308.py.bak @@ -0,0 +1,44 @@ +class NumMatrix(object): + def __init__(self, matrix): + """ + initialize your data structure here. + :type matrix: List[List[int]] + """ + for row in matrix: + for col in range(1, len(row)): + row[col] += row[col-1] + self.matrix = matrix + + + def update(self, row, col, val): + """ + update the element at matrix[row,col] to val. + :type row: int + :type col: int + :type val: int + :rtype: void + """ + original = self.matrix[row][col] + if col != 0: + original -= self.matrix[row][col-1] + + diff = original - val + + for y in range(col, len(self.matrix[0])): + self.matrix[row][y] -= diff + + def sumRegion(self, row1, col1, row2, col2): + """ + sum of elements matrix[(row1,col1)..(row2,col2)], inclusive. + :type row1: int + :type col1: int + :type row2: int + :type col2: int + :rtype: int + """ + sum = 0 + for x in range(row1, row2+1): + sum += self.matrix[x][col2] + if col1 != 0: + sum -= self.matrix[x][col1-1] + return sum \ No newline at end of file diff --git a/solutions/python3/bak/309.py.bak b/solutions/python3/bak/309.py.bak new file mode 100644 index 0000000..406797b --- /dev/null +++ b/solutions/python3/bak/309.py.bak @@ -0,0 +1,6 @@ +class Solution: + def maxProfit(self, prices): + dp1, dp2, dp3 = 0, 0, -float("inf") + for p in prices: + dp1, dp2, dp3 = dp3 + p, max(dp1, dp2), max(dp2 - p, dp3) + return max(dp1, dp2) \ No newline at end of file diff --git a/solutions/python3/bak/31.py.bak b/solutions/python3/bak/31.py.bak new file mode 100644 index 0000000..c95c990 --- /dev/null +++ b/solutions/python3/bak/31.py.bak @@ -0,0 +1,13 @@ +class Solution: + def nextPermutation(self, nums): + perm, l = False, len(nums) - 2 + while 0 <= l: + r = len(nums) - 1 + while l < r and nums[r] <= nums[l]: + r -= 1 + if r <= l: + l -= 1 + else: + nums[l], nums[l + 1:], perm = nums[r], sorted(nums[l + 1:r] + [nums[l]] + nums[r + 1:]), True + break + if not perm: nums.sort() \ No newline at end of file diff --git a/solutions/python3/bak/310.py.bak b/solutions/python3/bak/310.py.bak new file mode 100644 index 0000000..109509f --- /dev/null +++ b/solutions/python3/bak/310.py.bak @@ -0,0 +1,18 @@ +class Solution: + def findMinHeightTrees(self, n, edges): + if n == 1: return [0] + adj = [set() for i in range(n)] + for i, j in edges: + adj[i].add(j) + adj[j].add(i) + leaves = [i for i in range(n) if len(adj[i]) == 1] + while n > 2: + n -= len(leaves) + newleaves = [] + for i in leaves: + j = adj[i].pop() + adj[j].remove(i) + if len(adj[j]) == 1: + newleaves.append(j) + leaves = newleaves + return leaves \ No newline at end of file diff --git a/solutions/python3/bak/311.py.bak b/solutions/python3/bak/311.py.bak new file mode 100644 index 0000000..8d5ff77 --- /dev/null +++ b/solutions/python3/bak/311.py.bak @@ -0,0 +1,3 @@ +class Solution: + def multiply(self, A, B): + return [[sum(a * b for a, b in zip(A[i], [B[k][j] for k in range(len(B))])) for j in range(len(B[0]))] for i in range(len(A))] \ No newline at end of file diff --git a/solutions/python3/bak/312.py.bak b/solutions/python3/bak/312.py.bak new file mode 100644 index 0000000..cc68e11 --- /dev/null +++ b/solutions/python3/bak/312.py.bak @@ -0,0 +1,8 @@ +class Solution: + def maxCoins(self, nums): + memo, nums = {}, [1] + [num for num in nums if num] + [1] + def dfs(l, r): + if r - l == 1: return 0 + if (l, r) not in memo: memo[(l, r)] = max(nums[l] * nums[i] * nums[r] + dfs(l, i) + dfs(i, r) for i in range(l + 1, r)) + return memo[(l, r)] + return dfs(0, len(nums) - 1) \ No newline at end of file diff --git a/solutions/python3/bak/313.py.bak b/solutions/python3/bak/313.py.bak new file mode 100644 index 0000000..81ee832 --- /dev/null +++ b/solutions/python3/bak/313.py.bak @@ -0,0 +1,11 @@ +class Solution: + def nthSuperUglyNumber(self, n, primes): + arr, heap, used = [1], primes[:], set() + for i in range(1, n): + num = heapq.heappop(heap) + arr.append(num) + for p in primes: + if p * num not in used: + heapq.heappush(heap, p * num) + used.add(p * num) + return arr[-1] \ No newline at end of file diff --git a/solutions/python3/bak/314.py.bak b/solutions/python3/bak/314.py.bak new file mode 100644 index 0000000..d4f8bf3 --- /dev/null +++ b/solutions/python3/bak/314.py.bak @@ -0,0 +1,20 @@ +# Definition for a binary tree node. +# class TreeNode: +# def __init__(self, x): +# self.val = x +# self.left = None +# self.right = None + +class Solution: + def verticalOrder(self, root): + q, arrays = root and collections.deque([(root, 0)]) or None, collections.defaultdict(list) + while q: + new = collections.deque() + for node, ind in q: + arrays[ind].append(node.val) + if node.left: + new.append((node.left, ind - 1)) + if node.right: + new.append((node.right, ind + 1)) + q = new + return [arr for i, arr in sorted(arrays.items())] \ No newline at end of file diff --git a/solutions/python3/bak/315.py.bak b/solutions/python3/bak/315.py.bak new file mode 100644 index 0000000..2ae1b56 --- /dev/null +++ b/solutions/python3/bak/315.py.bak @@ -0,0 +1,7 @@ +class Solution: + def countSmaller(self, nums): + r = [] + for i in range(len(nums) - 1, -1, -1): + bisect.insort(r, nums[i]) + nums[i] = bisect.bisect_left(r, nums[i]) + return nums \ No newline at end of file diff --git a/solutions/python3/bak/316.py.bak b/solutions/python3/bak/316.py.bak new file mode 100644 index 0000000..b73e7f6 --- /dev/null +++ b/solutions/python3/bak/316.py.bak @@ -0,0 +1,10 @@ +class Solution: + def removeDuplicateLetters(self, s): + rindex = {c: i for i, c in enumerate(s)} + result = '' + for i, c in enumerate(s): + if c not in result: + while c < result[-1:] and i < rindex[result[-1]]: + result = result[:-1] + result += c + return result \ No newline at end of file diff --git a/solutions/python3/bak/317.py.bak b/solutions/python3/bak/317.py.bak new file mode 100644 index 0000000..42a9559 --- /dev/null +++ b/solutions/python3/bak/317.py.bak @@ -0,0 +1,20 @@ +class Solution: + def shortestDistance(self, grid: List[List[int]]) -> int: + m, n, d = len(grid), len(grid[0]), 1 + piled = collections.defaultdict(set) + dist = collections.defaultdict(int) + bfs = [(i, j, i, j) for i in range(m) for j in range(n) if grid[i][j] == 1] + total, res = len(bfs), [] + while bfs: + new = [] + for x, y, i, j in bfs: + for ii, jj in ((i + 1, j), (i - 1, j), (i, j + 1), (i, j - 1)): + if 0 <= ii < m and 0 <= jj < n and not grid[ii][jj] and (x, y) not in piled[(ii, jj)]: + piled[(ii, jj)].add((x, y)) + dist[(ii, jj)] += d + if len(piled[(ii, jj)]) == total: + res.append(dist[(ii, jj)]) + new.append((x, y, ii, jj)) + bfs = new + d += 1 + return min(res) if res else -1 \ No newline at end of file diff --git a/solutions/python3/bak/318.py.bak b/solutions/python3/bak/318.py.bak new file mode 100644 index 0000000..d4e3702 --- /dev/null +++ b/solutions/python3/bak/318.py.bak @@ -0,0 +1,11 @@ +class Solution: + def maxProduct(self, words): + sets, mx = {w: set(w) for w in words}, 0 + words.sort(key = len, reverse = True) + for i in range(len(words) - 1): + for j in range(i + 1, len(words)): + if len(words[i]) * len(words[j]) <= mx: + break + elif not sets[words[i]] & sets[words[j]]: + mx = len(words[i]) * len(words[j]) + return mx \ No newline at end of file diff --git a/solutions/python3/bak/319.py.bak b/solutions/python3/bak/319.py.bak new file mode 100644 index 0000000..026768c --- /dev/null +++ b/solutions/python3/bak/319.py.bak @@ -0,0 +1,3 @@ +class Solution: + def bulbSwitch(self, n): + return int(n ** 0.5) \ No newline at end of file diff --git a/solutions/python3/bak/32.py.bak b/solutions/python3/bak/32.py.bak new file mode 100644 index 0000000..3e099fc --- /dev/null +++ b/solutions/python3/bak/32.py.bak @@ -0,0 +1,9 @@ +class Solution: + def longestValidParentheses(self, s): + stack, mx = [], 0 + for i, c in enumerate(s): + if c == ")" and stack and s[stack[-1]] == "(": stack.pop() + else: stack.append(i) + stack = [-1] + stack + [len(s)] + for i1, i2 in zip(stack, stack[1:]): mx = max(mx, i2 - i1 - 1) + return mx if len(stack) > 2 else len(s) \ No newline at end of file diff --git a/solutions/python3/bak/320.py.bak b/solutions/python3/bak/320.py.bak new file mode 100644 index 0000000..f193d3a --- /dev/null +++ b/solutions/python3/bak/320.py.bak @@ -0,0 +1,13 @@ +class Solution: + def generateAbbreviations(self, word): + l, res = len(word), [] + def dfs(s, i): + if i == l: + res.append(s) + else: + dfs(s + word[i], i + 1) + if not s or s[-1] > "9": + for j in range(i + 1, l + 1): + dfs(s + str(j - i), j) + dfs("", 0) + return res \ No newline at end of file diff --git a/solutions/python3/bak/321.py.bak b/solutions/python3/bak/321.py.bak new file mode 100644 index 0000000..04d8c48 --- /dev/null +++ b/solutions/python3/bak/321.py.bak @@ -0,0 +1,30 @@ +class Solution: + def maxNumber(self, nums1, nums2, k): + def merge(arr1, arr2): + res, i, j = [], 0, 0 + while i < len(arr1) and j < len(arr2): + if arr1[i:] >= arr2[j:]: + res.append(arr1[i]) + i += 1 + else: + res.append(arr2[j]) + j += 1 + if i < len(arr1): res += arr1[i:] + elif j < len(arr2): res += arr2[j:] + return res + + def makeArr(arr, l): + i, res = 0, [] + for r in range(l - 1, -1, -1): + num, i = max(arr[i:-r] or arr[i:]) + i = -i + 1 + res.append(num) + return res + + nums1, nums2, choices = [(num, -i) for i, num in enumerate(nums1)], [(num, -i) for i, num in enumerate(nums2)], [] + for m in range(k + 1): + if m > len(nums1) or k - m > len(nums2): continue + arr1, arr2 = makeArr(nums1, m), makeArr(nums2, k - m) + choices.append(merge(arr1, arr2)) + return max(choices) + \ No newline at end of file diff --git a/solutions/python3/bak/322.py.bak b/solutions/python3/bak/322.py.bak new file mode 100644 index 0000000..ebebc91 --- /dev/null +++ b/solutions/python3/bak/322.py.bak @@ -0,0 +1,10 @@ +class Solution: + def coinChange(self, coins, amount): + """ + :type coins: List[int] + :type amount: int + :rtype: int + """ + dp = [0] + [float('inf')] * amount + for i in range(1, amount + 1): dp[i] = min([dp[i - c] if i - c >= 0 else float('inf') for c in coins]) + 1 + return dp[amount] if dp[amount] != float('inf') else -1 \ No newline at end of file diff --git a/solutions/python3/bak/323.py.bak b/solutions/python3/bak/323.py.bak new file mode 100644 index 0000000..dbe227e --- /dev/null +++ b/solutions/python3/bak/323.py.bak @@ -0,0 +1,16 @@ +class Solution: + def countComponents(self, n, edges): + visited, res, adj = set(), 0, collections.defaultdict(set) + for a, b in edges: + adj[a].add(b) + adj[b].add(a) + def dfs(i): + visited.add(i) + for v in adj[i]: + if v not in visited: + dfs(v) + for i in range(n): + if i not in visited: + res += 1 + dfs(i) + return res \ No newline at end of file diff --git a/solutions/python3/bak/324.py.bak b/solutions/python3/bak/324.py.bak new file mode 100644 index 0000000..ddc1eb7 --- /dev/null +++ b/solutions/python3/bak/324.py.bak @@ -0,0 +1,11 @@ +class Solution: + def wiggleSort(self, nums: List[int]) -> None: + """ + Do not return anything, modify nums in-place instead. + """ + heap = [-num for num in nums] + heapq.heapify(heap) + for i in range(1, len(nums), 2): + nums[i] = -heapq.heappop(heap) + for i in range(0, len(nums), 2): + nums[i] = -heapq.heappop(heap) \ No newline at end of file diff --git a/solutions/python3/bak/325.py.bak b/solutions/python3/bak/325.py.bak new file mode 100644 index 0000000..32d21c9 --- /dev/null +++ b/solutions/python3/bak/325.py.bak @@ -0,0 +1,11 @@ +class Solution: + def maxSubArrayLen(self, nums, k): + index, l, sm = {}, 0, 0 + index[0] = -1 + for i, num in enumerate(nums): + sm += num + if sm - k in index: + l = max(l, i - index[sm - k]) + if sm not in index: + index[sm] = i + return l \ No newline at end of file diff --git a/solutions/python3/bak/326.py.bak b/solutions/python3/bak/326.py.bak new file mode 100644 index 0000000..d6497ae --- /dev/null +++ b/solutions/python3/bak/326.py.bak @@ -0,0 +1,6 @@ +class Solution: + def isPowerOfThree(self, n: int) -> bool: + i = 1 + while i < n: + i *=3 + return i == n \ No newline at end of file diff --git a/solutions/python3/bak/327.py.bak b/solutions/python3/bak/327.py.bak new file mode 100644 index 0000000..9352c0a --- /dev/null +++ b/solutions/python3/bak/327.py.bak @@ -0,0 +1,8 @@ +class Solution: + def countRangeSum(self, nums, lower, upper): + sums, sm, res = [0], 0, 0 + for num in nums: + sm += num + res += bisect.bisect_right(sums, sm - lower) - bisect.bisect_left(sums, sm - upper) + bisect.insort(sums, sm) + return res \ No newline at end of file diff --git a/solutions/python3/bak/328.py.bak b/solutions/python3/bak/328.py.bak new file mode 100644 index 0000000..6491270 --- /dev/null +++ b/solutions/python3/bak/328.py.bak @@ -0,0 +1,21 @@ +# Definition for singly-linked list. +# class ListNode: +# def __init__(self, x): +# self.val = x +# self.next = None + +class Solution: + def oddEvenList(self, head): + """ + :type head: ListNode + :rtype: ListNode + """ + root, i, last, first = head, 1, None, None + if head and head.next: first = head.next + while head: + latter = head.next + if i%2 != 0: last = head + if head.next: head.next = head.next.next + head, i = latter, i+1 + if last: last.next = first + return root \ No newline at end of file diff --git a/solutions/python3/bak/329.py.bak b/solutions/python3/bak/329.py.bak new file mode 100644 index 0000000..336add1 --- /dev/null +++ b/solutions/python3/bak/329.py.bak @@ -0,0 +1,9 @@ +class Solution: + def longestIncreasingPath(self, matrix): + def dfs(i, j): + if not dp[i][j]: + dp[i][j] = 1+max((dfs(x,y) for x,y in ((i-1,j),(i+1,j),(i,j-1),(i,j+1)) if 0 <=x matrix[i][j]),default=0) + return dp[i][j] + m, n, = len(matrix), len(matrix and matrix[0]) + dp = [[0] * n for _ in range(m)] + return max((dfs(i,j) for i in range(m) for j in range(n)),default=0) \ No newline at end of file diff --git a/solutions/python3/bak/33.py.bak b/solutions/python3/bak/33.py.bak new file mode 100644 index 0000000..84aa96f --- /dev/null +++ b/solutions/python3/bak/33.py.bak @@ -0,0 +1,12 @@ +class Solution: + def search(self, nums, target): + l, r = 0, len(nums) - 1 + while l <= r: + mid = (l + r) // 2 + if nums[mid] == target: + return mid + elif sum((target < nums[l], nums[l] <= nums[mid], nums[mid] < target)) == 2: + l = mid + 1 + else: + r = mid - 1 + return -1 \ No newline at end of file diff --git a/solutions/python3/bak/330.py.bak b/solutions/python3/bak/330.py.bak new file mode 100644 index 0000000..26582e2 --- /dev/null +++ b/solutions/python3/bak/330.py.bak @@ -0,0 +1,11 @@ +class Solution: + def minPatches(self, nums, n): + miss, added, i = 1, 0, 0 + while miss <= n: + if i < len(nums) and nums[i] <= miss: + miss += nums[i] + i += 1 + else: + miss *= 2 + added += 1 + return added \ No newline at end of file diff --git a/solutions/python3/bak/331.py.bak b/solutions/python3/bak/331.py.bak new file mode 100644 index 0000000..e97908b --- /dev/null +++ b/solutions/python3/bak/331.py.bak @@ -0,0 +1,12 @@ +class Solution: + def isValidSerialization(self, preorder: str) -> bool: + stack = [] + for c in preorder.split(','): + stack.append(c) + while stack[-2:] == ['#', '#']: + stack.pop() + stack.pop() + if not stack: return False + stack.pop() + stack.append('#') + return stack == ['#'] \ No newline at end of file diff --git a/solutions/python3/bak/332.py.bak b/solutions/python3/bak/332.py.bak new file mode 100644 index 0000000..bd9618b --- /dev/null +++ b/solutions/python3/bak/332.py.bak @@ -0,0 +1,8 @@ +class Solution: + def findItinerary(self, tickets): + graph, stack, reached = collections.defaultdict(list), ["JFK"], [] + for a, b in tickets: heapq.heappush(graph[a], b) + while stack: + if graph[stack[-1]]: stack.append(heapq.heappop(graph[stack[-1]])) + else: reached.append(stack.pop()) + return reached[::-1] \ No newline at end of file diff --git a/solutions/python3/bak/333.py.bak b/solutions/python3/bak/333.py.bak new file mode 100644 index 0000000..05379cc --- /dev/null +++ b/solutions/python3/bak/333.py.bak @@ -0,0 +1,14 @@ +class Solution: + def largestBSTSubtree(self, root): + def dfs(node): + if not node: + return True, 0, None, None, 0 + lBool, lSize, lMx, lMn, lTree = dfs(node.left) + rBool, rSize, rMx, rMn, rTree = dfs(node.right) + lVal = lMx if lMx != None else -float("inf") + rVal = rMn if rMn != None else float("inf") + curMx = max(val for val in (lMx, rMx, node.val) if val != None) + curMn = min(val for val in (lMn, rMn, node.val) if val != None) + curBool = lBool and rBool and lVal < node.val < rVal + return curBool, lSize + rSize + 1, curMx, curMn, curBool and lSize + rSize + 1 or max(lTree, rTree) + return dfs(root)[4] \ No newline at end of file diff --git a/solutions/python3/bak/334.py.bak b/solutions/python3/bak/334.py.bak new file mode 100644 index 0000000..e752514 --- /dev/null +++ b/solutions/python3/bak/334.py.bak @@ -0,0 +1,17 @@ +class Solution: + def increasingTriplet(self, nums): + mn = None + for i in range(len(nums)): + if mn == None or nums[i] < mn: + mn = nums[i] + if mn < nums[i]: + nums[i] = [True, nums[i]] + else: + nums[i] = [False, nums[i]] + mn = None + for i in range(len(nums)): + if nums[i][0] and (mn == None or nums[i][1] < mn): + mn = nums[i][1] + elif mn != None and mn < nums[i][1]: + return True + return False \ No newline at end of file diff --git a/solutions/python3/bak/335.py.bak b/solutions/python3/bak/335.py.bak new file mode 100644 index 0000000..3109a57 --- /dev/null +++ b/solutions/python3/bak/335.py.bak @@ -0,0 +1,8 @@ +class Solution: + def isSelfCrossing(self, x: List[int]) -> bool: + b = c = d = e = 0 + for a in x: + if d >= b > 0 and (a >= c or a >= c-e >= 0 and f >= d-b): + return True + b, c, d, e, f = a, b, c, d, e + return False \ No newline at end of file diff --git a/solutions/python3/bak/336.py.bak b/solutions/python3/bak/336.py.bak new file mode 100644 index 0000000..5e5f8b3 --- /dev/null +++ b/solutions/python3/bak/336.py.bak @@ -0,0 +1,15 @@ +class Solution: + def palindromePairs(self, words): + index, res = {w:i for i, w in enumerate(words)}, [] + for i, w in enumerate(words): + for j in range(len(w) + 1): + pre, suf = w[:j], w[j:] + if pre == pre[::-1]: + suf = suf[::-1] + if suf != w and suf in index: + res.append([index[suf], i]) + if j != len(w) and suf == suf[::-1]: + pre = pre[::-1] + if pre != w and pre in index: + res.append([i, index[pre]]) + return res \ No newline at end of file diff --git a/solutions/python3/bak/337.py.bak b/solutions/python3/bak/337.py.bak new file mode 100644 index 0000000..4c74c0d --- /dev/null +++ b/solutions/python3/bak/337.py.bak @@ -0,0 +1,7 @@ +class Solution: + def rob(self, root): + def dfs(node): + if not node: return 0, 0 + l, r = dfs(node.left), dfs(node.right) + return max(l) + max(r), node.val + l[0] + r[0] + return max(dfs(root)) \ No newline at end of file diff --git a/solutions/python3/bak/338.py.bak b/solutions/python3/bak/338.py.bak new file mode 100644 index 0000000..171208b --- /dev/null +++ b/solutions/python3/bak/338.py.bak @@ -0,0 +1,3 @@ +class Solution: + def countBits(self, num: int) -> List[int]: + return [bin(i)[2:].count('1') for i in range(num + 1)] \ No newline at end of file diff --git a/solutions/python3/bak/339.py.bak b/solutions/python3/bak/339.py.bak new file mode 100644 index 0000000..64f084e --- /dev/null +++ b/solutions/python3/bak/339.py.bak @@ -0,0 +1,48 @@ +# """ +# This is the interface that allows for creating nested lists. +# You should not implement it, or speculate about its implementation +# """ +#class NestedInteger: +# def __init__(self, value=None): +# """ +# If value is not specified, initializes an empty list. +# Otherwise initializes a single integer equal to value. +# """ +# +# def isInteger(self): +# """ +# @return True if this NestedInteger holds a single integer, rather than a nested list. +# :rtype bool +# """ +# +# def add(self, elem): +# """ +# Set this NestedInteger to hold a nested list and adds a nested integer elem to it. +# :rtype void +# """ +# +# def setInteger(self, value): +# """ +# Set this NestedInteger to hold a single integer equal to value. +# :rtype void +# """ +# +# def getInteger(self): +# """ +# @return the single integer that this NestedInteger holds, if it holds a single integer +# Return None if this NestedInteger holds a nested list +# :rtype int +# """ +# +# def getList(self): +# """ +# @return the nested list that this NestedInteger holds, if it holds a nested list +# Return None if this NestedInteger holds a single integer +# :rtype List[NestedInteger] +# """ + +class Solution: + def depthSum(self, nestedList): + def dfs(obj, d): return obj.getInteger() * d if obj.isInteger() else sum(dfs(new, d + 1) for new in obj.getList()) + return sum(dfs(item, 1) for item in nestedList) + \ No newline at end of file diff --git a/solutions/python3/bak/34.py.bak b/solutions/python3/bak/34.py.bak new file mode 100644 index 0000000..79e66d5 --- /dev/null +++ b/solutions/python3/bak/34.py.bak @@ -0,0 +1,4 @@ +class Solution(object): + def searchRange(self, nums, target): + l, r = bisect.bisect_left(nums, target), bisect.bisect_right(nums, target) - 1 + return [l, r] if 0 <= l <= r else [-1, -1] \ No newline at end of file diff --git a/solutions/python3/bak/340.py.bak b/solutions/python3/bak/340.py.bak new file mode 100644 index 0000000..42196c9 --- /dev/null +++ b/solutions/python3/bak/340.py.bak @@ -0,0 +1,15 @@ +class Solution: + def lengthOfLongestSubstringKDistinct(self, s: str, k: int) -> int: + if not k: + return 0 + cnt = collections.Counter() + i = res = 0 + for j, c in enumerate(s): + while len(cnt) == k and c not in cnt: + cnt[s[i]] -= 1 + if cnt[s[i]] == 0: + cnt.pop(s[i]) + i += 1 + cnt[c] += 1 + res = max(res, j - i + 1) + return res \ No newline at end of file diff --git a/solutions/python3/bak/342.py.bak b/solutions/python3/bak/342.py.bak new file mode 100644 index 0000000..11901ba --- /dev/null +++ b/solutions/python3/bak/342.py.bak @@ -0,0 +1,9 @@ +class Solution: + def isPowerOfFour(self, num: int) -> bool: + if num < 0: + return False + i = 1 + while i < num: + i = i * 4 + return i == num + \ No newline at end of file diff --git a/solutions/python3/bak/343.py.bak b/solutions/python3/bak/343.py.bak new file mode 100644 index 0000000..99ed253 --- /dev/null +++ b/solutions/python3/bak/343.py.bak @@ -0,0 +1,8 @@ +class Solution: + def integerBreak(self, n): + pre = [0, 1, 1, 2, 4, 6, 9] + if n < 7: + return pre[n] + for i in range(7, n + 1): + pre.append(max(pre[i - 2] * 2, pre[i - 3] * 3)) + return pre[-1] \ No newline at end of file diff --git a/solutions/python3/bak/344.py.bak b/solutions/python3/bak/344.py.bak new file mode 100644 index 0000000..c1859bb --- /dev/null +++ b/solutions/python3/bak/344.py.bak @@ -0,0 +1,7 @@ +class Solution: + def reverseString(self, s: List[str]) -> None: + """ + Do not return anything, modify s in-place instead. + """ + for i in range(len(s) // 2): + s[i], s[-i-1] = s[-i-1], s[i] \ No newline at end of file diff --git a/solutions/python3/bak/345.py.bak b/solutions/python3/bak/345.py.bak new file mode 100644 index 0000000..eb5deb2 --- /dev/null +++ b/solutions/python3/bak/345.py.bak @@ -0,0 +1,4 @@ +class Solution: + def reverseVowels(self, s): + r = [c for c in s if c in "aeiouAEIOU"] + return "".join(c in "aeiouAEIOU" and r.pop() or c for c in s) \ No newline at end of file diff --git a/solutions/python3/bak/346.py.bak b/solutions/python3/bak/346.py.bak new file mode 100644 index 0000000..b4fcdf0 --- /dev/null +++ b/solutions/python3/bak/346.py.bak @@ -0,0 +1,16 @@ +class MovingAverage: + + def __init__(self, size: int): + """ + Initialize your data structure here. + """ + self.arr = collections.deque(maxlen = size) + + def next(self, val: int) -> float: + self.arr.append(val) + return sum(self.arr) / len(self.arr) + + +# Your MovingAverage object will be instantiated and called as such: +# obj = MovingAverage(size) +# param_1 = obj.next(val) \ No newline at end of file diff --git a/solutions/python3/bak/347.py.bak b/solutions/python3/bak/347.py.bak new file mode 100644 index 0000000..8b131af --- /dev/null +++ b/solutions/python3/bak/347.py.bak @@ -0,0 +1,9 @@ +class Solution: + def topKFrequent(self, nums, k): + """ + :type nums: List[int] + :type k: int + :rtype: List[int] + """ + from collections import Counter as ct + return [k for (k,v) in ct(nums).most_common(k)] \ No newline at end of file diff --git a/solutions/python3/bak/348.py.bak b/solutions/python3/bak/348.py.bak new file mode 100644 index 0000000..e304609 --- /dev/null +++ b/solutions/python3/bak/348.py.bak @@ -0,0 +1,21 @@ +class TicTacToe: + + def __init__(self, n): + self.n = n + self.rows, self.cols = collections.defaultdict(int), collections.defaultdict(int) + self.d = self.ad = 0 + + def move(self, row, col, player): + add = player == 1 and 1 or -1 + self.rows[row] += add + self.cols[col] += add + if row == col: + self.d += add + if row == self.n - col - 1: + self.ad += add + if self.rows[row] == self.n or self.cols[col] == self.n or self.d == self.n or self.ad == self.n: + return 1 + elif self.rows[row] == -self.n or self.cols[col] == -self.n or self.d == -self.n or self.ad == -self.n: + return 2 + else: + return 0 \ No newline at end of file diff --git a/solutions/python3/bak/349.py.bak b/solutions/python3/bak/349.py.bak new file mode 100644 index 0000000..52d3bd9 --- /dev/null +++ b/solutions/python3/bak/349.py.bak @@ -0,0 +1,8 @@ +class Solution: + def intersection(self, nums1, nums2): + """ + :type nums1: List[int] + :type nums2: List[int] + :rtype: List[int] + """ + return list(set(nums1)&set(nums2)) \ No newline at end of file diff --git a/solutions/python3/bak/35.py.bak b/solutions/python3/bak/35.py.bak new file mode 100644 index 0000000..51fd153 --- /dev/null +++ b/solutions/python3/bak/35.py.bak @@ -0,0 +1,3 @@ +class Solution: + def searchInsert(self, nums: List[int], target: int) -> int: + return bisect.bisect_left(nums, target) \ No newline at end of file diff --git a/solutions/python3/bak/350.py.bak b/solutions/python3/bak/350.py.bak new file mode 100644 index 0000000..e994d03 --- /dev/null +++ b/solutions/python3/bak/350.py.bak @@ -0,0 +1,2 @@ +class Solution: + intersect = lambda *x: [k for k, v in (collections.Counter(x[1]) & collections.Counter(x[2])).items() for _ in range(v)] \ No newline at end of file diff --git a/solutions/python3/bak/351.py.bak b/solutions/python3/bak/351.py.bak new file mode 100644 index 0000000..893a036 --- /dev/null +++ b/solutions/python3/bak/351.py.bak @@ -0,0 +1,40 @@ +class Solution: + def numberOfPatterns(self, m, n): + q, pattern = [[c] for c in range(1, 10)], 0 + while q: + new = [] + for arr in q: + if m <= len(arr) <= n: + pattern += 1 + if len(arr) < n: + last = arr[-1] + for c in range(1, 10): + if c not in arr: + if last in (1, 4, 7) and c == last + 2: + if last + 1 in arr: + new.append(arr + [c]) + elif last in (3, 6, 9) and c == last - 2: + if last - 1 in arr: + new.append(arr + [c]) + elif last in (1, 2, 3) and c == last + 6: + if last + 3 in arr: + new.append(arr + [c]) + elif last in (7, 8, 9) and c == last - 6: + if last - 3 in arr: + new.append(arr + [c]) + elif last == 1 and c == 9: + if 5 in arr: + new.append(arr + [9]) + elif last == 9 and c == 1: + if 5 in arr: + new.append(arr + [1]) + elif last == 3 and c == 7: + if 5 in arr: + new.append(arr + [7]) + elif last == 7 and c == 3: + if 5 in arr: + new.append(arr + [3]) + else: + new.append(arr + [c]) + q = new + return pattern \ No newline at end of file diff --git a/solutions/python3/bak/352.py.bak b/solutions/python3/bak/352.py.bak new file mode 100644 index 0000000..ebcd0bb --- /dev/null +++ b/solutions/python3/bak/352.py.bak @@ -0,0 +1,22 @@ +class SummaryRanges: + + def __init__(self): + self.starts, self.ends, self.used = [-float("inf"), float("inf")], [-float("inf"), float("inf")], set() + + def addNum(self, val): + if val not in self.used: + self.used.add(val) + i = bisect.bisect_left(self.starts, val) - 1 + if self.ends[i] + 1 == val and val + 1 == self.starts[i + 1]: # if val is the gap btw 2 intervals + del self.starts[i + 1] + del self.ends[i] + elif self.ends[i] + 1 == val: #if val is adjacent to current end + self.ends[i] += 1 + elif self.starts[i + 1] == val + 1: # if val is adjacent to next start + self.starts[i + 1] -= 1 + elif val > self.ends[i]: # if val is independent of those 2 intervals + self.starts.insert(i + 1, val) + self.ends.insert(i + 1, val) + + def getIntervals(self): + return [[s, e] for s, e in zip(self.starts[1:-1], self.ends[1:-1])] #exclude infinity \ No newline at end of file diff --git a/solutions/python3/bak/353.py.bak b/solutions/python3/bak/353.py.bak new file mode 100644 index 0000000..d398575 --- /dev/null +++ b/solutions/python3/bak/353.py.bak @@ -0,0 +1,31 @@ +class SnakeGame: + + def __init__(self, width, height, food): + self.foods = collections.deque(food) + self.i = self.j = 0 + self.w, self.h = width, height + self.score = 0 + self.snake = collections.OrderedDict() + self.snake[(0, 0)] = 1 + + + def move(self, direction): + x, y = self.snake.popitem(last = False) + if direction == "U": + self.i -= 1 + elif direction == "D": + self.i += 1 + elif direction == "R": + self.j += 1 + else: + self.j -= 1 + if 0 <= self.i < self.h and 0 <= self.j < self.w and (self.i, self.j) not in self.snake: + self.snake[(self.i, self.j)] = 1 + if self.foods and self.i == self.foods[0][0] and self.j == self.foods[0][1]: + self.score += 1 + self.foods.popleft() + self.snake[(x, y)] = 1 + self.snake.move_to_end((x, y), last = False) + return self.score + else: + return -1 \ No newline at end of file diff --git a/solutions/python3/bak/354.py.bak b/solutions/python3/bak/354.py.bak new file mode 100644 index 0000000..c17427e --- /dev/null +++ b/solutions/python3/bak/354.py.bak @@ -0,0 +1,8 @@ +class Solution: + def maxEnvelopes(self, envelopes): + tails = [] + for w, h in sorted(envelopes, key = lambda x: (x[0], -x[1])): + i = bisect.bisect_left(tails, h) + if i == len(tails): tails.append(h) + else: tails[i] = h + return len(tails) \ No newline at end of file diff --git a/solutions/python3/bak/355.py.bak b/solutions/python3/bak/355.py.bak new file mode 100644 index 0000000..3a09254 --- /dev/null +++ b/solutions/python3/bak/355.py.bak @@ -0,0 +1,54 @@ +class Twitter: + + def __init__(self): + """ + Initialize your data structure here. + """ + self.tweets = collections.defaultdict(list) + self.following = collections.defaultdict(set) + self.order = 0 + def postTweet(self, userId, tweetId): + """ + Compose a new tweet. + :type userId: int + :type tweetId: int + :rtype: void + """ + self.tweets[userId] += (self.order, tweetId), + self.order -= 1 + + def getNewsFeed(self, userId): + """ + Retrieve the 10 most recent tweet ids in the user's news feed. Each item in the news feed must be posted by users who the user followed or by the user herself. Tweets must be ordered from most recent to least recent. + :type userId: int + :rtype: List[int] + """ + tw = sorted(tw for i in self.following[userId] | {userId} for tw in self.tweets[i])[:10] + return [news for i, news in tw] + + + def follow(self, followerId, followeeId): + """ + Follower follows a followee. If the operation is invalid, it should be a no-op. + :type followerId: int + :type followeeId: int + :rtype: void + """ + self.following[followerId].add(followeeId) + + def unfollow(self, followerId, followeeId): + """ + Follower unfollows a followee. If the operation is invalid, it should be a no-op. + :type followerId: int + :type followeeId: int + :rtype: void + """ + self.following[followerId].discard(followeeId) + + +# Your Twitter object will be instantiated and called as such: +# obj = Twitter() +# obj.postTweet(userId,tweetId) +# param_2 = obj.getNewsFeed(userId) +# obj.follow(followerId,followeeId) +# obj.unfollow(followerId,followeeId) \ No newline at end of file diff --git a/solutions/python3/bak/356.py.bak b/solutions/python3/bak/356.py.bak new file mode 100644 index 0000000..54cbf3a --- /dev/null +++ b/solutions/python3/bak/356.py.bak @@ -0,0 +1,23 @@ +class Solution: + def isReflected(self, points): + if len(points) < 2: + return True + x = (min(x for x, y in points) + max(x for x, y in points)) / 2 + left, right, on = set(), set(), set() + for i, j in points: + if i < x: + left.add((i, j)) + elif i > x: + right.add((i, j)) + else: + on.add((i, j)) + for i, j in points: + if i < x and (2 * x - i, j) in right: + continue + elif i > x and (2 * x - i, j) in left: + continue + elif i == x and (2 * x - i, j) in on: + continue + else: + return False + return True \ No newline at end of file diff --git a/solutions/python3/bak/357.py.bak b/solutions/python3/bak/357.py.bak new file mode 100644 index 0000000..7d74fbb --- /dev/null +++ b/solutions/python3/bak/357.py.bak @@ -0,0 +1,3 @@ +class Solution: + def countNumbersWithUniqueDigits(self, n): + return [1, 10, 91, 739, 5275, 32491, 168571, 712891, 2345851, 5611771, 8877691][n % 11] \ No newline at end of file diff --git a/solutions/python3/bak/358.py.bak b/solutions/python3/bak/358.py.bak new file mode 100644 index 0000000..d6b8375 --- /dev/null +++ b/solutions/python3/bak/358.py.bak @@ -0,0 +1,13 @@ +class Solution: + def rearrangeString(self, s, k): + q, last, res, wq = [(-v, k) for k, v in collections.Counter(s).items()], {}, "", [] + heapq.heapify(q) + for i in range(len(s)): + if wq and (wq[0][1] not in last or last[wq[0][1]] + k <= i): cnt, char = heapq.heappop(wq) + else: + while q and not (q[0][1] not in last or last[q[0][1]] + k <= i): heapq.heappush(wq, heapq.heappop(q)) + if not q: return "" + cnt, char = heapq.heappop(q) + res, cnt, last[char] = res + char, cnt + 1, i + if cnt: heapq.heappush(q, (cnt, char)) + return res \ No newline at end of file diff --git a/solutions/python3/bak/359.py.bak b/solutions/python3/bak/359.py.bak new file mode 100644 index 0000000..b552d77 --- /dev/null +++ b/solutions/python3/bak/359.py.bak @@ -0,0 +1,10 @@ +class Logger: + + def __init__(self): + self.logs = {} + + def shouldPrintMessage(self, timestamp, message): + if message not in self.logs or timestamp - self.logs[message] >= 10: + self.logs[message] = timestamp + return True + return False \ No newline at end of file diff --git a/solutions/python3/bak/36.py.bak b/solutions/python3/bak/36.py.bak new file mode 100644 index 0000000..21e1e95 --- /dev/null +++ b/solutions/python3/bak/36.py.bak @@ -0,0 +1,10 @@ +class Solution: + def isValidSudoku(self, board): + rows, cols, triples = collections.defaultdict(set), collections.defaultdict(set), collections.defaultdict(set) + for i, row in enumerate(board): + for j, c in enumerate(row): + if c != "." and c in rows[i] or c in cols[j] or c in triples[(i //3, j // 3)]: + return False + elif c != ".": + rows[i].add(c); cols[j].add(c); triples[(i // 3, j // 3)].add(c) + return True \ No newline at end of file diff --git a/solutions/python3/bak/360.py.bak b/solutions/python3/bak/360.py.bak new file mode 100644 index 0000000..0028579 --- /dev/null +++ b/solutions/python3/bak/360.py.bak @@ -0,0 +1,16 @@ +class Solution: + def sortTransformedArray(self, nums, a, b, c): + arr, l, r, ind = [0] * len(nums), 0, len(nums) - 1, a >= 0 and len(nums) - 1 or 0 + while l <= r: + n1, n2 = a * nums[l] * nums[l] + b * nums[l] + c, a * nums[r] * nums[r] + b * nums[r] + c + if a >= 0: + if n1 >= n2: l += 1 + else: r -= 1 + arr[ind] = n1 >= n2 and n1 or n2 + ind -= 1 + else: + if n1 < n2: l += 1 + else: r -= 1 + arr[ind] = n1 < n2 and n1 or n2 + ind += 1 + return arr \ No newline at end of file diff --git a/solutions/python3/bak/361.py.bak b/solutions/python3/bak/361.py.bak new file mode 100644 index 0000000..3bb39a7 --- /dev/null +++ b/solutions/python3/bak/361.py.bak @@ -0,0 +1,23 @@ +class Solution: + def maxKilledEnemies(self, grid): + m, n, res = len(grid), len(grid and grid[0]), 0 + dp = [[[0, 0, 0, 0] for j in range(n + 1)] for i in range(m + 1)] + for i in range(m): + for j in range(n): + if grid[i][j] == "0": + dp[i][j][0] = dp[i][j - 1][0] + dp[i][j][1] = dp[i - 1][j][1] + elif grid[i][j] == "E": + dp[i][j][0] = dp[i][j - 1][0] + 1 + dp[i][j][1] = dp[i - 1][j][1] + 1 + for i in range(m - 1, -1, -1): + for j in range(n - 1, -1, -1): + if grid[i][j] == "0": + dp[i][j][2] = dp[i][j + 1][2] + dp[i][j][3] = dp[i + 1][j][3] + elif grid[i][j] == "E": + dp[i][j][2] = dp[i][j + 1][2] + 1 + dp[i][j][3] = dp[i + 1][j][3] + 1 + if grid[i][j] == "0": + res = max(res, sum(dp[i][j])) + return res \ No newline at end of file diff --git a/solutions/python3/bak/362.py.bak b/solutions/python3/bak/362.py.bak new file mode 100644 index 0000000..19b0366 --- /dev/null +++ b/solutions/python3/bak/362.py.bak @@ -0,0 +1,12 @@ +class HitCounter(object): + + def __init__(self): + self.hits = [] + + def hit(self, timestamp): + heapq.heappush(self.hits, timestamp + 300) + + def getHits(self, timestamp): + while self.hits and self.hits[0] <= timestamp: + heapq.heappop(self.hits) + return len(self.hits) \ No newline at end of file diff --git a/solutions/python3/bak/363.py.bak b/solutions/python3/bak/363.py.bak new file mode 100644 index 0000000..37fd5ef --- /dev/null +++ b/solutions/python3/bak/363.py.bak @@ -0,0 +1,14 @@ +class Solution: + def maxSumSubmatrix(self, matrix, k, mxTotal = -float("inf")): + for l in range(len(matrix[0])): + dp = [0] * len(matrix) + for r in range(l, len(matrix[0])): + for i in range(len(matrix)): + dp[i] += matrix[i][r] + sums, cur, mx = [float("inf")], 0, -float("inf") + for sm in dp: + bisect.insort(sums, cur) + cur += sm + mx = max(mx, cur - sums[bisect.bisect_left(sums, cur - k)]) + mxTotal = max(mxTotal, mx) + return mxTotal \ No newline at end of file diff --git a/solutions/python3/bak/364.py.bak b/solutions/python3/bak/364.py.bak new file mode 100644 index 0000000..e47976e --- /dev/null +++ b/solutions/python3/bak/364.py.bak @@ -0,0 +1,51 @@ +# """ +# This is the interface that allows for creating nested lists. +# You should not implement it, or speculate about its implementation +# """ +#class NestedInteger: +# def __init__(self, value=None): +# """ +# If value is not specified, initializes an empty list. +# Otherwise initializes a single integer equal to value. +# """ +# +# def isInteger(self): +# """ +# @return True if this NestedInteger holds a single integer, rather than a nested list. +# :rtype bool +# """ +# +# def add(self, elem): +# """ +# Set this NestedInteger to hold a nested list and adds a nested integer elem to it. +# :rtype void +# """ +# +# def setInteger(self, value): +# """ +# Set this NestedInteger to hold a single integer equal to value. +# :rtype void +# """ +# +# def getInteger(self): +# """ +# @return the single integer that this NestedInteger holds, if it holds a single integer +# Return None if this NestedInteger holds a nested list +# :rtype int +# """ +# +# def getList(self): +# """ +# @return the nested list that this NestedInteger holds, if it holds a nested list +# Return None if this NestedInteger holds a single integer +# :rtype List[NestedInteger] +# """ + +class Solution: + def depthSumInverse(self, nestedList): + def dfs(obj, d): + return obj.isInteger() and d or max((dfs(item, d + 1) for item in obj.getList()), default = 0) + def dfs2(obj, d): + return obj.isInteger() and d * obj.getInteger() or sum(dfs2(item, d - 1) for item in obj.getList()) + mx = max((dfs(item, 1) for item in nestedList), default = 0) + return mx and sum(dfs2(item, mx) for item in nestedList) or 0 \ No newline at end of file diff --git a/solutions/python3/bak/365.py.bak b/solutions/python3/bak/365.py.bak new file mode 100644 index 0000000..e281966 --- /dev/null +++ b/solutions/python3/bak/365.py.bak @@ -0,0 +1,7 @@ +class Solution: + def canMeasureWater(self, x, y, z): + def gcd(x, y): + for i in range(min(x, y), -1, -1): + if not x % i and not y % i: return i + div = gcd(x, y) if x * y else 0 + return not z % div and z <= x + y if div else not z \ No newline at end of file diff --git a/solutions/python3/bak/366.py.bak b/solutions/python3/bak/366.py.bak new file mode 100644 index 0000000..cde94d9 --- /dev/null +++ b/solutions/python3/bak/366.py.bak @@ -0,0 +1,18 @@ +# Definition for a binary tree node. +# class TreeNode: +# def __init__(self, x): +# self.val = x +# self.left = None +# self.right = None + +class Solution: + def findLeaves(self, root): + res = [] + def dfs(node): + if not node: return -1 + i = max(dfs(node.left), dfs(node.right)) + 1 + try: res[i].append(node.val) + except: res.append([node.val]) + return i + dfs(root) + return res \ No newline at end of file diff --git a/solutions/python3/bak/367.py.bak b/solutions/python3/bak/367.py.bak new file mode 100644 index 0000000..af033d7 --- /dev/null +++ b/solutions/python3/bak/367.py.bak @@ -0,0 +1,11 @@ +class Solution: + def isPerfectSquare(self, num): + """ + :type num: int + :rtype: bool + """ + i=1 + while i**2<=num: + if i**2= len(dp[j]): + dp[j] = dp[i] + dp[j][-1:] + return dp and sorted(dp, key = len)[-1] \ No newline at end of file diff --git a/solutions/python3/bak/369.py.bak b/solutions/python3/bak/369.py.bak new file mode 100644 index 0000000..7949098 --- /dev/null +++ b/solutions/python3/bak/369.py.bak @@ -0,0 +1,25 @@ +# Definition for singly-linked list. +# class ListNode: +# def __init__(self, x): +# self.val = x +# self.next = None + +class Solution: + def plusOne(self, head): + """ + :type head: ListNode + :rtype: ListNode + """ + def dfs(node): + if not node.next or dfs(node.next): + if node.val + 1 > 9: + node.val = 0 + return True + else: + node.val += 1 + return False + if dfs(head): + dummy = ListNode(1) + dummy.next = head + return dummy + return head \ No newline at end of file diff --git a/solutions/python3/bak/37.py.bak b/solutions/python3/bak/37.py.bak new file mode 100644 index 0000000..f2a168c --- /dev/null +++ b/solutions/python3/bak/37.py.bak @@ -0,0 +1,33 @@ +class Solution: + def solveSudoku(self, board): + rows, cols, triples, visit = collections.defaultdict(set), collections.defaultdict(set), collections.defaultdict(set), collections.deque([]) + for r in range(9): + for c in range(9): + if board[r][c] != ".": + rows[r].add(board[r][c]) + cols[c].add(board[r][c]) + triples[(r // 3, c // 3)].add(board[r][c]) + else: + visit.append((r, c)) + def dfs(): + if not visit: + return True + r, c = visit[0] + t = (r // 3, c // 3) + for dig in {"1", "2", "3", "4", "5", "6", "7", "8", "9"}: + if dig not in rows[r] and dig not in cols[c] and dig not in triples[t]: + board[r][c] = dig + rows[r].add(dig) + cols[c].add(dig) + triples[t].add(dig) + visit.popleft() + if dfs(): + return True + else: + board[r][c] = "." + rows[r].discard(dig) + cols[c].discard(dig) + triples[t].discard(dig) + visit.appendleft((r, c)) + return False + dfs() \ No newline at end of file diff --git a/solutions/python3/bak/370.py.bak b/solutions/python3/bak/370.py.bak new file mode 100644 index 0000000..5cdabb0 --- /dev/null +++ b/solutions/python3/bak/370.py.bak @@ -0,0 +1,13 @@ +class Solution: + def getModifiedArray(self, length, updates): + start, end, res, cur = collections.defaultdict(int), collections.defaultdict(int), [0] * length, 0 + for s, e, inc in updates: + start[s] += inc + end[e] += -inc + for i in range(length): + if start[i]: + cur += start[i] + res[i] += cur + if end[i]: + cur += end[i] + return res \ No newline at end of file diff --git a/solutions/python3/bak/371.py.bak b/solutions/python3/bak/371.py.bak new file mode 100644 index 0000000..4de2603 --- /dev/null +++ b/solutions/python3/bak/371.py.bak @@ -0,0 +1,11 @@ +class Solution: + def getSum(self, a, b): + """ + :type a: int + :type b: int + :rtype: int + """ + mx, mask = 0x7FFFFFFF, 0xFFFFFFFF + while b: + a, b = (a ^ b) & mask, ((a & b) << 1) & mask + return a if a <= mx else ~(a ^ mask) \ No newline at end of file diff --git a/solutions/python3/bak/372.py.bak b/solutions/python3/bak/372.py.bak new file mode 100644 index 0000000..787f754 --- /dev/null +++ b/solutions/python3/bak/372.py.bak @@ -0,0 +1,3 @@ +class Solution: + def superPow(self, a, b): + return pow(a, int(''.join(map(str, b))), 1337) \ No newline at end of file diff --git a/solutions/python3/bak/373.py.bak b/solutions/python3/bak/373.py.bak new file mode 100644 index 0000000..a06e1fb --- /dev/null +++ b/solutions/python3/bak/373.py.bak @@ -0,0 +1,10 @@ +class Solution: + def kSmallestPairs(self, nums1, nums2, k): + if not nums1 or not nums2: return [] + n, res, cnt, heap = len(nums2), [], 0, [(nums1[i] + nums2[0], i, 0) for i in range(len(nums1))] + while heap and cnt < k: + cnt += 1 + sm, i, j = heapq.heappop(heap) + res.append([nums1[i], nums2[j]]) + if j + 1 < n: heapq.heappush(heap, (nums1[i] + nums2[j + 1], i, j + 1)) + return res \ No newline at end of file diff --git a/solutions/python3/bak/375.py.bak b/solutions/python3/bak/375.py.bak new file mode 100644 index 0000000..9fb1547 --- /dev/null +++ b/solutions/python3/bak/375.py.bak @@ -0,0 +1,8 @@ +class Solution: + def getMoneyAmount(self, n): + dic = {} + def dfs(l, r): + if l >=r: return 0 + if (l, r) not in dic: dic[(l, r)] = min(num + max(dfs(l, num - 1), dfs(num + 1, r)) for num in range(l, r)) + return dic[(l, r)] + return dfs(1, n) \ No newline at end of file diff --git a/solutions/python3/bak/376.py.bak b/solutions/python3/bak/376.py.bak new file mode 100644 index 0000000..37892b7 --- /dev/null +++ b/solutions/python3/bak/376.py.bak @@ -0,0 +1,10 @@ +class Solution: + def wiggleMaxLength(self, nums): + if len(nums) <= 2: return 0 if not nums else 1 if nums[0] == nums[-1] else 2 + inc = nums[0] < nums[1] if nums[0] != nums[1] else None + cnt = 2 if inc != None else 1 + for i in range(2, len(nums)): + if nums[i - 1] != nums[i] and (inc == None or inc != (nums[i - 1] < nums[i])): + inc = nums[i - 1] < nums[i] + cnt += 1 + return cnt \ No newline at end of file diff --git a/solutions/python3/bak/377.py.bak b/solutions/python3/bak/377.py.bak new file mode 100644 index 0000000..0ba33bb --- /dev/null +++ b/solutions/python3/bak/377.py.bak @@ -0,0 +1,16 @@ +class Solution: + def combinationSum4(self, nums, target): + memo = {} + def dfs(sm): + if sm in memo: + return memo[sm] + else: + if sm >= target: + memo[sm] = sm == target + return memo[sm] + cnt = 0 + for num in nums: + memo[sm + num] = dfs(sm + num) + cnt += memo[sm + num] + return cnt + return dfs(0) \ No newline at end of file diff --git a/solutions/python3/bak/378.py.bak b/solutions/python3/bak/378.py.bak new file mode 100644 index 0000000..0f86934 --- /dev/null +++ b/solutions/python3/bak/378.py.bak @@ -0,0 +1,3 @@ +class Solution: + def kthSmallest(self, matrix, k): + return sorted(itertools.chain(*matrix))[k - 1] \ No newline at end of file diff --git a/solutions/python3/bak/379.py.bak b/solutions/python3/bak/379.py.bak new file mode 100644 index 0000000..bc1fc5d --- /dev/null +++ b/solutions/python3/bak/379.py.bak @@ -0,0 +1,13 @@ +class PhoneDirectory: + + def __init__(self, maxNumbers): + self.nums = set(range(maxNumbers)) + + def get(self): + return self.nums.pop() if self.nums else -1 + + def check(self, number): + return number in self.nums + + def release(self, number): + self.nums.add(number) \ No newline at end of file diff --git a/solutions/python3/bak/38.py.bak b/solutions/python3/bak/38.py.bak new file mode 100644 index 0000000..4243a57 --- /dev/null +++ b/solutions/python3/bak/38.py.bak @@ -0,0 +1,15 @@ +class Solution: + def countAndSay(self, n): + curr = "1" + for i in range(n - 1): + tmp, cnt = "", 1 + for j, c in enumerate(curr): + if j > 0 and curr[j - 1] == c: + cnt += 1 + elif j > 0: + tmp += str(cnt) + curr[j - 1] + cnt = 1 + if j == len(curr) - 1: + tmp += str(cnt) + curr[j] + curr = tmp + return curr \ No newline at end of file diff --git a/solutions/python3/bak/380.py.bak b/solutions/python3/bak/380.py.bak new file mode 100644 index 0000000..9aaf65b --- /dev/null +++ b/solutions/python3/bak/380.py.bak @@ -0,0 +1,45 @@ +class RandomizedSet: + + def __init__(self): + """ + Initialize your data structure here. + """ + self.nums, self.ind = [], {} + def insert(self, val): + """ + Inserts a value to the set. Returns true if the set did not already contain the specified element. + :type val: int + :rtype: bool + """ + if val not in self.ind: + self.nums += val, + self.ind[val] = len(self.nums) - 1 + return True + return False + + def remove(self, val): + """ + Removes a value from the set. Returns true if the set contained the specified element. + :type val: int + :rtype: bool + """ + if val in self.ind: + ind, last = self.ind[val], self.nums[-1] + self.nums[ind], self.ind[last] = last, ind + self.nums.pop() + self.ind.pop(val) + return True + return False + + def getRandom(self): + """ + Get a random element from the set. + :rtype: int + """ + return random.choice(self.nums) + +# Your RandomizedSet object will be instantiated and called as such: +# obj = RandomizedSet() +# param_1 = obj.insert(val) +# param_2 = obj.remove(val) +# param_3 = obj.getRandom() \ No newline at end of file diff --git a/solutions/python3/bak/381.py.bak b/solutions/python3/bak/381.py.bak new file mode 100644 index 0000000..0591e83 --- /dev/null +++ b/solutions/python3/bak/381.py.bak @@ -0,0 +1,27 @@ +class RandomizedCollection: + + def __init__(self): + self.arr, self.pos = [], collections.defaultdict(set) + def insert(self, val): + out = val not in self.pos + self.arr.append(val) + self.pos[val].add(len(self.arr) - 1) + return out + + def remove(self, val): + if val in self.pos: + if self.arr[-1] != val: + x, y = self.pos[val].pop(), self.arr[-1] + self.pos[y].discard(len(self.arr) - 1) + self.pos[y].add(x) + self.arr[x] = y + else: + self.pos[val].discard(len(self.arr) - 1) + self.arr.pop() + if not self.pos[val]: + self.pos.pop(val) + return True + return False + + def getRandom(self): + return random.choice(self.arr) \ No newline at end of file diff --git a/solutions/python3/bak/382.py.bak b/solutions/python3/bak/382.py.bak new file mode 100644 index 0000000..b2568ac --- /dev/null +++ b/solutions/python3/bak/382.py.bak @@ -0,0 +1,16 @@ +# Definition for singly-linked list. +# class ListNode: +# def __init__(self, x): +# self.val = x +# self.next = None + +class Solution: + + def __init__(self, head): + self.arr = [] + while head: + self.arr.append(head.val) + head = head.next + + def getRandom(self): + return random.choice(self.arr) \ No newline at end of file diff --git a/solutions/python3/bak/383.py.bak b/solutions/python3/bak/383.py.bak new file mode 100644 index 0000000..24da446 --- /dev/null +++ b/solutions/python3/bak/383.py.bak @@ -0,0 +1,9 @@ +class Solution: + def canConstruct(self, ransomNote: str, magazine: str) -> bool: + cnt = collections.Counter(magazine) + for c in ransomNote: + if cnt[c]: + cnt[c] -= 1 + else: + return False + return True \ No newline at end of file diff --git a/solutions/python3/bak/384.py.bak b/solutions/python3/bak/384.py.bak new file mode 100644 index 0000000..3f9669a --- /dev/null +++ b/solutions/python3/bak/384.py.bak @@ -0,0 +1,25 @@ +class Solution: + + def __init__(self, nums: List[int]): + self.arr = nums + self.org = nums[:] + + def reset(self) -> List[int]: + """ + Resets the array to its original configuration and return it. + """ + self.arr = self.org[:] + return self.arr + + def shuffle(self) -> List[int]: + """ + Returns a random shuffling of the array. + """ + random.shuffle(self.arr) + return self.arr + + +# Your Solution object will be instantiated and called as such: +# obj = Solution(nums) +# param_1 = obj.reset() +# param_2 = obj.shuffle() \ No newline at end of file diff --git a/solutions/python3/bak/385.py.bak b/solutions/python3/bak/385.py.bak new file mode 100644 index 0000000..710d4be --- /dev/null +++ b/solutions/python3/bak/385.py.bak @@ -0,0 +1,18 @@ +class Solution: + def deserialize(self, s): + stack, num, last = [], "", None + for c in s: + if c.isdigit() or c == "-": num += c + elif c == "," and num: + stack[-1].add(NestedInteger(int(num))) + num = "" + elif c == "[": + elem = NestedInteger() + if stack: stack[-1].add(elem) + stack.append(elem) + elif c == "]": + if num: + stack[-1].add(NestedInteger(int(num))) + num = "" + last = stack.pop() + return last if last else NestedInteger(int(num)) \ No newline at end of file diff --git a/solutions/python3/bak/386.py.bak b/solutions/python3/bak/386.py.bak new file mode 100644 index 0000000..1617a1e --- /dev/null +++ b/solutions/python3/bak/386.py.bak @@ -0,0 +1,2 @@ +class Solution: + def lexicalOrder(self, n): return sorted(range(1, n + 1), key = str) \ No newline at end of file diff --git a/solutions/python3/bak/387.py.bak b/solutions/python3/bak/387.py.bak new file mode 100644 index 0000000..6e181d2 --- /dev/null +++ b/solutions/python3/bak/387.py.bak @@ -0,0 +1,12 @@ +class Solution: + def firstUniqChar(self, s): + """ + :type s: str + :rtype: int + """ + dic = collections.defaultdict(int) + for c in s: + dic[c] += 1 + for i, c in enumerate(s): + if dic[c] == 1: return i + return -1 \ No newline at end of file diff --git a/solutions/python3/bak/388.py.bak b/solutions/python3/bak/388.py.bak new file mode 100644 index 0000000..850621d --- /dev/null +++ b/solutions/python3/bak/388.py.bak @@ -0,0 +1,12 @@ +class Solution: + def lengthLongestPath(self, input: str) -> int: + maxlen = 0 + pathlen = {0: 0} + for line in input.splitlines(): + name = line.lstrip('\u005Ct') + depth = len(line) - len(name) + if '.' in name: + maxlen = max(maxlen, pathlen[depth] + len(name)) + else: + pathlen[depth + 1] = pathlen[depth] + len(name) + 1 + return maxlen \ No newline at end of file diff --git a/solutions/python3/bak/389.py.bak b/solutions/python3/bak/389.py.bak new file mode 100644 index 0000000..ad55b1f --- /dev/null +++ b/solutions/python3/bak/389.py.bak @@ -0,0 +1,3 @@ +class Solution: + def findTheDifference(self, s, t): + return next(iter(collections.Counter(t) - collections.Counter(s))) \ No newline at end of file diff --git a/solutions/python3/bak/39.py.bak b/solutions/python3/bak/39.py.bak new file mode 100644 index 0000000..a48133f --- /dev/null +++ b/solutions/python3/bak/39.py.bak @@ -0,0 +1,11 @@ +class Solution: + def combinationSum(self, c, t): + res, stack, n = [], [(0, [], 0)], len(c) + while stack: + sm, tmp, r = stack.pop() + for i in range(r, n): + if sm + c[i] < t: + stack.append((sm + c[i], tmp + [c[i]], i)) + elif sm + c[i] == t: + res.append(tmp + [c[i]]) + return res \ No newline at end of file diff --git a/solutions/python3/bak/390.py.bak b/solutions/python3/bak/390.py.bak new file mode 100644 index 0000000..22f4242 --- /dev/null +++ b/solutions/python3/bak/390.py.bak @@ -0,0 +1,9 @@ +class Solution: + def lastRemaining(self, n): + head, left, step, remaining = 1, 1, 1, n + while remaining > 1: + if left or remaining % 2: head += step + left = 1 - left + step *= 2 + remaining //= 2 + return head \ No newline at end of file diff --git a/solutions/python3/bak/391.py.bak b/solutions/python3/bak/391.py.bak new file mode 100644 index 0000000..b5cbbf7 --- /dev/null +++ b/solutions/python3/bak/391.py.bak @@ -0,0 +1,13 @@ +class Solution: + def isRectangleCover(self, rectangles): + cnt = collections.Counter() + for x1, y1, x2, y2 in rectangles: + cnt[(x1, y1)] += 1 + cnt[(x1, y2)] += 1 + cnt[(x2, y2)] += 1 + cnt[(x2, y1)] += 1 + x1, y1, x2, y2 = min([r[:2] for r in rectangles]) + max(r[-2:] for r in rectangles) + for x, y in ((x1, y1), (x1, y2), (x2, y2), (x2, y1)): + if cnt[(x, y)] != 1: return False + cnt.pop((x, y)) + return all(cnt[k] in (2, 4) for k in cnt) and sum((x2 - x1) * (y2 - y1) for x1, y1, x2, y2 in rectangles) == (x2 - x1) * (y2 - y1) \ No newline at end of file diff --git a/solutions/python3/bak/392.py.bak b/solutions/python3/bak/392.py.bak new file mode 100644 index 0000000..3ff6082 --- /dev/null +++ b/solutions/python3/bak/392.py.bak @@ -0,0 +1,7 @@ +class Solution: + def isSubsequence(self, s, t): + ind = -1 + for i in s: + try: ind = t.index(i, ind + 1) + except: return False + return True \ No newline at end of file diff --git a/solutions/python3/bak/393.py.bak b/solutions/python3/bak/393.py.bak new file mode 100644 index 0000000..247e2c7 --- /dev/null +++ b/solutions/python3/bak/393.py.bak @@ -0,0 +1,27 @@ +class Solution: + def validUtf8(self, data: List[int]) -> bool: + def rest(i): + if len(data) < i: + return False + for _ in range(i): + if not data.pop().startswith("10"): + return False + return True + + data, byte = [str(bin(seq)[2:].zfill(8)) for seq in data[::-1]], None + while data: + seq = data.pop() + if seq.startswith("0"): + continue + elif seq.startswith("110"): + if not rest(1): + return False + elif seq.startswith("1110"): + if not rest(2): + return False + elif seq.startswith("11110"): + if not rest(3): + return False + else: + return False + return True diff --git a/solutions/python3/bak/394.py.bak b/solutions/python3/bak/394.py.bak new file mode 100644 index 0000000..7bc9ab6 --- /dev/null +++ b/solutions/python3/bak/394.py.bak @@ -0,0 +1,14 @@ +class Solution: + def decodeString(self, s): + stack, num, string = [], 0, "" + for c in s: + if c == "[": + stack += string, + stack += num, + num, string = 0, "" + elif c == "]": + pre_num, pre_string = stack.pop(), stack.pop() + string = pre_string + pre_num * string + elif c.isdigit(): num = num * 10 + int(c) + else: string += c + return string \ No newline at end of file diff --git a/solutions/python3/bak/395.py.bak b/solutions/python3/bak/395.py.bak new file mode 100644 index 0000000..a6b4640 --- /dev/null +++ b/solutions/python3/bak/395.py.bak @@ -0,0 +1,4 @@ +class Solution: + def longestSubstring(self, s, k): + br = [-1] + [i for i, c in enumerate(s) if s.count(c) < k] + [len(s)] + return len(s) if len(br) == 2 else max(self.longestSubstring(s[br[i - 1] + 1:br[i]], k) for i in range(1, len(br))) \ No newline at end of file diff --git a/solutions/python3/bak/396.py.bak b/solutions/python3/bak/396.py.bak new file mode 100644 index 0000000..91c28ce --- /dev/null +++ b/solutions/python3/bak/396.py.bak @@ -0,0 +1,14 @@ +class Solution: + def maxRotateFunction(self, A): + """ + :type A: List[int] + :rtype: int + """ + mx, sm = 0, sum(A) + for i in range(len(A)): + mx += i * A[i] + curr = mx + for i in range(1, len(A)): + curr = curr - sm + A[i - 1] * len(A) + mx = max(mx, curr) + return mx \ No newline at end of file diff --git a/solutions/python3/bak/397.py.bak b/solutions/python3/bak/397.py.bak new file mode 100644 index 0000000..8171723 --- /dev/null +++ b/solutions/python3/bak/397.py.bak @@ -0,0 +1,12 @@ +class Solution: + def integerReplacement(self, n): + """ + :type n: int + :rtype: int + """ + if n == 1: + return 0 + elif n % 2 == 0: + return self.integerReplacement(n/2)+1 + else: + return min(self.integerReplacement(n+1),self.integerReplacement(n-1))+1 \ No newline at end of file diff --git a/solutions/python3/bak/398.py.bak b/solutions/python3/bak/398.py.bak new file mode 100644 index 0000000..ca790a4 --- /dev/null +++ b/solutions/python3/bak/398.py.bak @@ -0,0 +1,9 @@ +class Solution: + + def __init__(self, nums): + self.indexes = collections.defaultdict(set) + for i, num in enumerate(nums): + self.indexes[num].add(i) + + def pick(self, target): + return random.sample(self.indexes[target], 1)[0] \ No newline at end of file diff --git a/solutions/python3/bak/399.py.bak b/solutions/python3/bak/399.py.bak new file mode 100644 index 0000000..dd17a98 --- /dev/null +++ b/solutions/python3/bak/399.py.bak @@ -0,0 +1,22 @@ +class Solution: + def calcEquation(self, equations, values, queries): + def explore(x, y, r, q): + results[(x, y)] = r + for z in edges[y]: + if z not in q: + results[(x, z)], results[(z, x)] = r * vals[(y, z)], 1 / (r * vals[(y, z)]) + explore(x, z, r * vals[(y, z)], q | {z}) + edges, vals, visited, results, res = collections.defaultdict(set), {}, set(), {}, [] + for i, eq in enumerate(equations): + edges[eq[0]].add(eq[1]) + edges[eq[1]].add(eq[0]) + vals[(eq[0], eq[1])], vals[(eq[1], eq[0])] = values[i], 1 / values[i] + for i, eq in enumerate(equations): + for p in eq: + if p not in visited: + visited.add(p) + explore(p, p, 1.0, {p}) + for q in queries: + if (q[0], q[1]) in results: res += results[(q[0], q[1])], + else: res += -1.0, + return res \ No newline at end of file diff --git a/solutions/python3/bak/4.py.bak b/solutions/python3/bak/4.py.bak new file mode 100644 index 0000000..ee99f9e --- /dev/null +++ b/solutions/python3/bak/4.py.bak @@ -0,0 +1,5 @@ +class Solution: + def findMedianSortedArrays(self, nums1, nums2): + arr = sorted(nums1 + nums2) + if len(arr) % 2 == 0: return (arr[len(arr) // 2] + arr[len(arr) // 2 - 1]) / 2 + else: return arr[len(arr) // 2] \ No newline at end of file diff --git a/solutions/python3/bak/40.py.bak b/solutions/python3/bak/40.py.bak new file mode 100644 index 0000000..6e2f167 --- /dev/null +++ b/solutions/python3/bak/40.py.bak @@ -0,0 +1,15 @@ +class Solution: + def combinationSum2(self, candidates, target): + res = [] + self.dfs(sorted(candidates), target, 0, [], res) + return res + def dfs(self, nums, target, index, path, res): + if target < 0: + return + if target == 0 and path not in res: + res.append(path) + return + for i in range(index, len(nums)): + if i>1 and nums[i] == nums[i-1]: + continue + self.dfs(nums[:i] + nums[i+1:], target-nums[i], i, path+[nums[i]], res) \ No newline at end of file diff --git a/solutions/python3/bak/401.py.bak b/solutions/python3/bak/401.py.bak new file mode 100644 index 0000000..f6bbd17 --- /dev/null +++ b/solutions/python3/bak/401.py.bak @@ -0,0 +1,9 @@ +class Solution: + def readBinaryWatch(self, num): + """ + :type num: int + :rtype: List[str] + """ + return ['%d:%02d' % (h, m) + for h in range(12) for m in range(60) + if (bin(h) + bin(m)).count('1') == num] \ No newline at end of file diff --git a/solutions/python3/bak/402.py.bak b/solutions/python3/bak/402.py.bak new file mode 100644 index 0000000..f3c9668 --- /dev/null +++ b/solutions/python3/bak/402.py.bak @@ -0,0 +1,9 @@ +class Solution: + def removeKdigits(self, num, k): + out = [] + for digit in num: + while k and out and out[-1] > digit: + out.pop() + k -= 1 + out.append(digit) + return ''.join(out[:-k or None]).lstrip('0') or "0" \ No newline at end of file diff --git a/solutions/python3/bak/403.py.bak b/solutions/python3/bak/403.py.bak new file mode 100644 index 0000000..042349c --- /dev/null +++ b/solutions/python3/bak/403.py.bak @@ -0,0 +1,9 @@ +class Solution: + def canCross(self, stones): + memo, stones, target = {}, set(stones), stones[-1] + def dfs(unit, last): + if unit == target: return True + if (unit, last) not in memo: + memo[(unit, last)] = any(dfs(unit + move, move) for move in (last - 1, last, last + 1) if move and unit + move in stones) + return memo[(unit, last)] + return dfs(1, 1) if 1 in stones else False \ No newline at end of file diff --git a/solutions/python3/bak/404.py.bak b/solutions/python3/bak/404.py.bak new file mode 100644 index 0000000..2778f53 --- /dev/null +++ b/solutions/python3/bak/404.py.bak @@ -0,0 +1,22 @@ +# Definition for a binary tree node. +# class TreeNode: +# def __init__(self, x): +# self.val = x +# self.left = None +# self.right = None + +class Solution: + def sumOfLeftLeaves(self, root): + """ + :type root: TreeNode + :rtype: int + """ + def left(node, sm): + if not node: return + left(node.left,sm) + if node.left: + if not node.left.left and not node.left.right: sm.append(node.left.val) + left(node.right,sm) + otp=list() + left(root,otp) + return sum(otp) \ No newline at end of file diff --git a/solutions/python3/bak/405.py.bak b/solutions/python3/bak/405.py.bak new file mode 100644 index 0000000..66e2027 --- /dev/null +++ b/solutions/python3/bak/405.py.bak @@ -0,0 +1,10 @@ +class Solution: + def toHex(self, num): + if not num: return "0" + mp, ans = "0123456789abcdef", "" + for i in range(8): + n = num & 15 + c = mp[n] + ans = c + ans + num = num >> 4 + return ans.lstrip('0') \ No newline at end of file diff --git a/solutions/python3/bak/406.py.bak b/solutions/python3/bak/406.py.bak new file mode 100644 index 0000000..a55fb5d --- /dev/null +++ b/solutions/python3/bak/406.py.bak @@ -0,0 +1,12 @@ +class Solution: + def reconstructQueue(self, people): + arr = [0] * len(people) + people.sort() + for h, k in people: + cnt = 0 + for i in range(len(arr)): + if not arr[i] or arr[i][0] == h: + cnt += 1 + if cnt == k + 1: + arr[i] = [h, k] + return arr \ No newline at end of file diff --git a/solutions/python3/bak/407.py.bak b/solutions/python3/bak/407.py.bak new file mode 100644 index 0000000..36912b1 --- /dev/null +++ b/solutions/python3/bak/407.py.bak @@ -0,0 +1,16 @@ +class Solution: + def trapRainWater(self, heightMap): + m, n, heap, trapped = len(heightMap), len(heightMap and heightMap[0]), [], 0 + for i in range(m): + for j in range(n): + if i in {0, m - 1} or j in {0, n - 1}: + heapq.heappush(heap, (heightMap[i][j], i, j)) + heightMap[i][j] = -1 + while heap: + h, i, j = heapq.heappop(heap) + for x, y in ((i + 1, j), (i - 1, j), (i, j + 1), (i, j - 1)): + if 0 < x < m - 1 and 0 < y < n - 1 and heightMap[x][y] != -1: + trapped += max(h - heightMap[x][y], 0) + heapq.heappush(heap, (max(heightMap[x][y], h), x, y)) + heightMap[x][y] = -1 + return trapped \ No newline at end of file diff --git a/solutions/python3/bak/408.py.bak b/solutions/python3/bak/408.py.bak new file mode 100644 index 0000000..f9e941e --- /dev/null +++ b/solutions/python3/bak/408.py.bak @@ -0,0 +1,18 @@ +class Solution: + def validWordAbbreviation(self, word: str, abbr: str) -> bool: + i = num = 0 + for c in abbr: + if c.isdigit(): + if num == 0 and c == '0': + return False + num = num * 10 + int(c) + else: + if num: + #print(i, num) + i += num + num = 0 + if i >= len(word) or word[i] != c: + #print(i, c) + return False + i += 1 + return i == len(word) if num == 0 else i + num == len(word) \ No newline at end of file diff --git a/solutions/python3/bak/409.py.bak b/solutions/python3/bak/409.py.bak new file mode 100644 index 0000000..b215f40 --- /dev/null +++ b/solutions/python3/bak/409.py.bak @@ -0,0 +1,15 @@ +class Solution: + def longestPalindrome(self, s): + """ + :type s: str + :rtype: int + """ + from collections import Counter + out=even=sum(v for k,v in Counter(s).items() if v%2==0) + odd_big=[v for k,v in Counter(s).items() if v%2!=0 and v>1] + odd_small=[v for k,v in Counter(s).items() if v==1] + if len(odd_big)==1: out+=odd_big[0] + else: + out+=sum(odd_big)-len(odd_big)+1 + if len(odd_small)==0 and len(odd_big)==0: out-=1 + return out \ No newline at end of file diff --git a/solutions/python3/bak/41.py.bak b/solutions/python3/bak/41.py.bak new file mode 100644 index 0000000..f170aac --- /dev/null +++ b/solutions/python3/bak/41.py.bak @@ -0,0 +1,6 @@ +class Solution: + def firstMissingPositive(self, nums: List[int], res: int = 1) -> int: + for num in sorted(nums): + res += num == res + return res + \ No newline at end of file diff --git a/solutions/python3/bak/410.py.bak b/solutions/python3/bak/410.py.bak new file mode 100644 index 0000000..ed71dd1 --- /dev/null +++ b/solutions/python3/bak/410.py.bak @@ -0,0 +1,19 @@ +class Solution: + def splitArray(self, nums, m): + def valid(mid): + cnt = sm = 0 + for num in nums: + sm += num + if sm > mid: + cnt += 1 + if cnt>= m: return False + sm = num + return True + l, h = max(nums), sum(nums) + while l < h: + mid = (l + h) // 2 + if valid(mid): + h = mid + else: + l = mid + 1 + return l \ No newline at end of file diff --git a/solutions/python3/bak/411.py.bak b/solutions/python3/bak/411.py.bak new file mode 100644 index 0000000..2c5cd04 --- /dev/null +++ b/solutions/python3/bak/411.py.bak @@ -0,0 +1,77 @@ +class Solution(object): + def extract_number(self, j, abbr, M): + num = 0 + while j < M and abbr[j].isdigit(): + num, j = num*10 + int(abbr[j]), j+1 + return num, j + + def valid(self, word, abbr): + i,j,N, M = 0,0,len(word), len(abbr) + while i < N and j < M: + if abbr[j].isalpha() and abbr[j] != word[i]: + return False + elif abbr[j].isalpha() and abbr[j] == word[i]: + i,j = i+1,j+1 + elif abbr[j].isdigit(): + if abbr[j] == '0': + return False + num, j = self.extract_number(j, abbr, M) + i = i+num + return (i==N and j == M) + + def process_solution(self, so_far): + csofar, i, cnt = [], 0, 0 + while i < len(so_far): + if so_far[i].isalpha(): + csofar.append(so_far[i]) + i, cnt = i+1, cnt+1 + else: + num = 0 + while i < len(so_far) and so_far[i].isdigit(): + num, i = num+1, i+1 + cnt = cnt + 1 + csofar.append(str(num)) + return "".join(csofar), cnt + + def test(self, abbr, dictionary): + for wrd in dictionary: + if self.valid(wrd, abbr): + return False + return True + + def helper(self, word, so_far, i, dictionary): + if i == len(word): + abbr, cnt = self.process_solution(so_far) + if cnt < self.result_len and self.test(abbr, dictionary): + self.result, self.result_len = abbr, cnt + return + else: + so_far.append("1") + self.helper(word, so_far, i+1, dictionary) + so_far.pop() + so_far.append(word[i]) + self.helper(word, so_far, i+1, dictionary) + so_far.pop() + + def minAbbreviation(self, target, dictionary): + """ + :type target: str + :type dictionary: List[str] + :rtype: str + """ + + # Remove those words which can never be an abbreviation for target. + # This preprocessing will help us save time. + filtered_dictionary = [] + for wrd in dictionary: + if len(wrd) != len(target): + continue + filtered_dictionary.append(wrd) + dictionary = filtered_dictionary + if len(dictionary) == 0: + return str(len(target)) + + self.result_len = len(target)+1 + self.result, so_far, i = target, [], 0 + self.helper(target, so_far, i, dictionary) + return self.result \ No newline at end of file diff --git a/solutions/python3/bak/412.py.bak b/solutions/python3/bak/412.py.bak new file mode 100644 index 0000000..780d3c0 --- /dev/null +++ b/solutions/python3/bak/412.py.bak @@ -0,0 +1,17 @@ +class Solution: + def fizzBuzz(self, n): + """ + :type n: int + :rtype: List[str] + """ + num = [] + for i in range(1, n + 1): + if i % 3 == 0 and i % 5 == 0: + num.append("FizzBuzz") + elif i % 3 == 0: + num.append("Fizz") + elif i % 5 == 0: + num.append("Buzz") + else: + num.append(str(i)) + return num \ No newline at end of file diff --git a/solutions/python3/bak/413.py.bak b/solutions/python3/bak/413.py.bak new file mode 100644 index 0000000..50ab7e6 --- /dev/null +++ b/solutions/python3/bak/413.py.bak @@ -0,0 +1,13 @@ +class Solution: + def numberOfArithmeticSlices(self, A): + if len(A) < 3: + return 0 + A.append(float("inf")) + d, l, n, res = A[1] - A[0], 0, len(A), 0 + for i in range(2, n): + if d != A[i] - A[i - 1]: + diff = i - l - 2 + if diff > 0: + res += diff * (diff + 1) // 2 + d, l = A[i] - A[i - 1], i - 1 + return res \ No newline at end of file diff --git a/solutions/python3/bak/414.py.bak b/solutions/python3/bak/414.py.bak new file mode 100644 index 0000000..2b749a2 --- /dev/null +++ b/solutions/python3/bak/414.py.bak @@ -0,0 +1,10 @@ +class Solution: + def thirdMax(self, nums): + """ + :type nums: List[int] + :rtype: int + """ + s=list(set(nums)) + if s[-1]=0] + if len(s)>=3: return s[-3] + else: return s[-1] \ No newline at end of file diff --git a/solutions/python3/bak/415.py.bak b/solutions/python3/bak/415.py.bak new file mode 100644 index 0000000..06eb10b --- /dev/null +++ b/solutions/python3/bak/415.py.bak @@ -0,0 +1,8 @@ +class Solution: + def addStrings(self, num1, num2): + """ + :type num1: str + :type num2: str + :rtype: str + """ + return "".join(str(sum([(ord(num1[i])-ord("0"))*(10**(len(num1)-1-i)) for i in range(len(num1))]+[(ord(num2[i])-ord("0"))*(10**(len(num2)-1-i)) for i in range(len(num2))]))) \ No newline at end of file diff --git a/solutions/python3/bak/416.py.bak b/solutions/python3/bak/416.py.bak new file mode 100644 index 0000000..1ed23ea --- /dev/null +++ b/solutions/python3/bak/416.py.bak @@ -0,0 +1,12 @@ +class Solution: + def canPartition(self, nums): + sm, n = sum(nums), len(nums) + if sm % 2: + return False + sm //= 2 + dp = [False] * (sm + 1) + dp[0] = True + for num in nums: + for j in range(num, sm + 1)[::-1]: + dp[j] = dp[j] or dp[j - num] + return dp[-1] \ No newline at end of file diff --git a/solutions/python3/bak/417.py.bak b/solutions/python3/bak/417.py.bak new file mode 100644 index 0000000..cc7a5a2 --- /dev/null +++ b/solutions/python3/bak/417.py.bak @@ -0,0 +1,15 @@ +class Solution: + def pacificAtlantic(self, matrix): + pac, atl, m, n = set(), set(), len(matrix), len(matrix and matrix[0]) + def explore(i, j, ocean): + ocean.add((i, j)) + if i > 0 and (i - 1, j) not in ocean and matrix[i - 1][j] >= matrix[i][j]: explore(i - 1, j, ocean) + if j > 0 and (i, j - 1) not in ocean and matrix[i][j - 1] >= matrix[i][j]: explore(i, j - 1, ocean) + if i + 1 < m and (i + 1, j) not in ocean and matrix[i + 1][j] >= matrix[i][j]: explore(i + 1, j, ocean) + if j + 1 < n and (i, j +1) not in ocean and matrix[i][j + 1] >= matrix[i][j]: explore(i, j + 1, ocean) + for i in range(max(m, n)): + if i < m and (i, 0) not in pac: explore(i, 0, pac) + if i < n and (0, i) not in pac: explore(0, i, pac) + if i < n and (m - 1, i) not in atl: explore(m - 1, i, atl) + if i < m and (i, n - 1) not in atl: explore(i, n - 1, atl) + return [[x, y] for x, y in pac & atl] \ No newline at end of file diff --git a/solutions/python3/bak/418.py.bak b/solutions/python3/bak/418.py.bak new file mode 100644 index 0000000..9575b66 --- /dev/null +++ b/solutions/python3/bak/418.py.bak @@ -0,0 +1,13 @@ +class Solution: + def wordsTyping(self, sentence, rows, cols): + left, count, sm, ptr, wordLen = [0] * len(sentence), 0, 0, 0, len(sentence[0]) + for i, w in enumerate(sentence): + while sm + wordLen <= cols: + sm += wordLen + ptr += 1 + wordLen = len(sentence[ptr % len(sentence)]) + 1 + left[i] = ptr - i + sm -= len(w) + 1 + for r in range(rows): + count += left[count % len(sentence)] + return count // len(sentence) \ No newline at end of file diff --git a/solutions/python3/bak/419.py.bak b/solutions/python3/bak/419.py.bak new file mode 100644 index 0000000..8561f04 --- /dev/null +++ b/solutions/python3/bak/419.py.bak @@ -0,0 +1,3 @@ +class Solution: + def countBattleships(self, board): + return sum(board[i][j] == "X" and (i == 0 or board[i - 1][j] == ".") and (j == 0 or board[i][j - 1] == ".") for i in range(len(board)) for j in range(len(board[0]))) \ No newline at end of file diff --git a/solutions/python3/bak/42.py.bak b/solutions/python3/bak/42.py.bak new file mode 100644 index 0000000..7410ae5 --- /dev/null +++ b/solutions/python3/bak/42.py.bak @@ -0,0 +1,14 @@ +class Solution: + def trap(self, height): + res, left, l, r = 0, {}, 0, 0 + for i, h in enumerate(height): + left[i] = l + if h > l: + l = h + for i in range(len(height) - 1, -1, -1): + roof = min(left[i] , r) + if roof > height[i]: + res += roof - height[i] + if height[i] > r: + r = height[i] + return res \ No newline at end of file diff --git a/solutions/python3/bak/420.py.bak b/solutions/python3/bak/420.py.bak new file mode 100644 index 0000000..a3ac09c --- /dev/null +++ b/solutions/python3/bak/420.py.bak @@ -0,0 +1,39 @@ +class Solution(object): + def strongPasswordChecker(self, s): + """ + :type s: str + :rtype: int + """ + missing_type = 3 + if any('a' <= c <= 'z' for c in s): missing_type -= 1 + if any('A' <= c <= 'Z' for c in s): missing_type -= 1 + if any(c.isdigit() for c in s): missing_type -= 1 + + change = 0 + one = two = 0 + p = 2 + while p < len(s): + if s[p] == s[p-1] == s[p-2]: + length = 2 + while p < len(s) and s[p] == s[p-1]: + length += 1 + p += 1 + + change += length // 3 + if length % 3 == 0: one += 1 + elif length % 3 == 1: two += 1 + else: + p += 1 + + if len(s) < 6: + return max(missing_type, 6 - len(s)) + elif len(s) <= 20: + return max(missing_type, change) + else: + delete = len(s) - 20 + + change -= min(delete, one) + change -= min(max(delete - one, 0), two * 2) // 2 + change -= max(delete - one - 2 * two, 0) // 3 + + return delete + max(missing_type, change) \ No newline at end of file diff --git a/solutions/python3/bak/421.py.bak b/solutions/python3/bak/421.py.bak new file mode 100644 index 0000000..09f609e --- /dev/null +++ b/solutions/python3/bak/421.py.bak @@ -0,0 +1,14 @@ +class Solution: + def findMaximumXOR(self, nums, ans = 0): + ans = 0 + for bit in range(30, -1, -1): + ans <<= 1 + attempt = ans | 1 + prefix = set() + for x in nums: + p = x >> bit + if attempt ^ p in prefix: + ans = attempt + break + prefix.add(p) + return ans \ No newline at end of file diff --git a/solutions/python3/bak/422.py.bak b/solutions/python3/bak/422.py.bak new file mode 100644 index 0000000..46d50eb --- /dev/null +++ b/solutions/python3/bak/422.py.bak @@ -0,0 +1,9 @@ +class Solution: + def validWordSquare(self, words): + for j, row in enumerate(words): + col = "" + for s in words: + try: col += s[j] + except: break + if row != col: return False + return True \ No newline at end of file diff --git a/solutions/python3/bak/424.py.bak b/solutions/python3/bak/424.py.bak new file mode 100644 index 0000000..efaf3c5 --- /dev/null +++ b/solutions/python3/bak/424.py.bak @@ -0,0 +1,15 @@ +class Solution: + def characterReplacement(self, s, k): + """ + :type s: str + :type k: int + :rtype: int + """ + dic, start, end = {}, 0, 0 + for end in range(1, len(s)+1): + if not s[end-1] in dic: dic[s[end-1]] = 1 + else: dic[s[end-1]] += 1 + if end-start-max(dic.values()) > k: + dic[s[start]] -= 1 + start += 1 + return end-start \ No newline at end of file diff --git a/solutions/python3/bak/425.py.bak b/solutions/python3/bak/425.py.bak new file mode 100644 index 0000000..db0f9d6 --- /dev/null +++ b/solutions/python3/bak/425.py.bak @@ -0,0 +1,15 @@ +class Solution: + def wordSquares(self, words): + pref, res = collections.defaultdict(set), [] + for w in words: + for i in range(len(w)): + pref[w[:i + 1]].add(w) + def dfs(i, arr): + if i == len(arr[0]): + res.append(arr) + else: + for w in pref["".join(row[i] for row in arr)]: + dfs(i + 1, arr + [w]) + for w in words: + dfs(1, [w]) + return res \ No newline at end of file diff --git a/solutions/python3/bak/426.py.bak b/solutions/python3/bak/426.py.bak new file mode 100644 index 0000000..0bb0694 --- /dev/null +++ b/solutions/python3/bak/426.py.bak @@ -0,0 +1,23 @@ +class Solution: + def treeToDoublyList(self, root): + head, tail = [None], [None] + def dfs(node, pre): + if not node: + return + l = dfs(node.left, pre) + new = Node(node.val, l or pre, None) + if pre and not l: + pre.right = new + elif l: + l.right = new + if not pre and not l: + head[0] = new + if not tail[0] or node.val > tail[0].val: + tail[0] = new + r = dfs(node.right, new) + return r if r else new + dfs(root, None) + if head[0]: + head[0].left = tail[0] + tail[0].right = head[0] + return head[0] \ No newline at end of file diff --git a/solutions/python3/bak/427.py.bak b/solutions/python3/bak/427.py.bak new file mode 100644 index 0000000..7f14e08 --- /dev/null +++ b/solutions/python3/bak/427.py.bak @@ -0,0 +1,17 @@ +class Solution: + def construct(self, grid): + def dfs(x, y, l): + if l == 1: + node = Node(grid[x][y] == 1, True, None, None, None, None) + else: + tLeft = dfs(x, y, l // 2) + tRight = dfs(x, y + l // 2, l // 2) + bLeft = dfs(x + l // 2, y, l// 2) + bRight = dfs(x + l // 2, y + l // 2, l // 2) + value = tLeft.val or tRight.val or bLeft.val or bRight.val + if tLeft.isLeaf and tRight.isLeaf and bLeft.isLeaf and bRight.isLeaf and tLeft.val == tRight.val == bLeft.val == bRight.val: + node = Node(value, True, None, None, None, None) + else: + node = Node(value, False, tLeft, tRight, bLeft, bRight) + return node + return grid and dfs(0, 0, len(grid)) or None \ No newline at end of file diff --git a/solutions/python3/bak/43.py.bak b/solutions/python3/bak/43.py.bak new file mode 100644 index 0000000..2560973 --- /dev/null +++ b/solutions/python3/bak/43.py.bak @@ -0,0 +1,4 @@ +class Solution: + def multiply(self, num1, num2): + dic, l1, l2 = {str(i): i for i in range(10)}, len(num1) - 1, len(num2) - 1 + return str(sum([dic[n1] * (10**(l1-i)) for i, n1 in enumerate(num1)]) * sum([dic[n2] * (10**(l2-j)) for j, n2 in enumerate(num2)])) \ No newline at end of file diff --git a/solutions/python3/bak/432.py.bak b/solutions/python3/bak/432.py.bak new file mode 100644 index 0000000..092d498 --- /dev/null +++ b/solutions/python3/bak/432.py.bak @@ -0,0 +1,81 @@ +class Node: + def __init__(self, key, value): + self.val = value + self.key = key + self.next = None + self.pre = None +class AllOne: + + def __init__(self): + self.first = {} + self.last = {} + self.keys = {} + self.head = Node(-1, -1) + self.tail = Node(-1, -1) + self.head.next = self.tail + self.tail.pre = self.head + + def add(self, prev, node): + node.pre = prev + node.next = prev.next + node.pre.next = node.next.pre = node + + def remove(self, node): + node.pre.next = node.next + node.next.pre = node.pre + + def process(self, node): + if self.last[node.val] == node and node.pre.val != node.val: + self.first.pop(node.val) + self.last.pop(node.val) + elif self.first[node.val] == node: + self.first[node.val] = node.next + elif self.last[node.val] == node: + self.last[node.val] = node.pre + + def process2(self, node, prev, key, d): + if key in self.keys: + if node.val + d in self.last: + self.add(self.last[node.val + d], node) + elif node.val in self.last: + self.add(self.last[node.val], node) + else: + self.add(prev, node) + elif 1 in self.last: + node = Node(key, 0) + self.add(self.last[1], node) + else: + node = Node(key, 0) + self.add(self.head, node) + node.val += d + self.last[node.val] = node + if node.val not in self.first: + self.first[node.val] = node + if key not in self.keys: + self.keys[key] = node + + def inc(self, key): + if key in self.keys: + node = self.keys[key] + prev = node.pre + self.process(node) + self.remove(node) + self.process2(node, prev, key, 1) + else: + self.process2(None, None, key, 1) + + def dec(self, key): + if key in self.keys: + node = self.keys[key] + prev = node.pre + self.process(node) + self.remove(node) + if node.val != 1: + self.process2(node, prev, key, -1) + else: + self.keys.pop(key) + + def getMaxKey(self): + return self.tail.pre.key if self.tail.pre != self.head else "" + def getMinKey(self): + return self.head.next.key if self.head.next != self.tail else "" \ No newline at end of file diff --git a/solutions/python3/bak/433.py.bak b/solutions/python3/bak/433.py.bak new file mode 100644 index 0000000..95628d0 --- /dev/null +++ b/solutions/python3/bak/433.py.bak @@ -0,0 +1,20 @@ +class Solution: + def minMutation(self, start: str, end: str, bank: List[str]) -> int: + bfs = [start] + genes = set(bank) + cnt = 0 + while bfs: + arr = [] + for g in bfs: + if g == end: + return cnt + for i, c in enumerate(g): + for new in 'AGTC': + if new != c: + s = g[:i] + new + g[i + 1:] + if s in genes: + arr.append(s) + genes.discard(s) + bfs = arr + cnt += 1 + return -1 \ No newline at end of file diff --git a/solutions/python3/bak/434.py.bak b/solutions/python3/bak/434.py.bak new file mode 100644 index 0000000..a9915ec --- /dev/null +++ b/solutions/python3/bak/434.py.bak @@ -0,0 +1,8 @@ +class Solution: + def countSegments(self, s): + """ + :type s: str + :rtype: int + """ + return len(s.split()) + \ No newline at end of file diff --git a/solutions/python3/bak/435.py.bak b/solutions/python3/bak/435.py.bak new file mode 100644 index 0000000..0f4366f --- /dev/null +++ b/solutions/python3/bak/435.py.bak @@ -0,0 +1,13 @@ +# Definition for an interval. +# class Interval: +# def __init__(self, s=0, e=0): +# self.start = s +# self.end = e + +class Solution: + def eraseOverlapIntervals(self, intervals): + intervals.sort(key = lambda x: x.end); res, curr = 0, -float("inf") + for i in intervals: + if curr > i.start: res += 1 + else: curr = i.end + return res \ No newline at end of file diff --git a/solutions/python3/bak/436.py.bak b/solutions/python3/bak/436.py.bak new file mode 100644 index 0000000..dcef026 --- /dev/null +++ b/solutions/python3/bak/436.py.bak @@ -0,0 +1,18 @@ +class Solution: + def findRightInterval(self, intervals): + def binarySearch(l, r): + x, found = intervals[l - 1].end, None + while l <= r: + mid = (l + r) // 2 + if intervals[mid].start >= x: + r = mid - 1 + found = mid + else: + l = mid + 1 + return ind[intervals[found]] if found != None else -1 + root = intervals[:] + ind = {intr:i for i, intr in enumerate(root)} + intervals.sort(key = lambda x: x.start) + for i in range(len(intervals)): + root[ind[intervals[i]]] = binarySearch(i + 1, len(intervals) - 1) + return root \ No newline at end of file diff --git a/solutions/python3/bak/437.py.bak b/solutions/python3/bak/437.py.bak new file mode 100644 index 0000000..70372eb --- /dev/null +++ b/solutions/python3/bak/437.py.bak @@ -0,0 +1,28 @@ +# Definition for a binary tree node. +# class TreeNode: +# def __init__(self, x): +# self.val = x +# self.left = None +# self.right = None + +class Solution: + def pathSum(self, root, sum): + """ + :type root: TreeNode + :type sum: int + :rtype: int + """ + dic = {} + def traverse(node, parent): + if not node: return + dic[node] = [node.val] + if node.val == sum: res[0] += 1 + if parent: + for num in dic[parent]: + dic[node].append(num + node.val) + if num + node.val == sum: res[0] += 1 + traverse(node.left, node) + traverse(node.right, node) + res = [0] + traverse(root, None) + return res[0] \ No newline at end of file diff --git a/solutions/python3/bak/438.py.bak b/solutions/python3/bak/438.py.bak new file mode 100644 index 0000000..a49a477 --- /dev/null +++ b/solutions/python3/bak/438.py.bak @@ -0,0 +1,16 @@ +class Solution: + def findAnagrams(self, s, p): + """ + :type s: str + :type p: str + :rtype: List[int] + """ + out=list() + from collections import Counter + s_counter, p_counter=Counter(s[:len(p)-1]), Counter(p) + for i in range(len(p)-1,len(s)): + s_counter[s[i]]+=1 + if s_counter==p_counter: out.append(i-len(p)+1) + s_counter[s[i-len(p)+1]]-=1 + if s_counter[s[i-len(p)+1]]==0: del s_counter[s[i-len(p)+1]] + return out \ No newline at end of file diff --git a/solutions/python3/bak/439.py.bak b/solutions/python3/bak/439.py.bak new file mode 100644 index 0000000..ad2b9b7 --- /dev/null +++ b/solutions/python3/bak/439.py.bak @@ -0,0 +1,9 @@ +class Solution: + def parseTernary(self, expression, stack = []): + for c in expression[::-1]: + if stack and stack[-1] == "?": + _, first, q, second = stack.pop(), stack.pop(), stack.pop(), stack.pop() + stack.append(c == "T" and first or second) + else: + stack.append(c) + return stack.pop() \ No newline at end of file diff --git a/solutions/python3/bak/44.py.bak b/solutions/python3/bak/44.py.bak new file mode 100644 index 0000000..9d3e3a8 --- /dev/null +++ b/solutions/python3/bak/44.py.bak @@ -0,0 +1,21 @@ +class Solution: + def isMatch(self, s, p): + sp = pp = match = 0 + star = -1 + while sp < len(s): + if (pp < len(p) and (s[sp] == p[pp] or p[pp] == '?')): + sp +=1 + pp +=1 + elif pp < len(p) and p[pp] == '*': + star = pp + match = sp + pp +=1 + elif star != -1: + pp = star + 1 + match +=1 + sp = match + else: + return False + while(pp < len(p) and p[pp] == '*'): + pp += 1 + return pp == len(p) \ No newline at end of file diff --git a/solutions/python3/bak/441.py.bak b/solutions/python3/bak/441.py.bak new file mode 100644 index 0000000..c322c7e --- /dev/null +++ b/solutions/python3/bak/441.py.bak @@ -0,0 +1,9 @@ +class Solution: + def arrangeCoins(self, n: int) -> int: + sm = res = 0 + for i in range(1, n + 1): + sm += i + if sm > n: + break + res += 1 + return res \ No newline at end of file diff --git a/solutions/python3/bak/442.py.bak b/solutions/python3/bak/442.py.bak new file mode 100644 index 0000000..592582f --- /dev/null +++ b/solutions/python3/bak/442.py.bak @@ -0,0 +1,11 @@ +class Solution: + def findDuplicates(self, nums): + """ + :type nums: List[int] + :rtype: List[int] + """ + out=list() + for i in range(len(nums)): + if nums[abs(nums[i])-1]<0: out.append(abs(nums[i])) + else: nums[abs(nums[i])-1]*=-1 + return out \ No newline at end of file diff --git a/solutions/python3/bak/443.py.bak b/solutions/python3/bak/443.py.bak new file mode 100644 index 0000000..7e1f52f --- /dev/null +++ b/solutions/python3/bak/443.py.bak @@ -0,0 +1,16 @@ +class Solution: + def compress(self, chars): + """ + :type chars: List[str] + :rtype: int + """ + curr, count, i = chars[0], 1, 1 + while i1: chars[:i]+= (i for i in "".join(str(count))); i+=len([i for i in "".join(str(count))]) + i, count =i+1, 1 + else: + if i==len(chars)-1: chars.pop(i); chars+=[i for i in "".join(str(count+1))]; break + chars.pop(i); count+=1 + return len(chars) \ No newline at end of file diff --git a/solutions/python3/bak/444.py.bak b/solutions/python3/bak/444.py.bak new file mode 100644 index 0000000..764c16b --- /dev/null +++ b/solutions/python3/bak/444.py.bak @@ -0,0 +1,18 @@ +class Solution: + def sequenceReconstruction(self, org, seqs): + order, orders, graph, seen = collections.defaultdict(int), set(), collections.defaultdict(set), set() + for seq in seqs: + for i in range(len(seq)): + if i > 0: + if seq[i] == seq[i - 1]: return False + graph[seq[i - 1]].add(seq[i]) + seen.add(seq[i]) + if not seen: return False + for i in range(len(org) - 1, -1, -1): + if org[i] in seen: seen.discard(org[i]) + order[org[i]] = max([order[v] for v in graph[org[i]]] or [0]) + 1 + before = set(v for v in graph[org[i]] if v in seen) + if order[org[i]] in orders or before: + return False + orders.add(order[org[i]]) + return not seen \ No newline at end of file diff --git a/solutions/python3/bak/445.py.bak b/solutions/python3/bak/445.py.bak new file mode 100644 index 0000000..6a32568 --- /dev/null +++ b/solutions/python3/bak/445.py.bak @@ -0,0 +1,26 @@ +class Solution: + def addTwoNumbers(self, l1: ListNode, l2: ListNode) -> ListNode: + s1, s2, s3 = [], [], [] + p1, p2 = l1, l2 + while p1: + s1.append(p1.val) + p1 = p1.next + while p2: + s2.append(p2.val) + p2 = p2.next + if len(s1) < len(s2): + s1, s2 = s2, s1 + l1, l2 = l2, l1 + residual = 0 + while len(s1) > 0: + temp = s1.pop() + residual + if len(s2) > 0: + temp += s2.pop() + s3.append(temp % 10) + residual = temp // 10 + head, p = ListNode(1), l1 + head.next = p + while len(s3) > 0: + p.val = s3.pop() + p = p.next + return head if residual == 1 else head.next \ No newline at end of file diff --git a/solutions/python3/bak/446.py.bak b/solutions/python3/bak/446.py.bak new file mode 100644 index 0000000..c8a8799 --- /dev/null +++ b/solutions/python3/bak/446.py.bak @@ -0,0 +1,8 @@ +class Solution: + def numberOfArithmeticSlices(self, A): + dp, res = collections.defaultdict(dict), 0 + for j in range(len(A)): + for i in range(j): + dp[j][A[j] - A[i]] = dp[j].get(A[j] - A[i], 0) + dp[i].get(A[j] - A[i], 1) + if A[j] - A[i] in dp[i]: res, dp[j][A[j] - A[i]] = res + dp[i][A[j] - A[i]], dp[j][A[j] - A[i]] + 1 + return res \ No newline at end of file diff --git a/solutions/python3/bak/448.py.bak b/solutions/python3/bak/448.py.bak new file mode 100644 index 0000000..049ee43 --- /dev/null +++ b/solutions/python3/bak/448.py.bak @@ -0,0 +1,7 @@ +class Solution: + def findDisappearedNumbers(self, nums): + """ + :type nums: List[int] + :rtype: List[int] + """ + return [x for x in set([i for i in range(1,len(nums)+1)])-set(nums)] \ No newline at end of file diff --git a/solutions/python3/bak/45.py.bak b/solutions/python3/bak/45.py.bak new file mode 100644 index 0000000..04c24f3 --- /dev/null +++ b/solutions/python3/bak/45.py.bak @@ -0,0 +1,10 @@ +class Solution: + def jump(self, nums): + last = cur = jump = i = 0 + while cur < len(nums) - 1: + while i <= last: + if i + nums[i] > cur: cur = i + nums[i] + i += 1 + last = cur + jump += 1 + return jump \ No newline at end of file diff --git a/solutions/python3/bak/450.py.bak b/solutions/python3/bak/450.py.bak new file mode 100644 index 0000000..3f25eb6 --- /dev/null +++ b/solutions/python3/bak/450.py.bak @@ -0,0 +1,25 @@ +# Definition for a binary tree node. +# class TreeNode: +# def __init__(self, x): +# self.val = x +# self.left = None +# self.right = None + +class Solution: + def deleteNode(self, root, key): + """ + :type root: TreeNode + :type key: int + :rtype: TreeNode + """ + if not root: return + if root.val > key: root.left = self.deleteNode(root.left, key) + elif root.val < key: root.right = self.deleteNode(root.right, key) + else: + if not root.right: return root.left + elif not root.left: return root.right + tmp, mini = root.right, root.right.val + while tmp.left: + tmp, mini = tmp.left, tmp.left.val + root.val, root.right = mini, self.deleteNode(root.right, mini) + return root \ No newline at end of file diff --git a/solutions/python3/bak/451.py.bak b/solutions/python3/bak/451.py.bak new file mode 100644 index 0000000..0a8ee31 --- /dev/null +++ b/solutions/python3/bak/451.py.bak @@ -0,0 +1,7 @@ +class Solution: + def frequencySort(self, s: str) -> str: + cnt = collections.Counter(s) + res = '' + for k, v in sorted(cnt.items(), key = lambda x: -cnt[x[0]]): + res += k * v + return res \ No newline at end of file diff --git a/solutions/python3/bak/452.py.bak b/solutions/python3/bak/452.py.bak new file mode 100644 index 0000000..da05f57 --- /dev/null +++ b/solutions/python3/bak/452.py.bak @@ -0,0 +1,7 @@ +class Solution: + def findMinArrowShots(self, p): + p.sort(key = lambda x: x[1]) + (res, curr) = (1, p[0][1]) if p else (0, None) + for n in p: + if n[0] > curr: res, curr = res + 1, n[1] + return res \ No newline at end of file diff --git a/solutions/python3/bak/453.py.bak b/solutions/python3/bak/453.py.bak new file mode 100644 index 0000000..a1455e0 --- /dev/null +++ b/solutions/python3/bak/453.py.bak @@ -0,0 +1,7 @@ +class Solution: + def minMoves(self, nums): + """ + :type nums: List[int] + :rtype: int + """ + return sum(nums) - min(nums) * len(nums) \ No newline at end of file diff --git a/solutions/python3/bak/454.py.bak b/solutions/python3/bak/454.py.bak new file mode 100644 index 0000000..97839f0 --- /dev/null +++ b/solutions/python3/bak/454.py.bak @@ -0,0 +1,4 @@ +class Solution: + def fourSumCount(self, A: List[int], B: List[int], C: List[int], D: List[int]) -> int: + ab = collections.Counter([a + b for a in A for b in B]) + return sum(-c - d in ab and ab[-c-d] for c in C for d in D) \ No newline at end of file diff --git a/solutions/python3/bak/455.py.bak b/solutions/python3/bak/455.py.bak new file mode 100644 index 0000000..eb0dac4 --- /dev/null +++ b/solutions/python3/bak/455.py.bak @@ -0,0 +1,7 @@ +class Solution: + def findContentChildren(self, g, s): + g.sort(reverse = True); s.sort(reverse = True); res = 0 + while s and g: + if g[-1] <= s[-1]: res += 1; g.pop(); s.pop() + else: s.pop() + return res \ No newline at end of file diff --git a/solutions/python3/bak/456.py.bak b/solutions/python3/bak/456.py.bak new file mode 100644 index 0000000..cd882c6 --- /dev/null +++ b/solutions/python3/bak/456.py.bak @@ -0,0 +1,8 @@ +class Solution: + def find132pattern(self, nums): + stack, s3 = [], -float("inf") + for n in nums[::-1]: + if n < s3: return True + while stack and stack[-1] < n: s3 = stack.pop() + stack.append(n) + return False \ No newline at end of file diff --git a/solutions/python3/bak/459.py.bak b/solutions/python3/bak/459.py.bak new file mode 100644 index 0000000..2e1a6de --- /dev/null +++ b/solutions/python3/bak/459.py.bak @@ -0,0 +1,7 @@ +class Solution: + def repeatedSubstringPattern(self, s): + """ + :type s: str + :rtype: bool + """ + return True if len(s)>1 and (s in [s[:i]*(len(s)//i) for i in range(2,len(s)) if len(s)%i==0] or s==s[0]*len(s)) else False \ No newline at end of file diff --git a/solutions/python3/bak/46.py.bak b/solutions/python3/bak/46.py.bak new file mode 100644 index 0000000..e65e9da --- /dev/null +++ b/solutions/python3/bak/46.py.bak @@ -0,0 +1,2 @@ +class Solution: + def permute(self, nums): return list(itertools.permutations(nums)) \ No newline at end of file diff --git a/solutions/python3/bak/460.py.bak b/solutions/python3/bak/460.py.bak new file mode 100644 index 0000000..12a56f4 --- /dev/null +++ b/solutions/python3/bak/460.py.bak @@ -0,0 +1,68 @@ +class Node: + def __init__(self, k, v, f): + self.key = k + self.val = v + self.freq = f + self.next = self.pre = None +class LFUCache: + + def __init__(self, capacity): + self.max = capacity + self.cache = 0 + self.freqLast = {} + self.Nodes = {} + self.head = self.tail = Node("#", "#", "#") + self.head.next = self.tail + self.tail.pre = self.head + + def changeFreq(self, key): + node, f = self.Nodes[key], self.Nodes[key].freq + if self.freqLast[f] == node: + if node.pre.freq == f: + self.freqLast[f] = node.pre + else: + self.freqLast.pop(f) + if f + 1 in self.freqLast: + node.pre.next = node.next + node.next.pre = node.pre + node.pre = self.freqLast[f + 1] + node.next = node.pre.next + elif f in self.freqLast: + node.pre.next = node.next + node.next.pre = node.pre + node.pre = self.freqLast[f] + node.next = node.pre.next + node.pre.next = node.next.pre = node + self.freqLast[f + 1] = node + node.freq += 1 + + def removeFirst(self): + node, f = self.head.next, self.head.next.freq + node.pre.next = node.next + node.next.pre = node.pre + self.Nodes.pop(node.key) + if self.freqLast[f] == node: + self.freqLast.pop(f) + self.cache -= 1 + + def get(self, key): + if key in self.Nodes: + self.changeFreq(key) + return self.Nodes[key].val + return -1 + def put(self, key, value): + if key in self.Nodes: + self.changeFreq(key) + self.Nodes[key].val = value + elif self.max: + if self.cache == self.max: + self.removeFirst() + self.cache += 1 + new = Node(key, value, 1) + if 1 in self.freqLast: + new.pre = self.freqLast[1] + else: + new.pre = self.head + new.next = new.pre.next + new.pre.next = new.next.pre = new + self.freqLast[1] = self.Nodes[key] = new \ No newline at end of file diff --git a/solutions/python3/bak/461.py.bak b/solutions/python3/bak/461.py.bak new file mode 100644 index 0000000..7bea7d2 --- /dev/null +++ b/solutions/python3/bak/461.py.bak @@ -0,0 +1,3 @@ +class Solution: + def hammingDistance(self, x: int, y: int) -> int: + return sum(a != b for a, b in zip(bin(x)[2:].zfill(32), bin(y)[2:].zfill(32))) \ No newline at end of file diff --git a/solutions/python3/bak/462.py.bak b/solutions/python3/bak/462.py.bak new file mode 100644 index 0000000..5f9d928 --- /dev/null +++ b/solutions/python3/bak/462.py.bak @@ -0,0 +1,5 @@ +class Solution: + def minMoves2(self, nums): + nums.sort() + m = nums[(len(nums) - 1) // 2] + return sum(abs(num - m) for num in nums) \ No newline at end of file diff --git a/solutions/python3/bak/463.py.bak b/solutions/python3/bak/463.py.bak new file mode 100644 index 0000000..3d82ed7 --- /dev/null +++ b/solutions/python3/bak/463.py.bak @@ -0,0 +1,18 @@ +class Solution: + def islandPerimeter(self, grid: List[List[int]]) -> int: + self.res = 0 + used = set() + def dfs(i, j): + used.add((i, j)) + self.res += 4 + for x, y in (i - 1, j), (i + 1, j), (i, j - 1), (i, j + 1): + if 0 <= x < m and 0 <= y < n and grid[x][y]: + self.res -= 1 + if (x, y) not in used: + dfs(x, y) + m, n = len(grid), len(grid[0]) + for i in range(m): + for j in range(n): + if grid[i][j] == 1 and (i, j) not in used: + dfs(i, j) + return self.res \ No newline at end of file diff --git a/solutions/python3/bak/464.py.bak b/solutions/python3/bak/464.py.bak new file mode 100644 index 0000000..553b5e0 --- /dev/null +++ b/solutions/python3/bak/464.py.bak @@ -0,0 +1,18 @@ +class Solution: + def canIWin(self, maxChoosableInteger, desiredTotal): + memo = {} + def dfs(arr, total): + s = str(arr) + if s in memo: + return memo[s] + elif arr[-1] >= total: + return True + for i in range(len(arr)): + if not dfs(arr[:i] + arr[i + 1:], total - arr[i]): + memo[s] = True + return True + memo[s] = False + return False + if (1 + maxChoosableInteger) * maxChoosableInteger/2 < desiredTotal: + return False + return dfs(list(range(1, maxChoosableInteger + 1)), desiredTotal) \ No newline at end of file diff --git a/solutions/python3/bak/465.py.bak b/solutions/python3/bak/465.py.bak new file mode 100644 index 0000000..bb4acaf --- /dev/null +++ b/solutions/python3/bak/465.py.bak @@ -0,0 +1,32 @@ +class Solution: + def minTransfers(self, transactions: List[List[int]]) -> int: + def remove_one_zero_clique(non_zero): + n = len(non_zero) + q = collections.deque() + # q store ([index set], sum of set) + q.append(([0], non_zero[0])) + min_zero_set = None + + while q: + cur_set, cur_sum = q.popleft() + if cur_sum == 0: + min_zero_set = cur_set + break + for j in range(cur_set[-1] + 1, n): + q.append((cur_set + [j], cur_sum + non_zero[j])) + + min_zero_set = set(min_zero_set) + return [non_zero[i] for i in range(n) if i not in min_zero_set] + + + bal = collections.defaultdict(int) + for t in transactions: + bal[t[0]] -= t[2] + bal[t[1]] += t[2] + non_zero = [bal[k] for k in bal if bal[k] != 0] + + bal_cnt = len(non_zero) + while len(non_zero) > 0: + non_zero = remove_one_zero_clique(non_zero) + bal_cnt -= 1 + return bal_cnt \ No newline at end of file diff --git a/solutions/python3/bak/466.py.bak b/solutions/python3/bak/466.py.bak new file mode 100644 index 0000000..57160c7 --- /dev/null +++ b/solutions/python3/bak/466.py.bak @@ -0,0 +1,25 @@ +class Solution(object): + def getMaxRepetitions(self, s1, n1, s2, n2): + start = {} # s2_idx : s1_round, s2_round + s1_round, s2_round, s2_idx = 0, 0, 0 + while s1_round < n1: + s1_round += 1 + for ch in s1: + if ch == s2[s2_idx]: + s2_idx += 1 + if s2_idx == len(s2): + s2_round += 1 + s2_idx = 0 + if s2_idx in start: + prev_s1_round, prev_s2_round = start[s2_idx] + circle_s1_round, circle_s2_round = s1_round - prev_s1_round, s2_round - prev_s2_round + res = (n1 - prev_s1_round) // circle_s1_round * circle_s2_round + left_s1_round = (n1 - prev_s1_round) % circle_s1_round + prev_s1_round + for key, val in start.items(): + if val[0] == left_s1_round: + res += val[1] + break + return res // n2 + else: + start[s2_idx] = (s1_round, s2_round) + return s2_round // n2 \ No newline at end of file diff --git a/solutions/python3/bak/467.py.bak b/solutions/python3/bak/467.py.bak new file mode 100644 index 0000000..f0cabac --- /dev/null +++ b/solutions/python3/bak/467.py.bak @@ -0,0 +1,7 @@ +class Solution: + def findSubstringInWraproundString(self, p): + res, l = {i: 1 for i in p}, 1 + for i, j in zip(p, p[1:]): + l = l + 1 if (ord(j) - ord(i)) % 26 == 1 else 1 + res[j] = max(res[j], l) + return sum(res.values()) \ No newline at end of file diff --git a/solutions/python3/bak/468.py.bak b/solutions/python3/bak/468.py.bak new file mode 100644 index 0000000..09f7812 --- /dev/null +++ b/solutions/python3/bak/468.py.bak @@ -0,0 +1,20 @@ +class Solution: + def validIPAddress(self, IP): + """ + :type IP: str + :rtype: str + """ + ip4, ip6 = IP.split("."), IP.split(":") + if len(ip4) == 4: + for num in ip4: + try: + if not (num[0] in string.digits and int(num) < 256 and (num[0] != "0" or num == "0")): return "Neither" + except: return "Neither" + return "IPv4" + elif len(ip6) == 8: + for num in ip6: + try: + if not (num[0] in string.hexdigits and 0 <= int(num, 16) and len(num) <= 4): return "Neither" + except: return "Neither" + return "IPv6" + return "Neither" \ No newline at end of file diff --git a/solutions/python3/bak/469.py.bak b/solutions/python3/bak/469.py.bak new file mode 100644 index 0000000..de813d8 --- /dev/null +++ b/solutions/python3/bak/469.py.bak @@ -0,0 +1,9 @@ +class Solution: + def isConvex(self, points): + def direction(a, b, c): return (b[0] - a[0]) * (c[1] - a[1]) - (b[1] - a[1]) * (c[0] - a[0]) + d, n = 0, len(points) + for i in range(n): + a = direction(points[i], points[(i + 1) % n], points[(i + 2) % n]) + if not d: d = a + elif a * d < 0: return False + return True \ No newline at end of file diff --git a/solutions/python3/bak/47.py.bak b/solutions/python3/bak/47.py.bak new file mode 100644 index 0000000..e63ba64 --- /dev/null +++ b/solutions/python3/bak/47.py.bak @@ -0,0 +1,7 @@ +class Solution: + def permuteUnique(self, nums): + dic = set() + for p in itertools.permutations(nums): + if p not in dic: + dic.add(p) + return list(dic) \ No newline at end of file diff --git a/solutions/python3/bak/470.py.bak b/solutions/python3/bak/470.py.bak new file mode 100644 index 0000000..00bea1d --- /dev/null +++ b/solutions/python3/bak/470.py.bak @@ -0,0 +1,3 @@ +class Solution: + def rand10(self): + return sum(rand7() for _ in range(10)) % 10 + 1 \ No newline at end of file diff --git a/solutions/python3/bak/471.py.bak b/solutions/python3/bak/471.py.bak new file mode 100644 index 0000000..3bd2c84 --- /dev/null +++ b/solutions/python3/bak/471.py.bak @@ -0,0 +1,18 @@ +class Solution: + def encode(self, s: str) -> str: + def dfs(i, j): + if i == j: return s[i] + if (i, j) not in memo: + c1 = min((dfs(i, k) + dfs(k + 1, j) if s[i:k + 1] != s[k + 1:j + 1] else '2[' + dfs(i, k) + ']' for k in range(i, j)), key = len) + c2 = s[i:j + 1] + memo[(i, j)] = min(c1, c2, key = len) + for k in range(i, i + (j - i) // 2 + 1): + tar, ind, cnt = s[i:k + 1], i, 0 + while ind + k - i <= j and s[ind:ind + k - i + 1] == tar: + cnt += 1 + ind += k - i + 1 + c3 = str(cnt) + '[' + tar + ']' + dfs(ind, j) if ind <= j else str(cnt) + '[' + tar + ']' + memo[(i, j)] = min(memo[(i, j)], c3, key = len) + return memo[(i, j)] + memo = {} + return dfs(0, len(s) - 1) \ No newline at end of file diff --git a/solutions/python3/bak/472.py.bak b/solutions/python3/bak/472.py.bak new file mode 100644 index 0000000..9572739 --- /dev/null +++ b/solutions/python3/bak/472.py.bak @@ -0,0 +1,13 @@ +class Solution: + def findAllConcatenatedWordsInADict(self, words): + def check(w, st): + if w in st: return True + for i in range(1, len(w)): + if w[:i] in st and check(w[i:], st): return True + return False + w_set, res = set(words), [] + for w in words: + w_set.remove(w) + if check(w, w_set): res += w, + w_set.add(w) + return res \ No newline at end of file diff --git a/solutions/python3/bak/473.py.bak b/solutions/python3/bak/473.py.bak new file mode 100644 index 0000000..4ca0d32 --- /dev/null +++ b/solutions/python3/bak/473.py.bak @@ -0,0 +1,14 @@ +class Solution: + def makesquare(self, nums): + def dfs(index, edge, count, used): + for i in range(index, len(nums)): + if i in used or edge - nums[i] < 0: continue + elif edge - nums[i] > 0 and dfs(i + 1, edge - nums[i], count, used | {i}): return True + elif edge - nums[i] == 0 and (count and dfs(1, l, count - 1, used | {i})) or not count: return True + return False + sm = sum(nums) + if len(nums) < 4 or sm % 4 != 0: return False + l = sm // 4 + nums.sort(reverse = True) + if nums[0] > l: return False + return nums[0] == l and dfs(1, l, 1, {0}) or dfs(1, l - nums[0], 2, {0}) \ No newline at end of file diff --git a/solutions/python3/bak/474.py.bak b/solutions/python3/bak/474.py.bak new file mode 100644 index 0000000..24a949f --- /dev/null +++ b/solutions/python3/bak/474.py.bak @@ -0,0 +1,19 @@ +class Solution: + def findMaxForm(self, strs, m, n): + res = [0] + memo = set() + def dfs(st, zeros, ones, cnt): + if (zeros, ones, cnt) not in memo: + if cnt > res[0]: + res[0] = cnt + if zeros or ones: + for s in st: + if st[s] and cntr[s]["0"] <= zeros and cntr[s]["1"] <= ones: + st[s] -= 1 + dfs(st, zeros - cntr[s]["0"], ones - cntr[s]["1"], cnt + 1) + st[s] += 1 + memo.add((zeros, ones, cnt)) + + cntr = {s:collections.Counter(s) for s in strs} + dfs(collections.Counter(strs), m, n, 0) + return res[0] \ No newline at end of file diff --git a/solutions/python3/bak/475.py.bak b/solutions/python3/bak/475.py.bak new file mode 100644 index 0000000..c464bee --- /dev/null +++ b/solutions/python3/bak/475.py.bak @@ -0,0 +1,13 @@ +class Solution: + def findRadius(self, houses, heaters): + heaters.sort() + r = 0 + for h in houses: + ind = bisect.bisect_left(heaters, h) + if ind == len(heaters): + r = max(r, h - heaters[-1]) + elif ind == 0: + r = max(r, heaters[0] - h) + else: + r = max(r, min(heaters[ind] - h, h - heaters[ind - 1])) + return r \ No newline at end of file diff --git a/solutions/python3/bak/476.py.bak b/solutions/python3/bak/476.py.bak new file mode 100644 index 0000000..29c274a --- /dev/null +++ b/solutions/python3/bak/476.py.bak @@ -0,0 +1,7 @@ +class Solution: + def findComplement(self, num): + """ + :type num: int + :rtype: int + """ + return int("".join([str((int(i)+1)%2) for i in bin(num)[2:]]),2) \ No newline at end of file diff --git a/solutions/python3/bak/477.py.bak b/solutions/python3/bak/477.py.bak new file mode 100644 index 0000000..1e951e4 --- /dev/null +++ b/solutions/python3/bak/477.py.bak @@ -0,0 +1,8 @@ +class Solution: + def totalHammingDistance(self, nums): + ones, n, res = [0] * 32, len(nums), 0 + for num in nums: + for i, c in enumerate(bin(num)[2:][::-1]): + if c == "1": ones[i] += 1 + for one in ones: res += one * (n - one) + return res \ No newline at end of file diff --git a/solutions/python3/bak/478.py.bak b/solutions/python3/bak/478.py.bak new file mode 100644 index 0000000..1a956cf --- /dev/null +++ b/solutions/python3/bak/478.py.bak @@ -0,0 +1,8 @@ +class Solution: + + def __init__(self, radius, x_center, y_center): + self.x, self.y, self.r = x_center, y_center, radius + + def randPoint(self): + r, angle, scale = random.uniform(0, self.r), random.uniform(0, 2 * math.pi), math.sqrt(random.uniform(0, 1)) + return [self.x + self.r * scale * math.cos(angle), self.y + self.r * scale * math.sin(angle)] \ No newline at end of file diff --git a/solutions/python3/bak/479.py.bak b/solutions/python3/bak/479.py.bak new file mode 100644 index 0000000..6c858be --- /dev/null +++ b/solutions/python3/bak/479.py.bak @@ -0,0 +1,7 @@ +class Solution: + def largestPalindrome(self, n): + """ + :type n: int + :rtype: int + """ + return list(num for i,num in enumerate([0,9,987,123,597,677,1218,877,475]) if i==n)[0] \ No newline at end of file diff --git a/solutions/python3/bak/48.py.bak b/solutions/python3/bak/48.py.bak new file mode 100644 index 0000000..a756db3 --- /dev/null +++ b/solutions/python3/bak/48.py.bak @@ -0,0 +1,3 @@ +class Solution: + def rotate(self, matrix): + matrix[:] = [[row[i] for row in matrix[::-1]] for i in range(len(matrix))] \ No newline at end of file diff --git a/solutions/python3/bak/480.py.bak b/solutions/python3/bak/480.py.bak new file mode 100644 index 0000000..4b5e6c8 --- /dev/null +++ b/solutions/python3/bak/480.py.bak @@ -0,0 +1,9 @@ +class Solution: + def medianSlidingWindow(self, nums, k): + window = sorted(nums[:k]) + medians = [] + for a, b in zip(nums, nums[k:] + [0]): + medians.append((window[k//2] + window[~(k//2)]) / 2.) + window.remove(a) + bisect.insort(window, b) + return medians \ No newline at end of file diff --git a/solutions/python3/bak/481.py.bak b/solutions/python3/bak/481.py.bak new file mode 100644 index 0000000..610d5d7 --- /dev/null +++ b/solutions/python3/bak/481.py.bak @@ -0,0 +1,10 @@ +class Solution(object): + def magicalString(self, n): + cnt, s, two = 0, "1", True + for i in range(n - 1): + if s[i] == "1": + cnt += 1 + s += "2" if two else "1" + else: s += "22" if two else "11" + two = not two + return cnt if n != 1 else 1 \ No newline at end of file diff --git a/solutions/python3/bak/482.py.bak b/solutions/python3/bak/482.py.bak new file mode 100644 index 0000000..437b05e --- /dev/null +++ b/solutions/python3/bak/482.py.bak @@ -0,0 +1,4 @@ +class Solution: + def licenseKeyFormatting(self, S, K): + S = S.replace("-", "").upper()[::-1] + return '-'.join([S[i:i+K] for i in range(0, len(S), K)])[::-1] \ No newline at end of file diff --git a/solutions/python3/bak/483.py.bak b/solutions/python3/bak/483.py.bak new file mode 100644 index 0000000..cbfc5ad --- /dev/null +++ b/solutions/python3/bak/483.py.bak @@ -0,0 +1,8 @@ +class Solution: + def smallestGoodBase(self, n): + n = int(n) + for m in range(int(math.log(n, 2)), 1, -1): + k = int(n ** m ** -1) + if (k ** (m + 1) -1) // (k - 1) == n: + return str(k) + return str(n-1) \ No newline at end of file diff --git a/solutions/python3/bak/484.py.bak b/solutions/python3/bak/484.py.bak new file mode 100644 index 0000000..91846a1 --- /dev/null +++ b/solutions/python3/bak/484.py.bak @@ -0,0 +1,10 @@ +class Solution: + def findPermutation(self, s): + arr, cnt, n = list(range(1, len(s) + 2)), 0, len(s) + for i in range(n + 1): + if i < n and s[i] == "D": + cnt += 1 + elif cnt: + arr[i - cnt:i + 1] = arr[i - cnt:i + 1][::-1] + cnt = 0 + return arr \ No newline at end of file diff --git a/solutions/python3/bak/485.py.bak b/solutions/python3/bak/485.py.bak new file mode 100644 index 0000000..2a23988 --- /dev/null +++ b/solutions/python3/bak/485.py.bak @@ -0,0 +1,13 @@ +class Solution: + def findMaxConsecutiveOnes(self, nums): + """ + :type nums: List[int] + :rtype: int + """ + cons=[0,0] + for num in nums: + if num==1:cons[1]+=1 + else:cons[1]=0 + cons[0]=max(cons[0],cons[1]) + return cons[0] + \ No newline at end of file diff --git a/solutions/python3/bak/486.py.bak b/solutions/python3/bak/486.py.bak new file mode 100644 index 0000000..7dad28e --- /dev/null +++ b/solutions/python3/bak/486.py.bak @@ -0,0 +1,10 @@ +class Solution: + def PredictTheWinner(self, nums): + def dfs(l, r, p1, p2, turn): + if l > r: + return p1 >= p2 + elif turn: + return dfs(l + 1, r, p1 + nums[l], p2, 0) or dfs(l, r - 1, p1 + nums[r], p2, 0) + else: + return dfs(l + 1, r, p1, p2 + nums[l], 1) and dfs(l, r - 1, p1, p2 + nums[r], 1) + return dfs(0, len(nums) - 1, 0, 0, 1) \ No newline at end of file diff --git a/solutions/python3/bak/487.py.bak b/solutions/python3/bak/487.py.bak new file mode 100644 index 0000000..f9214d4 --- /dev/null +++ b/solutions/python3/bak/487.py.bak @@ -0,0 +1,7 @@ +class Solution: + def findMaxConsecutiveOnes(self, nums): + l, zero, mx = 0, -1, 0 + for r, num in enumerate(nums + [0]): + if not num: + l, zero, mx = zero + 1, r, max(mx, r - l) + return mx \ No newline at end of file diff --git a/solutions/python3/bak/488.py.bak b/solutions/python3/bak/488.py.bak new file mode 100644 index 0000000..4e217e7 --- /dev/null +++ b/solutions/python3/bak/488.py.bak @@ -0,0 +1,18 @@ +class Solution: + def findMinStep(self, board, hand): + def dfs(s, c): + if not s: return 0 + res, i = float("inf"), 0 + while i < len(s): + j = i + 1 + while j < len(s) and s[i] == s[j]: j += 1 + incr = 3 - (j - i) + if c[s[i]] >= incr: + incr = 0 if incr < 0 else incr + c[s[i]] -= incr + tep = dfs(s[:i] + s[j:], c) + if tep >= 0: res = min(res, tep + incr) + c[s[i]] += incr + i = j + return res if res != float("inf") else -1 + return dfs(board, collections.Counter(hand)) \ No newline at end of file diff --git a/solutions/python3/bak/489.py.bak b/solutions/python3/bak/489.py.bak new file mode 100644 index 0000000..269762c --- /dev/null +++ b/solutions/python3/bak/489.py.bak @@ -0,0 +1,17 @@ +class Solution: + def cleanRoom(self, robot, move = [(-1, 0), (0, -1), (1, 0), (0, 1)]): + def dfs(i, j, cleaned, ind): + robot.clean() + cleaned.add((i, j)) + k = 0 + for x, y in move[ind:] + move[:ind]: + if (i + x, j + y) not in cleaned and robot.move(): + dfs(i + x, j + y, cleaned, (ind + k) % 4) + robot.turnLeft() + robot.turnLeft() + robot.move() + robot.turnRight() + robot.turnRight() + robot.turnLeft() + k += 1 + dfs(0, 0, set(), 0) \ No newline at end of file diff --git a/solutions/python3/bak/49.py.bak b/solutions/python3/bak/49.py.bak new file mode 100644 index 0000000..e391258 --- /dev/null +++ b/solutions/python3/bak/49.py.bak @@ -0,0 +1,6 @@ +class Solution: + def groupAnagrams(self, strs): + dic = collections.defaultdict(list) + for s in strs: + dic["".join(sorted(s))].append(s) + return list(dic.values()) \ No newline at end of file diff --git a/solutions/python3/bak/490.py.bak b/solutions/python3/bak/490.py.bak new file mode 100644 index 0000000..e32d695 --- /dev/null +++ b/solutions/python3/bak/490.py.bak @@ -0,0 +1,18 @@ +class Solution: + def hasPath(self, maze, start, destination): + m, n, stopped = len(maze), len(maze[0]), set() + def dfs(x, y): + if (x, y) in stopped: + return False + stopped.add((x, y)) + if [x, y] == destination: + return True + for i, j in (-1, 0) , (1, 0), (0, -1), (0, 1): + newX, newY = x, y + while 0 <= newX + i < m and 0 <= newY + j < n and maze[newX + i][newY + j] != 1: + newX += i + newY += j + if dfs(newX, newY): + return True + return False + return dfs(*start) \ No newline at end of file diff --git a/solutions/python3/bak/491.py.bak b/solutions/python3/bak/491.py.bak new file mode 100644 index 0000000..a716c15 --- /dev/null +++ b/solutions/python3/bak/491.py.bak @@ -0,0 +1,6 @@ +class Solution: + def findSubsequences(self, nums): + subs = {()} + for num in nums: + subs |= {sub + (num,) for sub in subs if not sub or sub[-1] <= num} + return [sub for sub in subs if len(sub) >= 2] \ No newline at end of file diff --git a/solutions/python3/bak/492.py.bak b/solutions/python3/bak/492.py.bak new file mode 100644 index 0000000..9efd24c --- /dev/null +++ b/solutions/python3/bak/492.py.bak @@ -0,0 +1,12 @@ +class Solution: + def constructRectangle(self, area): + """ + :type area: int + :rtype: List[int] + """ + import math + l, w = int(math.sqrt(area)), int(math.sqrt(area)) + while l*w!=area: + if area%w==0: l=int(area/w) + else: w-=1 + return [l,w] \ No newline at end of file diff --git a/solutions/python3/bak/493.py.bak b/solutions/python3/bak/493.py.bak new file mode 100644 index 0000000..8788dfd --- /dev/null +++ b/solutions/python3/bak/493.py.bak @@ -0,0 +1,13 @@ +class Solution: + def reversePairs(self, nums: List[int]) -> int: + res = [0] + def merge(nums): + if len(nums) <= 1: return nums + left, right = merge(nums[:len(nums)//2]), merge(nums[len(nums)//2:]) + for r in right: + add = len(left) - bisect.bisect(left, 2 * r) + if not add: break + res[0] += add + return sorted(left+right) + merge(nums) + return res[0] \ No newline at end of file diff --git a/solutions/python3/bak/494.py.bak b/solutions/python3/bak/494.py.bak new file mode 100644 index 0000000..9a35691 --- /dev/null +++ b/solutions/python3/bak/494.py.bak @@ -0,0 +1,10 @@ +class Solution: + def findTargetSumWays(self, nums, S): + d = {S:1} + for i in range(len(nums)): + new_d = collections.defaultdict(int) + for k, v in d.items(): + new_d[k+nums[i]] += v + new_d[k-nums[i]] += v + d = new_d + return d[0] \ No newline at end of file diff --git a/solutions/python3/bak/495.py.bak b/solutions/python3/bak/495.py.bak new file mode 100644 index 0000000..582b31f --- /dev/null +++ b/solutions/python3/bak/495.py.bak @@ -0,0 +1,13 @@ +class Solution: + def findPoisonedDuration(self, timeSeries, duration): + """ + :type timeSeries: List[int] + :type duration: int + :rtype: int + """ + timeSeries.sort() + res, upper = 0, 0 + for i, num in enumerate(timeSeries): + if num > upper: upper = num + res, upper = res + num + duration - upper, num + duration + return res \ No newline at end of file diff --git a/solutions/python3/bak/496.py.bak b/solutions/python3/bak/496.py.bak new file mode 100644 index 0000000..9113ec7 --- /dev/null +++ b/solutions/python3/bak/496.py.bak @@ -0,0 +1,13 @@ +class Solution: + def nextGreaterElement(self, nums1, nums2): + """ + :type nums1: List[int] + :type nums2: List[int] + :rtype: List[int] + """ + out=list() + for num in nums1: + out.append(-1) + for j in range(nums2.index(num)+1,len(nums2)): + if nums2[j]>num: out[-1]=nums2[j]; break + return out \ No newline at end of file diff --git a/solutions/python3/bak/497.py.bak b/solutions/python3/bak/497.py.bak new file mode 100644 index 0000000..6fdb9d8 --- /dev/null +++ b/solutions/python3/bak/497.py.bak @@ -0,0 +1,11 @@ +class Solution: + + def __init__(self, rects): + self.rects, self.ranges, sm = rects, [], 0 + for x1, y1, x2, y2 in rects: + sm += (x2 - x1 + 1) * (y2 - y1 + 1) + self.ranges.append(sm) + + def pick(self): + x1, y1, x2, y2 = self.rects[bisect.bisect_left(self.ranges, random.randint(1, self.ranges[-1]))] + return [random.randint(x1, x2), random.randint(y1, y2)] \ No newline at end of file diff --git a/solutions/python3/bak/498.py.bak b/solutions/python3/bak/498.py.bak new file mode 100644 index 0000000..ca6b81e --- /dev/null +++ b/solutions/python3/bak/498.py.bak @@ -0,0 +1,10 @@ +class Solution: + def findDiagonalOrder(self, matrix): + i, j, d, res, n, m = 0, 0, 1, [], len(matrix), len(matrix and matrix[0]) + while i < n and j < m: + res.append(matrix[i][j]) + if j + 1 < m and (i == 0 and d == 1) or (i == n - 1 and d == -1): j, d = j + 1, -d + elif i + 1 < n and (j == 0 and d == -1) or (j == m - 1 and d == 1): i, d = i + 1, -d + elif d == 1: i, j = i - 1, j + 1 + else: i, j = i + 1, j - 1 + return res \ No newline at end of file diff --git a/solutions/python3/bak/499.py.bak b/solutions/python3/bak/499.py.bak new file mode 100644 index 0000000..1871c84 --- /dev/null +++ b/solutions/python3/bak/499.py.bak @@ -0,0 +1,19 @@ +class Solution: + def findShortestWay(self, maze, ball, hole): + m, n, q, stopped = len(maze), len(maze[0]), [(0, "", ball[0], ball[1])], {(ball[0], ball[1]): [0, ""]} + while q: + dist, pattern, x, y = heapq.heappop(q) + if [x, y] == hole: + return pattern + for i, j, p in ((-1, 0, "u"), (1, 0, "d"), (0, -1, "l"), (0, 1, "r")): + newX, newY, d = x, y, 0 + while 0 <= newX + i < m and 0 <= newY + j < n and maze[newX + i][newY + j] != 1: + newX += i + newY += j + d += 1 + if [newX, newY] == hole: + break + if (newX, newY) not in stopped or [dist + d, pattern + p] < stopped[(newX, newY)]: + stopped[(newX, newY)] = [dist + d, pattern + p] + heapq.heappush(q, (dist + d, pattern + p, newX, newY)) + return "impossible" \ No newline at end of file diff --git a/solutions/python3/bak/5.py.bak b/solutions/python3/bak/5.py.bak new file mode 100644 index 0000000..d6c0d18 --- /dev/null +++ b/solutions/python3/bak/5.py.bak @@ -0,0 +1,9 @@ +class Solution: + def longestPalindrome(self, s: str) -> str: + def check(l, r): + while 0 <= l <= r < len(s) and s[l] == s[r]: + l -= 1 + r += 1 + return s[l + 1:r] + pals = [check(i, i) for i in range(len(s))] + [check(i, i + 1) for i in range(len(s) - 1) if s[i] == s[i + 1]] + return sorted(pals, key = len)[-1] if pals else '' \ No newline at end of file diff --git a/solutions/python3/bak/50.py.bak b/solutions/python3/bak/50.py.bak new file mode 100644 index 0000000..0adeb5f --- /dev/null +++ b/solutions/python3/bak/50.py.bak @@ -0,0 +1,9 @@ +class Solution: + def myPow(self, x: float, n: int) -> float: + if n < 0: + n *= -1 + x = 1 / x + elif not n: + return 1 + half = self.myPow(x, n // 2) + return x * half * half if n % 2 else half * half \ No newline at end of file diff --git a/solutions/python3/bak/500.py.bak b/solutions/python3/bak/500.py.bak new file mode 100644 index 0000000..0c2108f --- /dev/null +++ b/solutions/python3/bak/500.py.bak @@ -0,0 +1,3 @@ +class Solution: + def findWords(self, words): + return [w for w in words if any(not set(w.lower()) - row for row in (set("qwertyuiop"), set("asdfghjkl"), set("zxcvbnm")))] \ No newline at end of file diff --git a/solutions/python3/bak/501.py.bak b/solutions/python3/bak/501.py.bak new file mode 100644 index 0000000..a38e25a --- /dev/null +++ b/solutions/python3/bak/501.py.bak @@ -0,0 +1,20 @@ +# Definition for a binary tree node. +# class TreeNode: +# def __init__(self, x): +# self.val = x +# self.left = None +# self.right = None + +class Solution: + def findMode(self, root): + """ + :type root: TreeNode + :rtype: List[int] + """ + from collections import Counter + def traverse(node): + if node: dic[node.val]+=1; traverse(node.left); traverse(node.right) + dic = collections.Counter() + traverse(root) + mx=max(dic.values(),default=0) + return [k for k,v in dic.items() if v==mx] \ No newline at end of file diff --git a/solutions/python3/bak/502.py.bak b/solutions/python3/bak/502.py.bak new file mode 100644 index 0000000..bd85be5 --- /dev/null +++ b/solutions/python3/bak/502.py.bak @@ -0,0 +1,14 @@ +class Solution: + def findMaximizedCapital(self, k, W, Profits, Capital): + pool, new = [], [(c, p) for c, p in zip(Capital, Profits)] + heapq.heapify(new) + for i in range(k): + while new and new[0][0] <= W: + c, p = heapq.heappop(new) + heapq.heappush(pool, -p) + try: + p = -heapq.heappop(pool) + W += p + except: + break + return W \ No newline at end of file diff --git a/solutions/python3/bak/503.py.bak b/solutions/python3/bak/503.py.bak new file mode 100644 index 0000000..b888390 --- /dev/null +++ b/solutions/python3/bak/503.py.bak @@ -0,0 +1,9 @@ +class Solution: + def nextGreaterElements(self, nums): + stack, res = [], [-1] * len(nums) + for j in range(2): + for i in range(len(nums)): + while stack and (nums[stack[-1]] < nums[i]): res[stack.pop()] = nums[i] + if j == 1 and not stack: break + stack += i, + return res \ No newline at end of file diff --git a/solutions/python3/bak/504.py.bak b/solutions/python3/bak/504.py.bak new file mode 100644 index 0000000..e0e4484 --- /dev/null +++ b/solutions/python3/bak/504.py.bak @@ -0,0 +1,8 @@ +class Solution: + def convertToBase7(self, num): + lead = "" if num > 0 else "0" if num == 0 else "-" + res, num = [], abs(num) + while num: + res.append(int(num % 7)) + num //= 7 + return lead + "".join(str(c) for c in res[::-1]) \ No newline at end of file diff --git a/solutions/python3/bak/505.py.bak b/solutions/python3/bak/505.py.bak new file mode 100644 index 0000000..7d96d96 --- /dev/null +++ b/solutions/python3/bak/505.py.bak @@ -0,0 +1,17 @@ +class Solution: + def shortestDistance(self, maze, start, destination): + m, n, q, stopped = len(maze), len(maze[0]), [(0, start[0], start[1])], {(start[0], start[1]):0} + while q: + dist, x, y = heapq.heappop(q) + if [x, y] == destination: + return dist + for i, j in ((-1, 0), (1, 0), (0, -1), (0, 1)): + newX, newY, d = x, y, 0 + while 0 <= newX + i < m and 0 <= newY + j < n and maze[newX + i][newY + j] != 1: + newX += i + newY += j + d += 1 + if (newX, newY) not in stopped or dist + d < stopped[(newX, newY)]: + stopped[(newX, newY)] = dist + d + heapq.heappush(q, (dist + d, newX, newY)) + return -1 \ No newline at end of file diff --git a/solutions/python3/bak/506.py.bak b/solutions/python3/bak/506.py.bak new file mode 100644 index 0000000..0f02135 --- /dev/null +++ b/solutions/python3/bak/506.py.bak @@ -0,0 +1,4 @@ +class Solution: + def findRelativeRanks(self, nums): + rank = {n:i>2 and str(i+1) or ["Gold","Silver","Bronze"][i] + ' Medal' for i,n in enumerate(sorted(nums,reverse=True))} + return [rank[num] for num in nums] \ No newline at end of file diff --git a/solutions/python3/bak/507.py.bak b/solutions/python3/bak/507.py.bak new file mode 100644 index 0000000..47ad07d --- /dev/null +++ b/solutions/python3/bak/507.py.bak @@ -0,0 +1,11 @@ +class Solution: + def checkPerfectNumber(self, num): + """ + :type num: int + :rtype: bool + """ + sm, div =1, 2 + while div**2<=num: + if num%div==0: sm+=div+(num//div) + div+=1 + return sm==num and div>2 \ No newline at end of file diff --git a/solutions/python3/bak/508.py.bak b/solutions/python3/bak/508.py.bak new file mode 100644 index 0000000..6bc5cfa --- /dev/null +++ b/solutions/python3/bak/508.py.bak @@ -0,0 +1,26 @@ +# Definition for a binary tree node. +# class TreeNode: +# def __init__(self, x): +# self.val = x +# self.left = None +# self.right = None + +class Solution: + def findFrequentTreeSum(self, root): + """ + :type root: TreeNode + :rtype: List[int] + """ + if not root: return [] + def traverse(node): + if not node: return 0 + sm = traverse(node.left) + traverse(node.right) + node.val + if sm in dic: dic[sm] += 1 + else: dic[sm] = 1 + return sm + dic = {} + traverse(root) + mx = max(dic.values()) + return [k for k in dic.keys() if dic[k] == mx] + + \ No newline at end of file diff --git a/solutions/python3/bak/509.py.bak b/solutions/python3/bak/509.py.bak new file mode 100644 index 0000000..42e24cf --- /dev/null +++ b/solutions/python3/bak/509.py.bak @@ -0,0 +1,4 @@ +class Solution: + def fib(self, N: int) -> int: + return self.fib(N - 1) + self.fib(N - 2) if N > 1 else N + \ No newline at end of file diff --git a/solutions/python3/bak/51.py.bak b/solutions/python3/bak/51.py.bak new file mode 100644 index 0000000..fe6b627 --- /dev/null +++ b/solutions/python3/bak/51.py.bak @@ -0,0 +1,16 @@ +class Solution: + def solveNQueens(self, n): + res = [] + def dfs(i, l, r, m, arr): + if i == n: + res.append(arr) + else: + l = l[1:] + [0] + r = [0] + r[:-1] + for j in range(n): + if m[j] == l[j] == r[j] == 0: + l[j] = r[j] = m[j] = 1 + dfs(i + 1, l, r, m, arr + [("." * j) + "Q" + ("." * (n - j - 1))]) + l[j] = r[j] = m[j] = 0 + dfs(0, [0] * n, [0] * n, [0] * n, []) + return res \ No newline at end of file diff --git a/solutions/python3/bak/510.py.bak b/solutions/python3/bak/510.py.bak new file mode 100644 index 0000000..9ebaf14 --- /dev/null +++ b/solutions/python3/bak/510.py.bak @@ -0,0 +1,10 @@ +class Solution: + def inorderSuccessor(self, node: 'Node') -> 'Node': + if node.right: + node = node.right + while node.left: + node = node.left + return node + while node.parent and node.parent.left != node: + node = node.parent + return node.parent \ No newline at end of file diff --git a/solutions/python3/bak/513.py.bak b/solutions/python3/bak/513.py.bak new file mode 100644 index 0000000..24c840b --- /dev/null +++ b/solutions/python3/bak/513.py.bak @@ -0,0 +1,14 @@ +# Definition for a binary tree node. +# class TreeNode: +# def __init__(self, x): +# self.val = x +# self.left = None +# self.right = None + +class Solution: + def findBottomLeftValue(self, root: TreeNode) -> int: + bfs = [root] + while bfs: + left = bfs[0].val + bfs = [child for node in bfs for child in (node.left, node.right) if child] + return left \ No newline at end of file diff --git a/solutions/python3/bak/514.py.bak b/solutions/python3/bak/514.py.bak new file mode 100644 index 0000000..93093e6 --- /dev/null +++ b/solutions/python3/bak/514.py.bak @@ -0,0 +1,9 @@ +class Solution: + def findRotateSteps(self, ring, key): + ind, n, dp, pre = collections.defaultdict(list), len(ring), [0] * len(ring), key[0] + for i, c in enumerate(ring): ind[c].append(i) + for i in ind[key[0]]: dp[i] = min(i, n - i) + 1 + for c in key[1:]: + for i in ind[c]: dp[i] = min(dp[j] + min(i - j, j + n - i) if i >= j else dp[j] + min(j - i, i + n - j) for j in ind[pre]) + 1 + pre = c + return min(dp[i] for i in ind[key[-1]]) \ No newline at end of file diff --git a/solutions/python3/bak/515.py.bak b/solutions/python3/bak/515.py.bak new file mode 100644 index 0000000..4af09ed --- /dev/null +++ b/solutions/python3/bak/515.py.bak @@ -0,0 +1,23 @@ +# Definition for a binary tree node. +# class TreeNode: +# def __init__(self, x): +# self.val = x +# self.left = None +# self.right = None + +class Solution: + def largestValues(self, root): + """ + :type root: TreeNode + :rtype: List[int] + """ + from collections import deque + q, res, target = deque([root]) if root else None, [root.val] if root else [], root + while q: + node = q.popleft() + if node.left: q.append(node.left) + if node.right: q.append(node.right) + if node == target and q: + res.append(max([i.val for i in q])) + target = q[-1] + return res \ No newline at end of file diff --git a/solutions/python3/bak/516.py.bak b/solutions/python3/bak/516.py.bak new file mode 100644 index 0000000..18cd1de --- /dev/null +++ b/solutions/python3/bak/516.py.bak @@ -0,0 +1,8 @@ +class Solution: + def longestPalindromeSubseq(self, s): + dp = [[0 for j in range(len(s))] for i in range(len(s))] + for i in range(len(s) - 1, -1, -1): + dp[i][i] = 1 + for j in range(i + 1, len(s)): + dp[i][j] = dp[i + 1][j - 1] + 2 if s[i] == s[j] else max(dp[i + 1][j], dp[i][j - 1]) + return dp[0][len(s) - 1] \ No newline at end of file diff --git a/solutions/python3/bak/517.py.bak b/solutions/python3/bak/517.py.bak new file mode 100644 index 0000000..edf8660 --- /dev/null +++ b/solutions/python3/bak/517.py.bak @@ -0,0 +1,8 @@ +class Solution: + def findMinMoves(self, machines): + target, n, sm, res, total = sum(machines) // len(machines), len(machines), 0, 0, sum(machines) + if target * n != total: return -1 + for i in range(n): + l, sm, r = target * i - sm, sm + machines[i], target * (n - i - 1) - total + sm + machines[i] + res = max(res, l + r, l, r) + return res \ No newline at end of file diff --git a/solutions/python3/bak/519.py.bak b/solutions/python3/bak/519.py.bak new file mode 100644 index 0000000..fa61eab --- /dev/null +++ b/solutions/python3/bak/519.py.bak @@ -0,0 +1,14 @@ +class Solution: + + def __init__(self, n_rows, n_cols): + self.rows, self.cols, self.used = n_rows, n_cols, set() + + def flip(self): + while True: + r, c = random.randint(1, self.rows), random.randint(1, self.cols) + if (r, c) not in self.used: + self.used.add((r, c)) + return [r - 1, c - 1] + + def reset(self): + self.used = set() \ No newline at end of file diff --git a/solutions/python3/bak/52.py.bak b/solutions/python3/bak/52.py.bak new file mode 100644 index 0000000..dcef9d3 --- /dev/null +++ b/solutions/python3/bak/52.py.bak @@ -0,0 +1,16 @@ +class Solution: + def totalNQueens(self, n): + res = [0] + def dfs(i, l, r, m): + if i == n: + res[0] += 1 + else: + l = l[1:] + [0] + r = [0] + r[:-1] + for j in range(n): + if m[j] == l[j] == r[j] == 0: + l[j] = r[j] = m[j] = 1 + dfs(i + 1, l, r, m) + l[j] = r[j] = m[j] = 0 + dfs(0, [0] * n, [0] * n, [0] * n) + return res[0] \ No newline at end of file diff --git a/solutions/python3/bak/520.py.bak b/solutions/python3/bak/520.py.bak new file mode 100644 index 0000000..2cc7b21 --- /dev/null +++ b/solutions/python3/bak/520.py.bak @@ -0,0 +1,3 @@ +class Solution: + def detectCapitalUse(self, word): + return word[0].isupper() and word[1:].islower() or word.isupper() or word.islower() \ No newline at end of file diff --git a/solutions/python3/bak/521.py.bak b/solutions/python3/bak/521.py.bak new file mode 100644 index 0000000..266f40f --- /dev/null +++ b/solutions/python3/bak/521.py.bak @@ -0,0 +1,8 @@ +class Solution: + def findLUSlength(self, a, b): + """ + :type a: str + :type b: str + :rtype: int + """ + return -1 if a == b else max(len(a), len(b)) \ No newline at end of file diff --git a/solutions/python3/bak/522.py.bak b/solutions/python3/bak/522.py.bak new file mode 100644 index 0000000..c4744c7 --- /dev/null +++ b/solutions/python3/bak/522.py.bak @@ -0,0 +1,11 @@ +class Solution: + def findLUSlength(self, strs): + def find(s, t): + i = 0 + for c in t: + if c == s[i]: i += 1 + if i == len(s): return True + return False + for s in sorted(strs, key=len, reverse=True): + if sum(find(s, t) for t in strs) == 1: return len(s) + return -1 \ No newline at end of file diff --git a/solutions/python3/bak/523.py.bak b/solutions/python3/bak/523.py.bak new file mode 100644 index 0000000..a0e67fc --- /dev/null +++ b/solutions/python3/bak/523.py.bak @@ -0,0 +1,9 @@ +class Solution: + def checkSubarraySum(self, nums, k): + if not k: return any(nums[i] == nums[i - 1] == 0 for i in range(1, len(nums))) + mods, sm = set(), 0 + for i, num in enumerate(nums): + sm = (sm + num) % k + if (sm in mods and num or (i and not nums[i - 1])) or (not sm and i): return True + mods |= {sm} + return False \ No newline at end of file diff --git a/solutions/python3/bak/524.py.bak b/solutions/python3/bak/524.py.bak new file mode 100644 index 0000000..314b88c --- /dev/null +++ b/solutions/python3/bak/524.py.bak @@ -0,0 +1,9 @@ +class Solution: + def findLongestWord(self, s, d): + d.sort(key = lambda x: (-len(x), x)) + for w in d: + i = 0 + for c in s: + if c == w[i]: i += 1 + if i == len(w): return w + return "" \ No newline at end of file diff --git a/solutions/python3/bak/525.py.bak b/solutions/python3/bak/525.py.bak new file mode 100644 index 0000000..92d472c --- /dev/null +++ b/solutions/python3/bak/525.py.bak @@ -0,0 +1,10 @@ +class Solution: + def findMaxLength(self, nums: List[int]) -> int: + ind, res, sm = {0:-1}, 0, 0 + for i, num in enumerate(nums): + sm += num and 1 or -1 + if sm in ind: + res = max(res, i - ind[sm]) + else: + ind[sm] = i + return res \ No newline at end of file diff --git a/solutions/python3/bak/526.py.bak b/solutions/python3/bak/526.py.bak new file mode 100644 index 0000000..925f801 --- /dev/null +++ b/solutions/python3/bak/526.py.bak @@ -0,0 +1,7 @@ +memo = {} +class Solution: + def countArrangement(self, N, arr = None): + if not arr: arr = tuple(range(1, N + 1)) + if (N, arr) in memo or N == 1: return N == 1 and 1 or memo[(N, arr)] + memo[(N, arr)] = sum([self.countArrangement(N-1, arr[:j]+arr[j + 1:]) for j in range(len(arr)) if arr[j]%N==0 or N%arr[j]==0]) + return memo[(N, arr)] \ No newline at end of file diff --git a/solutions/python3/bak/527.py.bak b/solutions/python3/bak/527.py.bak new file mode 100644 index 0000000..8cd4372 --- /dev/null +++ b/solutions/python3/bak/527.py.bak @@ -0,0 +1,13 @@ +class Solution: + def wordsAbbreviation(self, dict): + abb = collections.defaultdict(int) + for i, w in enumerate(dict): + for j in range(1, len(w) - 2): + abb[w[:j] + str(len(w) - j - 1) + w[-1]] += 1 + for i, w in enumerate(dict): + for j in range(1, len(w) - 2): + new = w[:j] + str(len(w) - j - 1) + w[-1] + if abb[new] == 1: + dict[i] = new + break + return dict \ No newline at end of file diff --git a/solutions/python3/bak/528.py.bak b/solutions/python3/bak/528.py.bak new file mode 100644 index 0000000..a12c1d7 --- /dev/null +++ b/solutions/python3/bak/528.py.bak @@ -0,0 +1,18 @@ +class Solution: + + def __init__(self, w): + self.ranges, sm = [], 0 + for weight in w: + self.ranges.append([sm, sm + weight]) + sm += weight + self.mn, self.mx = 1, sm + def pickIndex(self): + num, l, r = random.randint(self.mn, self.mx), 0, len(self.ranges) - 1 + while l <= r: + mid = (l + r) // 2 + if self.ranges[mid][1] < num: + l = mid + 1 + elif num <= self.ranges[mid][0]: + r = mid - 1 + else: + return mid \ No newline at end of file diff --git a/solutions/python3/bak/529.py.bak b/solutions/python3/bak/529.py.bak new file mode 100644 index 0000000..d25b5df --- /dev/null +++ b/solutions/python3/bak/529.py.bak @@ -0,0 +1,19 @@ +class Solution(object): + def updateBoard(self, board, click): + def explore(i, j): + visited.add((i, j)) + if board[i][j] == "M": board[i][j] = "X" + else: + points = ((i - 1, j), (i + 1, j), (i, j - 1), (i, j + 1), (i - 1, j - 1), (i - 1, j + 1), (i + 1, j + 1), (i + 1, j - 1)) + cnt, adj = 0, [] + for p in points: + if 0 <= p[0] < m and 0 <= p[1] < n: + if board[p[0]][p[1]] == "M": cnt += 1 + elif p not in visited: adj += p, + if cnt == 0: + board[i][j] = "B" + for p in adj: explore(p[0], p[1]) + else: board[i][j] = str(cnt) + m, n, visited = len(board), len(board and board[0]), set() + explore(click[0], click[1]) + return board \ No newline at end of file diff --git a/solutions/python3/bak/53.py.bak b/solutions/python3/bak/53.py.bak new file mode 100644 index 0000000..6e5fab8 --- /dev/null +++ b/solutions/python3/bak/53.py.bak @@ -0,0 +1,7 @@ +class Solution: + def maxSubArray(self, nums): + sm, mn, mx = 0, 0, -float("inf") + for num in nums: + sm += num + mx, mn = max(mx, sm - mn), min(mn, sm) + return mx \ No newline at end of file diff --git a/solutions/python3/bak/530.py.bak b/solutions/python3/bak/530.py.bak new file mode 100644 index 0000000..33bb35f --- /dev/null +++ b/solutions/python3/bak/530.py.bak @@ -0,0 +1,18 @@ +# Definition for a binary tree node. +# class TreeNode: +# def __init__(self, x): +# self.val = x +# self.left = None +# self.right = None + +class Solution: + def getMinimumDifference(self, root: TreeNode) -> int: + self.res = sys.maxsize + def dfs(node): + if not node: return sys.maxsize, -sys.maxsize + lMn, lMx = dfs(node.left) + rMn, rMx = dfs(node.right) + self.res = min(self.res, node.val - lMx, rMn - node.val) + return min(node.val, lMn), max(node.val, rMx) + dfs(root) + return self.res \ No newline at end of file diff --git a/solutions/python3/bak/531.py.bak b/solutions/python3/bak/531.py.bak new file mode 100644 index 0000000..eccaa2c --- /dev/null +++ b/solutions/python3/bak/531.py.bak @@ -0,0 +1,16 @@ +class Solution: + def findLonelyPixel(self, grid: List[List[str]]) -> int: + rows = collections.defaultdict(list) + cols = collections.defaultdict(list) + m, n = len(grid), len(grid[0]) + for i in range(m): + for j in range(n): + if grid[i][j] == 'B': + rows[i].append(j) + cols[j].append(i) + res = 0 + for i in range(m): + for j in range(n): + if grid[i][j] == 'B' and rows[i] == [j] and cols[j] == [i]: + res += 1 + return res \ No newline at end of file diff --git a/solutions/python3/bak/532.py.bak b/solutions/python3/bak/532.py.bak new file mode 100644 index 0000000..8d264f0 --- /dev/null +++ b/solutions/python3/bak/532.py.bak @@ -0,0 +1,16 @@ +class Solution: + def findPairs(self, nums, k): + """ + :type nums: List[int] + :type k: int + :rtype: int + """ + dic, pair = {}, 0 + for num in nums: + if (num-k in dic or num+k in dic) and (not num in dic or (k==0 and dic[num]==1)) and k>=0: + if num-k in dic and k!=0: pair+=1 + if num+k in dic: pair+=1 + if num in dic: dic[num]+=1; continue + if num in dic: continue + dic[num]=1 + return pair \ No newline at end of file diff --git a/solutions/python3/bak/533.py.bak b/solutions/python3/bak/533.py.bak new file mode 100644 index 0000000..da9582d --- /dev/null +++ b/solutions/python3/bak/533.py.bak @@ -0,0 +1,20 @@ +class Solution: + def findBlackPixel(self, picture, N): + m, n, res = len(picture), len(picture[0]), 0 + for row in picture: + r_cnt = row.count("B") + if r_cnt != N: + continue + for j in range(n): + if row[j] == "B": + col_cnt = same = 0 + for i in range(m): + if picture[i][j] == "B": + col_cnt += 1 + if picture[i] == row: + same += 1 + else: + break + if r_cnt == col_cnt == same: + res += 1 + return res \ No newline at end of file diff --git a/solutions/python3/bak/536.py.bak b/solutions/python3/bak/536.py.bak new file mode 100644 index 0000000..bde4baf --- /dev/null +++ b/solutions/python3/bak/536.py.bak @@ -0,0 +1,27 @@ +# Definition for a binary tree node. +# class TreeNode: +# def __init__(self, x): +# self.val = x +# self.left = None +# self.right = None + +class Solution: + def str2tree(self, s): + stack, cur = [], "" + for i, c in enumerate(s): + if c.isnumeric() or c == "-": + cur += c + elif not cur: + if c == ")": + stack.pop() + else: + node = TreeNode(int(cur)) + if stack: + if not stack[-1].left: + stack[-1].left = node + else: + stack[-1].right = node + cur = "" + if c == "(": + stack.append(node) + return stack and stack[0] or (cur and TreeNode(int(cur))) or [] \ No newline at end of file diff --git a/solutions/python3/bak/537.py.bak b/solutions/python3/bak/537.py.bak new file mode 100644 index 0000000..3e05048 --- /dev/null +++ b/solutions/python3/bak/537.py.bak @@ -0,0 +1,13 @@ +class Solution: + def complexNumberMultiply(self, a, b): + """ + :type a: str + :type b: str + :rtype: str + """ + re, im = 0, 0 + re_a, im_a = list(map(int,a[:-1].split("+"))) + re_b, im_b = list(map(int,b[:-1].split("+"))) + re += re_a * re_b - im_a * im_b + im += re_a * im_b + re_b *im_a + return str(re)+"+"+str(im)+"i" \ No newline at end of file diff --git a/solutions/python3/bak/538.py.bak b/solutions/python3/bak/538.py.bak new file mode 100644 index 0000000..f78cd23 --- /dev/null +++ b/solutions/python3/bak/538.py.bak @@ -0,0 +1,21 @@ +# Definition for a binary tree node. +# class TreeNode: +# def __init__(self, x): +# self.val = x +# self.left = None +# self.right = None + +class Solution: + def convertBST(self, root): + """ + :type root: TreeNode + :rtype: TreeNode + """ + def traverse(node): + if not node: return + traverse(node.right) + node.val = residue[0] = node.val + residue[0] + traverse(node.left) + return node + residue = [0] + return traverse(root) \ No newline at end of file diff --git a/solutions/python3/bak/539.py.bak b/solutions/python3/bak/539.py.bak new file mode 100644 index 0000000..59fdd28 --- /dev/null +++ b/solutions/python3/bak/539.py.bak @@ -0,0 +1,11 @@ +class Solution: + def findMinDifference(self, tp): + def getMinute(t): + h , m = t.split(":") + return int(h) * 60 + int(m) + tp = sorted(map(getMinute, tp)) + mn = sys.maxsize + for i in range(len(tp) - 1): + mn = min(mn, tp[i + 1] - tp[i]) + if mn == 0: return 0 + return min(mn, 1440 + tp[0] - tp[-1]) \ No newline at end of file diff --git a/solutions/python3/bak/54.py.bak b/solutions/python3/bak/54.py.bak new file mode 100644 index 0000000..aead196 --- /dev/null +++ b/solutions/python3/bak/54.py.bak @@ -0,0 +1,32 @@ +class Solution: + def spiralOrder(self, matrix: List[List[int]]) -> List[int]: + res = [] + seen = set() + def dfs(i, j, d): + seen.add((i, j)) + res.append(matrix[i][j]) + if d == 'r': + if j + 1 < n and (i, j + 1) not in seen: + dfs(i, j + 1, d) + elif i + 1 < m and (i + 1, j) not in seen: + dfs(i + 1, j , 'd') + elif d == 'd': + if i + 1 < m and (i + 1, j) not in seen: + dfs(i + 1, j , d) + elif j and (i, j - 1) not in seen: + dfs(i, j - 1, 'l') + elif d == 'l': + if j and (i, j - 1) not in seen: + dfs(i, j - 1, d) + elif i and (i - 1, j) not in seen: + dfs(i - 1, j, 'u') + else: + if i and (i - 1, j) not in seen: + dfs(i - 1, j, d) + elif j + 1 < n and (i, j + 1) not in seen: + dfs(i, j + 1, 'r') + if not matrix: return [] + m, n = len(matrix), len(matrix[0]) + dfs(0, 0, 'r') + return res + \ No newline at end of file diff --git a/solutions/python3/bak/540.py.bak b/solutions/python3/bak/540.py.bak new file mode 100644 index 0000000..b248295 --- /dev/null +++ b/solutions/python3/bak/540.py.bak @@ -0,0 +1,17 @@ +class Solution: + def singleNonDuplicate(self, nums): + """ + :type nums: List[int] + :rtype: int + """ + left, right = 0, len(nums)-1 + while left<=right: + mid = (left+right)//2 + if mid+1=0 and nums[mid] == nums[mid-1]: + if mid % 2 == 0: right = mid-2 + else: left = mid+1 + else: return nums[mid] + \ No newline at end of file diff --git a/solutions/python3/bak/541.py.bak b/solutions/python3/bak/541.py.bak new file mode 100644 index 0000000..778b1b6 --- /dev/null +++ b/solutions/python3/bak/541.py.bak @@ -0,0 +1,8 @@ +class Solution: + def reverseStr(self, s, k): + """ + :type s: str + :type k: int + :rtype: str + """ + return "".join([s[i:i+k][::-1]+s[i+k:i+2*k] if len(s)>=i or len(s)>i-k else s[k*i:][::-1] for i in range(0,len(s),k*2)]) \ No newline at end of file diff --git a/solutions/python3/bak/542.py.bak b/solutions/python3/bak/542.py.bak new file mode 100644 index 0000000..314765b --- /dev/null +++ b/solutions/python3/bak/542.py.bak @@ -0,0 +1,19 @@ +class Solution: + def updateMatrix(self, matrix): + m, n = len(matrix), len(matrix and matrix[0]) + for i in range(m): + for j in range(n): + if matrix[i][j] != 0: + matrix[i][j] = float("inf") + if i > 0 and matrix[i - 1][j] + 1 < matrix[i][j]: + matrix[i][j] = matrix[i - 1][j] + 1 + if j > 0 and matrix[i][j - 1] + 1 < matrix[i][j]: + matrix[i][j] = matrix[i][j - 1] + 1 + for i in range(m - 1, -1, -1): + for j in range(n - 1, -1, -1): + if matrix[i][j] != 0: + if i + 1 < m and matrix[i + 1][j] + 1 < matrix[i][j]: + matrix[i][j] = matrix[i + 1][j] + 1 + if j + 1 < n and matrix[i][j + 1] + 1 < matrix[i][j]: + matrix[i][j] = matrix[i][j + 1] + 1 + return matrix \ No newline at end of file diff --git a/solutions/python3/bak/543.py.bak b/solutions/python3/bak/543.py.bak new file mode 100644 index 0000000..accb244 --- /dev/null +++ b/solutions/python3/bak/543.py.bak @@ -0,0 +1,21 @@ +# Definition for a binary tree node. +# class TreeNode: +# def __init__(self, x): +# self.val = x +# self.left = None +# self.right = None + +class Solution: + def diameterOfBinaryTree(self, root): + """ + :type root: TreeNode + :rtype: int + """ + res = [0] + def traverse(node): + if not node: return 0 + left, right = traverse(node.left), traverse(node.right) + res[0] = max(left+right, res[0]) + return 1+ max(left, right) + traverse(root) + return res[0] \ No newline at end of file diff --git a/solutions/python3/bak/544.py.bak b/solutions/python3/bak/544.py.bak new file mode 100644 index 0000000..98af6f7 --- /dev/null +++ b/solutions/python3/bak/544.py.bak @@ -0,0 +1,5 @@ +class Solution: + def findContestMatch(self, n): + arr = [str(i) for i in range(1, n + 1)] + while len(arr) > 1: arr = ["(" + arr[i] + "," + arr[len(arr) - 1 - i] + ")" for i in range(len(arr) // 2)] + return ",".join(arr) \ No newline at end of file diff --git a/solutions/python3/bak/545.py.bak b/solutions/python3/bak/545.py.bak new file mode 100644 index 0000000..f36a6ae --- /dev/null +++ b/solutions/python3/bak/545.py.bak @@ -0,0 +1,41 @@ +# Definition for a binary tree node. +# class TreeNode: +# def __init__(self, x): +# self.val = x +# self.left = None +# self.right = None + +class Solution: + def boundaryOfBinaryTree(self, root: TreeNode) -> List[int]: + if not root: return [] + used, res, r = {root}, [root.val], [] + def lb(node): + if node not in used: + used.add(node) + res.append(node.val) + if node.left: + lb(node.left) + elif node.right: + lb(node.right) + def rb(node): + if node not in used: + used.add(node) + r.append(node.val) + if node.right: + rb(node.right) + elif node.left: + rb(node.left) + def lv(node): + if not node.left and not node.right and node not in used: + used.add(node) + res.append(node.val) + if node.left: + lv(node.left) + if node.right: + lv(node.right) + if root.left: + lb(root.left) + lv(root) + if root.right: + rb(root.right) + return res + r[::-1] \ No newline at end of file diff --git a/solutions/python3/bak/546.py.bak b/solutions/python3/bak/546.py.bak new file mode 100644 index 0000000..926bffe --- /dev/null +++ b/solutions/python3/bak/546.py.bak @@ -0,0 +1,18 @@ +class Solution: + def removeBoxes(self, A): + n = len(A) + memo = [[[0] * n for _ in range(n) ] for _ in range(n)] + def dp(i, j, k): + if i > j: return 0 + if not memo[i][j][k]: + m = i + while m+1 <= j and A[m+1] == A[i]: + m += 1 + i, k = m, k + m - i + ans = dp(i+1, j, 0) + (k+1) ** 2 + for m in range(i+1, j+1): + if A[i] == A[m]: + ans = max(ans, dp(i+1, m-1, 0) + dp(m, j, k+1)) + memo[i][j][k] = ans + return memo[i][j][k] + return dp(0, n-1, 0) \ No newline at end of file diff --git a/solutions/python3/bak/547.py.bak b/solutions/python3/bak/547.py.bak new file mode 100644 index 0000000..64ab8c2 --- /dev/null +++ b/solutions/python3/bak/547.py.bak @@ -0,0 +1,10 @@ +class Solution: + def findCircleNum(self, m): + res, n = 0, len(m) + def explore(i): + m[i][i] = 0 + for j in range(n): + if i != j and m[i][j] == m[j][j] == 1: explore(j) + for i in range(n): + if m[i][i] == 1: explore(i); res += 1 + return res \ No newline at end of file diff --git a/solutions/python3/bak/549.py.bak b/solutions/python3/bak/549.py.bak new file mode 100644 index 0000000..e256609 --- /dev/null +++ b/solutions/python3/bak/549.py.bak @@ -0,0 +1,21 @@ +class Solution: + def longestConsecutive(self, root): + dec, inc = {}, {} + def dfs(node): + if not node: return 0 + l = dfs(node.left) + r = dfs(node.right) + incL = inc[node.left] + 1 if node.left and node.val == node.left.val + 1 else 1 + incR = inc[node.right] + 1 if node.right and node.val == node.right.val + 1 else 1 + inc[node] = max(incL, incR) + decL = dec[node.left] + 1 if node.left and node.val == node.left.val - 1 else 1 + decR = dec[node.right] + 1 if node.right and node.val == node.right.val - 1 else 1 + dec[node] = max(decL, decR) + if node.left and node.right and node.left.val == node.val - 1 and node.right.val == node.val + 1: + m = inc[node.left] + dec[node.right] + 1 + elif node.left and node.right and node.left.val == node.val + 1 and node.right.val == node.val - 1: + m = dec[node.left] + inc[node.right] + 1 + else: + m = 0 + return max(m, l, r, inc[node], dec[node]) + return dfs(root) \ No newline at end of file diff --git a/solutions/python3/bak/55.py.bak b/solutions/python3/bak/55.py.bak new file mode 100644 index 0000000..2a7b4fc --- /dev/null +++ b/solutions/python3/bak/55.py.bak @@ -0,0 +1,11 @@ +class Solution: + def canJump(self, nums): + """ + :type nums: List[int] + :rtype: bool + """ + i = mx = 0 + while i < len(nums) and i <= mx: + if nums[i] + i >= len(nums) - 1: return True + mx, i = max(mx, i + nums[i]), i + 1 + return False \ No newline at end of file diff --git a/solutions/python3/bak/551.py.bak b/solutions/python3/bak/551.py.bak new file mode 100644 index 0000000..4c21429 --- /dev/null +++ b/solutions/python3/bak/551.py.bak @@ -0,0 +1,7 @@ +class Solution: + def checkRecord(self, s): + """ + :type s: str + :rtype: bool + """ + return False if "LLL" in s or s.count("A")>1 else True \ No newline at end of file diff --git a/solutions/python3/bak/553.py.bak b/solutions/python3/bak/553.py.bak new file mode 100644 index 0000000..cdc5682 --- /dev/null +++ b/solutions/python3/bak/553.py.bak @@ -0,0 +1,9 @@ +class Solution: + def optimalDivision(self, nums): + """ + :type nums: List[int] + :rtype: str + """ + if len(nums) == 1: return str(nums[0]) + elif len(nums) == 2: return str(nums[0])+"/"+str(nums[1]) + else: return str(nums[0])+"/("+"/".join(str(i) for i in nums[1:])+")" \ No newline at end of file diff --git a/solutions/python3/bak/554.py.bak b/solutions/python3/bak/554.py.bak new file mode 100644 index 0000000..070d800 --- /dev/null +++ b/solutions/python3/bak/554.py.bak @@ -0,0 +1,18 @@ +class Solution: + def leastBricks(self, wall: List[List[int]]) -> int: + m = len(wall) + sm = sum(wall[0]) + cnt = collections.defaultdict(int) + for i in range(m): + x = 0 + for num in wall[i]: + x += num + if x != sm: + cnt[x] += 1 + mx = 0 + for i in range(m): + x = 0 + for num in wall[i]: + x += num + mx = max(mx, cnt[x]) + return m - mx \ No newline at end of file diff --git a/solutions/python3/bak/555.py.bak b/solutions/python3/bak/555.py.bak new file mode 100644 index 0000000..9be1f53 --- /dev/null +++ b/solutions/python3/bak/555.py.bak @@ -0,0 +1,11 @@ +class Solution: + def splitLoopedString(self, strs): + arr, res = [s > s[::-1] and s or s[::-1] for s in strs], "" + for i, word in enumerate(strs): + for w in (word, word[::-1]): + s, ind = "", 0 + for j in range(len(w)): + if not s or w[j:] + w[:j] > s: s, ind = w[j:] + w[:j], j + cur = w[ind:] + "".join(arr[i + 1:]) + "".join(arr[:i]) + w[:ind] + if not res or cur > res: res = cur + return res \ No newline at end of file diff --git a/solutions/python3/bak/556.py.bak b/solutions/python3/bak/556.py.bak new file mode 100644 index 0000000..41563b3 --- /dev/null +++ b/solutions/python3/bak/556.py.bak @@ -0,0 +1,13 @@ +class Solution: + def nextGreaterElement(self, n): + arr = [c for c in str(n)] + for l in range(len(arr) - 2, -1, -1): + r = len(arr) - 1 + while l < r and arr[r] <= arr[l]: + r -= 1 + if l != r: + arr[l], arr[r] = arr[r], arr[l] + arr[l + 1:] = sorted(arr[l + 1:]) + num = int("".join(arr)) + return num if -2 ** 31 <= num <= 2 ** 31 - 1 else -1 + return -1 \ No newline at end of file diff --git a/solutions/python3/bak/557.py.bak b/solutions/python3/bak/557.py.bak new file mode 100644 index 0000000..7eba590 --- /dev/null +++ b/solutions/python3/bak/557.py.bak @@ -0,0 +1,11 @@ +class Solution: + def reverseWords(self, s): + """ + :type s: str + :rtype: str + """ + j, s_out=0, str() + for i, char in enumerate(s): + if i==len(s)-1: s_out+=s[j:i+1][::-1]; return "".join(s_out) + if char==" ": s_out+=s[j:i][::-1]; j=i+1; s_out+=" " + return "".join(s_out) \ No newline at end of file diff --git a/solutions/python3/bak/558.py.bak b/solutions/python3/bak/558.py.bak new file mode 100644 index 0000000..ccb6b1c --- /dev/null +++ b/solutions/python3/bak/558.py.bak @@ -0,0 +1,16 @@ +class Solution: + def intersect(self, q1, q2): + if q1.isLeaf: + return q1.val and q1 or q2 + elif q2.isLeaf: + return q2.val and q2 or q1 + else: + tLeft = self.intersect(q1.topLeft, q2.topLeft) + tRight = self.intersect(q1.topRight, q2.topRight) + bLeft = self.intersect(q1.bottomLeft, q2.bottomLeft) + bRight = self.intersect(q1.bottomRight, q2.bottomRight) + if tLeft.isLeaf and tRight.isLeaf and bLeft.isLeaf and bRight.isLeaf and tLeft.val == tRight.val == bLeft.val == bRight.val: + node = Node(tLeft.val, True, None, None, None, None) + else: + node = Node(False, False, tLeft, tRight, bLeft, bRight) + return node \ No newline at end of file diff --git a/solutions/python3/bak/56.py.bak b/solutions/python3/bak/56.py.bak new file mode 100644 index 0000000..ea0a995 --- /dev/null +++ b/solutions/python3/bak/56.py.bak @@ -0,0 +1,23 @@ +# Definition for an interval. +# class Interval: +# def __init__(self, s=0, e=0): +# self.start = s +# self.end = e + +class Solution: + def merge(self, intervals): + """ + :type intervals: List[Interval] + :rtype: List[Interval] + """ + res = [] + intervals.sort(key = lambda x: x.end) + for intr in intervals: + if not re: + res.append([intr.start, intr.end]) + else: + s = intr.start + while res and res[-1][1] >= intr.start: + s = min(s, res.pop()[0]) + res.append([s, intr.end]) + return res \ No newline at end of file diff --git a/solutions/python3/bak/560.py.bak b/solutions/python3/bak/560.py.bak new file mode 100644 index 0000000..c5b0f61 --- /dev/null +++ b/solutions/python3/bak/560.py.bak @@ -0,0 +1,7 @@ +class Solution: + def subarraySum(self, nums, k): + sums, res, sm = {}, 0, 0 + for i in range(len(nums)): + sums[sm], sm = sm in sums and sums[sm] + 1 or 1, sm + nums[i] + if sm - k in sums: res += sums[sm - k] + return res \ No newline at end of file diff --git a/solutions/python3/bak/561.py.bak b/solutions/python3/bak/561.py.bak new file mode 100644 index 0000000..22ee5a2 --- /dev/null +++ b/solutions/python3/bak/561.py.bak @@ -0,0 +1,14 @@ +class Solution: + def arrayPairSum(self, nums): + """ + :type nums: List[int] + :rtype: int + """ + nums.sort() + sum=0 + while nums: + num1=nums.pop() + num2=nums.pop() + sum+=num2 + return sum + \ No newline at end of file diff --git a/solutions/python3/bak/562.py.bak b/solutions/python3/bak/562.py.bak new file mode 100644 index 0000000..b2b6c6a --- /dev/null +++ b/solutions/python3/bak/562.py.bak @@ -0,0 +1,12 @@ +class Solution: + def longestLine(self, M): + hor, ver, dig, aDig, mx, m, n = {}, {}, {}, {}, 0, len(M), len(M and M[0]) + for i in range(m): + for j in range(n): + if M[i][j]: + ver[(i, j)] = j > 0 and M[i][j - 1] and ver[(i, j - 1)] + 1 or 1 + hor[(i, j)] = i > 0 and M[i - 1][j] and hor[(i - 1, j)] + 1 or 1 + dig[(i, j)] = i > 0 and j > 0 and M[i - 1][j - 1] and dig[(i - 1, j - 1)] + 1 or 1 + aDig[(i, j)] = i > 0 and j + 1 < n and M[i - 1][j + 1] and aDig[(i - 1, j + 1)] + 1 or 1 + mx = max(mx, ver[(i, j)], hor[(i, j)], dig[(i, j)], aDig[(i, j)]) + return mx \ No newline at end of file diff --git a/solutions/python3/bak/563.py.bak b/solutions/python3/bak/563.py.bak new file mode 100644 index 0000000..56b86b4 --- /dev/null +++ b/solutions/python3/bak/563.py.bak @@ -0,0 +1,22 @@ +# Definition for a binary tree node. +# class TreeNode: +# def __init__(self, x): +# self.val = x +# self.left = None +# self.right = None + +class Solution: + def findTilt(self, root): + """ + :type root: TreeNode + :rtype: int + """ + def traverse(node): + if not node: return 0 + left = traverse(node.left) + right = traverse(node.right) + res.append(abs(right -left)) + return node.val + left + right + res = [] + traverse(root) + return sum(res) \ No newline at end of file diff --git a/solutions/python3/bak/564.py.bak b/solutions/python3/bak/564.py.bak new file mode 100644 index 0000000..3436461 --- /dev/null +++ b/solutions/python3/bak/564.py.bak @@ -0,0 +1,19 @@ +class Solution: + def nearestPalindromic(self, S): + K = len(S) + candidates = [str(10**k + d) for k in (K-1, K) for d in (-1, 1)] + prefix = S[:(K+1)//2] + P = int(prefix) + for start in map(str, (P-1, P, P+1)): + candidates.append(start + (start[:-1] if K%2 else start)[::-1]) + + def delta(x): + return abs(int(S) - int(x)) + + ans = None + for cand in candidates: + if cand != S and not cand.startswith('00'): + if (ans is None or delta(cand) < delta(ans) or + delta(cand) == delta(ans) and int(cand) < int(ans)): + ans = cand + return ans \ No newline at end of file diff --git a/solutions/python3/bak/565.py.bak b/solutions/python3/bak/565.py.bak new file mode 100644 index 0000000..5dfccdf --- /dev/null +++ b/solutions/python3/bak/565.py.bak @@ -0,0 +1,17 @@ +class Solution: + def arrayNesting(self, nums): + """ + :type nums: List[int] + :rtype: int + """ + dic={} + for i in range(len(nums)): + if i in dic: + continue + j=i + dic[j]=1 + while nums[i]!=j: + dic[j]+=1 + i=nums[i] + dic[i]=1 + return max(dic.values()) \ No newline at end of file diff --git a/solutions/python3/bak/566.py.bak b/solutions/python3/bak/566.py.bak new file mode 100644 index 0000000..2760612 --- /dev/null +++ b/solutions/python3/bak/566.py.bak @@ -0,0 +1,13 @@ +class Solution: + def matrixReshape(self, nums, r, c): + """ + :type nums: List[List[int]] + :type r: int + :type c: int + :rtype: List[List[int]] + """ + nums_ordered=[x for y in nums for x in y] + if r*c==len(nums)*len(nums[0]): + return [nums_ordered[c*i:c*(i+1)] for i in range(r)] + else:return nums + \ No newline at end of file diff --git a/solutions/python3/bak/567.py.bak b/solutions/python3/bak/567.py.bak new file mode 100644 index 0000000..740a89c --- /dev/null +++ b/solutions/python3/bak/567.py.bak @@ -0,0 +1,18 @@ +class Solution: + def checkInclusion(self, s1, s2): + if len(s1) > len(s2): return False + dic = collections.defaultdict(int) + for i in range(len(s1)): + dic[s1[i]] += 1 + if dic[s1[i]] == 0: del dic[s1[i]] + dic[s2[i]] -= 1 + if dic[s2[i]] == 0: del dic[s2[i]] + i = 0 + for j in range(len(s1), len(s2)): + if not dic: return True + dic[s2[j]] -= 1 + if dic[s2[j]] == 0: del dic[s2[j]] + dic[s2[i]] += 1 + if dic[s2[i]] == 0: del dic[s2[i]] + i += 1 + return not dic \ No newline at end of file diff --git a/solutions/python3/bak/568.py.bak b/solutions/python3/bak/568.py.bak new file mode 100644 index 0000000..ba91f99 --- /dev/null +++ b/solutions/python3/bak/568.py.bak @@ -0,0 +1,11 @@ +class Solution: + def maxVacationDays(self, flights: List[List[int]], days: List[List[int]]) -> int: + if not flights or not days: + return 0 + n, k = len(flights), len(days[0]) + dp = [[-1] * (k + 1) for c in range(n)] + dp[0][0] = 0 + for w in range(1, k + 1): + for c in range(n): + dp[c][w] = max([dp[pre][w - 1] + days[c][w - 1] for pre in range(n) if (flights[pre][c] or pre == c) and dp[pre][w - 1] >= 0] or [-1]) + return max(dp[c][-1] for c in range(n)) \ No newline at end of file diff --git a/solutions/python3/bak/57.py.bak b/solutions/python3/bak/57.py.bak new file mode 100644 index 0000000..3a68d10 --- /dev/null +++ b/solutions/python3/bak/57.py.bak @@ -0,0 +1,13 @@ +class Solution: + def insert(self, intervals: List[List[int]], newInterval: List[int]) -> List[List[int]]: + new, i = [], 0 + for i, it in enumerate(intervals): + if newInterval[1] < it[0]: + i -= 1 + break + elif it[1] < newInterval[0]: + new += it, + else: + newInterval[0], newInterval[1] = min(it[0], newInterval[0]), max(it[1], newInterval[1]) + return new + [newInterval] + intervals[i + 1:] + \ No newline at end of file diff --git a/solutions/python3/bak/572.py.bak b/solutions/python3/bak/572.py.bak new file mode 100644 index 0000000..5a882ed --- /dev/null +++ b/solutions/python3/bak/572.py.bak @@ -0,0 +1,11 @@ +class Solution: + def isSubtree(self, s, t): + """ + :type s: TreeNode + :type t: TreeNode + :rtype: bool + """ + def traverse(node): + if not node: return "^" + return "$"+str(node.val)+"?"+traverse(node.left)+"@"+traverse(node.right) + return traverse(t) in traverse(s) \ No newline at end of file diff --git a/solutions/python3/bak/573.py.bak b/solutions/python3/bak/573.py.bak new file mode 100644 index 0000000..36a2716 --- /dev/null +++ b/solutions/python3/bak/573.py.bak @@ -0,0 +1,4 @@ +class Solution: + def minDistance(self, height, width, t, s, n): + sm = 2 * sum(abs(x - t[0]) + abs(y - t[1]) for x, y in n) + return min(sm - abs(x - t[0]) - abs(y - t[1]) + abs(x - s[0]) + abs(y - s[1]) for x, y in n) \ No newline at end of file diff --git a/solutions/python3/bak/575.py.bak b/solutions/python3/bak/575.py.bak new file mode 100644 index 0000000..fe82b50 --- /dev/null +++ b/solutions/python3/bak/575.py.bak @@ -0,0 +1,7 @@ +class Solution: + def distributeCandies(self, candies): + """ + :type candies: List[int] + :rtype: int + """ + return len(set(candies)) if len(set(candies))<=len(candies)//2 else len(candies)//2 \ No newline at end of file diff --git a/solutions/python3/bak/576.py.bak b/solutions/python3/bak/576.py.bak new file mode 100644 index 0000000..b66d805 --- /dev/null +++ b/solutions/python3/bak/576.py.bak @@ -0,0 +1,8 @@ +class Solution: + def __init__(self): self.dic = collections.defaultdict(int) + def findPaths(self, m, n, N, i, j): + if N >= 0 and (i < 0 or j < 0 or i >= m or j >= n): return 1 + elif N < 0: return 0 + elif (i, j, N) not in self.dic: + for p in ((1, 0), (-1, 0), (0, 1), (0, -1)): self.dic[(i, j, N)] += self.findPaths(m, n, N - 1, i + p[0], j + p[1]) + return self.dic[(i, j, N)] % (10 ** 9 + 7) \ No newline at end of file diff --git a/solutions/python3/bak/58.py.bak b/solutions/python3/bak/58.py.bak new file mode 100644 index 0000000..0cec937 --- /dev/null +++ b/solutions/python3/bak/58.py.bak @@ -0,0 +1,21 @@ +class Solution: + def lengthOfLastWord(self, s): + """ + :type s: str + :rtype: int + """ + if len(s)==0: + return 0 + count=0 + prev_count=0 + for letter in s: + if count>0: + prev_count=count + if letter==" ": + count=0 + continue + count+=1 + if count>0: + return count + else: + return prev_count \ No newline at end of file diff --git a/solutions/python3/bak/581.py.bak b/solutions/python3/bak/581.py.bak new file mode 100644 index 0000000..43b590b --- /dev/null +++ b/solutions/python3/bak/581.py.bak @@ -0,0 +1,10 @@ +class Solution: + def findUnsortedSubarray(self, nums: List[int]) -> int: + arr = sorted(nums) + i = 0 + for i in range(len(arr)): + if arr[i] != nums[i]: + for j in range(len(arr) - 1, -1, -1): + if arr[j] != nums[j]: + return j - i + 1 + return 0 \ No newline at end of file diff --git a/solutions/python3/bak/582.py.bak b/solutions/python3/bak/582.py.bak new file mode 100644 index 0000000..1386fbb --- /dev/null +++ b/solutions/python3/bak/582.py.bak @@ -0,0 +1,11 @@ +class Solution: + def killProcess(self, pid, ppid, kill): + indexes, res = collections.defaultdict(list), [kill] + for i, p in enumerate(ppid): + indexes[p].append(i) + stack = [kill] + while stack: + for i in indexes[stack.pop()]: + res.append(pid[i]) + stack.append(pid[i]) + return res \ No newline at end of file diff --git a/solutions/python3/bak/583.py.bak b/solutions/python3/bak/583.py.bak new file mode 100644 index 0000000..49b22e8 --- /dev/null +++ b/solutions/python3/bak/583.py.bak @@ -0,0 +1,13 @@ +class Solution: + def minDistance(self, w1, w2): + m, n = len(w1), len(w2) + dp = [[0] * (n + 1) for _ in range(m + 1)] + for i in range(m + 1): + for j in range(n + 1): + if i == 0 or j == 0: + dp[i][j] = i + j + elif w1[i - 1] == w2[j - 1]: + dp[i][j] = dp[i - 1][j - 1] + else: + dp[i][j] = min(dp[i][j - 1] + 1, dp[i - 1][j] + 1) + return dp[-1][-1] \ No newline at end of file diff --git a/solutions/python3/bak/587.py.bak b/solutions/python3/bak/587.py.bak new file mode 100644 index 0000000..3d5c95b --- /dev/null +++ b/solutions/python3/bak/587.py.bak @@ -0,0 +1,49 @@ +# http://www.algorithmist.com/index.php/Monotone_Chain_Convex_Hull.py + + +class Solution(object): + + def outerTrees(self, points): + """Computes the convex hull of a set of 2D points. + + Input: an iterable sequence of (x, y) pairs representing the points. + Output: a list of vertices of the convex hull in counter-clockwise order, + starting from the vertex with the lexicographically smallest coordinates. + Implements Andrew's monotone chain algorithm. O(n log n) complexity. + """ + + # Sort the points lexicographically (tuples are compared lexicographically). + # Remove duplicates to detect the case we have just one unique point. + # points = sorted(set(points)) + points = sorted(points, key=lambda p: (p.x, p.y)) + + # Boring case: no points or a single point, possibly repeated multiple times. + if len(points) <= 1: + return points + + # 2D cross product of OA and OB vectors, i.e. z-component of their 3D cross product. + # Returns a positive value, if OAB makes a counter-clockwise turn, + # negative for clockwise turn, and zero if the points are collinear. + def cross(o, a, b): + # return (a[0] - o[0]) * (b[1] - o[1]) - (a[1] - o[1]) * (b[0] - o[0]) + return (a.x - o.x) * (b.y - o.y) - (a.y - o.y) * (b.x - o.x) + + # Build lower hull + lower = [] + for p in points: + while len(lower) >= 2 and cross(lower[-2], lower[-1], p) < 0: + lower.pop() + lower.append(p) + + # Build upper hull + upper = [] + for p in reversed(points): + while len(upper) >= 2 and cross(upper[-2], upper[-1], p) < 0: + upper.pop() + upper.append(p) + + # Concatenation of the lower and upper hulls gives the convex hull. + # Last point of each list is omitted because it is repeated at the + # beginning of the other list. + # return lower[:-1] + upper[:-1] + return list(set(lower[:-1] + upper[:-1])) \ No newline at end of file diff --git a/solutions/python3/bak/588.py.bak b/solutions/python3/bak/588.py.bak new file mode 100644 index 0000000..b6ec4b4 --- /dev/null +++ b/solutions/python3/bak/588.py.bak @@ -0,0 +1,43 @@ +class File: + + def __init__(self, name): + self.name = name + self.files = {} + self.content = '' + +class FileSystem: + + def __init__(self): + self.root = File('/') + + def move(self, path): + cur = self.root + if path[1:]: + for dr in path[1:].split('/'): + if dr not in cur.files: + cur.files[dr] = File(dr) + cur = cur.files[dr] + return cur + + def ls(self, path: str) -> List[str]: + cur = self.move(path) + return [cur.name] if cur.content else sorted(cur.files.keys()) + + def mkdir(self, path: str) -> None: + self.move(path) + + def addContentToFile(self, filePath: str, content: str) -> None: + cur = self.move(filePath) + cur.content += content + + def readContentFromFile(self, filePath: str) -> str: + return self.move(filePath).content + + + +# Your FileSystem object will be instantiated and called as such: +# obj = FileSystem() +# param_1 = obj.ls(path) +# obj.mkdir(path) +# obj.addContentToFile(filePath,content) +# param_4 = obj.readContentFromFile(filePath) \ No newline at end of file diff --git a/solutions/python3/bak/59.py.bak b/solutions/python3/bak/59.py.bak new file mode 100644 index 0000000..15d6d53 --- /dev/null +++ b/solutions/python3/bak/59.py.bak @@ -0,0 +1,18 @@ +class Solution: + def generateMatrix(self, n): + """ + :type n: int + :rtype: List[List[int]] + """ + def dirToIndex(x, y, d): + if d == "r": return (x, y + 1, d) if y + 1 < n and matrix[x][y + 1] == 0 else (x + 1, y, "d") + elif d == "d": return (x + 1, y, d) if x + 1 < n and matrix[x + 1][y] == 0 else (x, y - 1, "l") + elif d == "l": return (x, y - 1, d) if y > 0 and matrix[x][y - 1] == 0 else (x - 1, y, "u") + else: return (x - 1, y, d) if x > 0 and matrix[x - 1][y] == 0 else (x, y +1, "r") + matrix = [[0 for i in range(1, n + 1)] for j in range(n)] + num, dir, i, j = 1, "r", 0, 0 + while 0 <= i < n and 0 <= j < n and matrix[i][j] == 0: + matrix[i][j] = num + num += 1 + i, j, dir = dirToIndex(i, j, dir) + return matrix \ No newline at end of file diff --git a/solutions/python3/bak/591.py.bak b/solutions/python3/bak/591.py.bak new file mode 100644 index 0000000..c4f2650 --- /dev/null +++ b/solutions/python3/bak/591.py.bak @@ -0,0 +1,47 @@ +class Solution: + def isValid(self, S): + CDATA_BEGIN = '![CDATA[' + CDATA_END = ']]>' + + def collect_tag(i): + for j in range(i, len(S)): + if S[j] == '>': break + else: + return None + return S[i+1:j] + + def valid_tag(tag): + return 1 <= len(tag) <= 9 and all('A' <= c <= 'Z' for c in tag) + + if not S or S[0] != '<': return False + tag = collect_tag(0) + if (tag is None or + not S.startswith('<{}>'.format(tag)) or + not S.endswith(''.format(tag)) or + not valid_tag(tag)): + return False + S = S[len(tag) + 2: -len(tag) - 3] + + i = 0 + stack = [] + while i < len(S): + if S[i] == '<': + tag = collect_tag(i) + if tag is None: return False + if tag.startswith(CDATA_BEGIN): + while i < len(S) and S[i:i+3] != CDATA_END: + i += 1 + if not S[i:i+3] == CDATA_END: + return False + i += 2 + elif tag.startswith('/'): + tag = tag[1:] + if not valid_tag(tag) or not stack or stack.pop() != tag: + return False + else: + if not valid_tag(tag): + return False + stack.append(tag) + i += 1 + + return not stack \ No newline at end of file diff --git a/solutions/python3/bak/592.py.bak b/solutions/python3/bak/592.py.bak new file mode 100644 index 0000000..6fab166 --- /dev/null +++ b/solutions/python3/bak/592.py.bak @@ -0,0 +1,40 @@ +class Solution: + def fractionAddition(self, e): + + def calc(i): + l, r = i - 1, i + 1 + while l > 0 and e[l - 1].isdigit(): + l -= 1 + while r < len(e) - 1 and e[r + 1].isdigit(): + r += 1 + l = -int(e[l:i]) if l > 0 and e[l - 1] == "-" else int(e[l:i]) + r = int(e[i + 1:r + 1]) + return l, r + + def lcm(x, y): + lcm = max(x, y) + while True: + if not lcm % x and not lcm % y: + return lcm + lcm += 1 + + def gcd(x, y): + for i in range(min(x, y), 0, -1): + if not x % i and not y % i: + return i + + n = d = None + for i in range(len(e)): + if e[i] == "/": + if n: + n2, d2 = calc(i) + newD = lcm(d, d2) + newN = n * (newD // d) + n2 * (newD // d2) + if newN: + r = gcd(abs(newD), abs(newN)) + n, d= newN // r, newD // r + else: + n, d = 0, 1 + else: + n, d = calc(i) + return str(n) + "/" + str(d) \ No newline at end of file diff --git a/solutions/python3/bak/593.py.bak b/solutions/python3/bak/593.py.bak new file mode 100644 index 0000000..db0b264 --- /dev/null +++ b/solutions/python3/bak/593.py.bak @@ -0,0 +1,14 @@ +class Solution: + def validSquare(self, p1, p2, p3, p4): + """ + :type p1: List[int] + :type p2: List[int] + :type p3: List[int] + :type p4: List[int] + :rtype: bool + """ + from itertools import combinations as cb + def D(C): + return (C[0][0] - C[1][0]) ** 2 + (C[0][1] - C[1][1]) ** 2 + S = set(map(D, cb((p1, p2, p3, p4), 2))) + return len(S) == 2 and 0 not in S \ No newline at end of file diff --git a/solutions/python3/bak/598.py.bak b/solutions/python3/bak/598.py.bak new file mode 100644 index 0000000..e1453ad --- /dev/null +++ b/solutions/python3/bak/598.py.bak @@ -0,0 +1,11 @@ +class Solution: + def maxCount(self, m, n, ops): + """ + :type m: int + :type n: int + :type ops: List[List[int]] + :rtype: int + """ + if ops==[]: + return m*n + return min(op[0] for op in ops)* min(op[1] for op in ops) \ No newline at end of file diff --git a/solutions/python3/bak/599.py.bak b/solutions/python3/bak/599.py.bak new file mode 100644 index 0000000..d0a3e97 --- /dev/null +++ b/solutions/python3/bak/599.py.bak @@ -0,0 +1,13 @@ +class Solution: + def findRestaurant(self, list1, list2): + """ + :type list1: List[str] + :type list2: List[str] + :rtype: List[str] + """ + dic={} + for item1 in list1: + for item2 in list2: + if item1==item2: + dic[item1]=list1.index(item1)+list2.index(item2) + return [k for k in dic if dic[k]==min(dic.values())] \ No newline at end of file diff --git a/solutions/python3/bak/6.py.bak b/solutions/python3/bak/6.py.bak new file mode 100644 index 0000000..01b5f64 --- /dev/null +++ b/solutions/python3/bak/6.py.bak @@ -0,0 +1,9 @@ +class Solution: + def convert(self, s, numRows): + if numRows == 1 or numRows >= len(s): return s + row, direction, res = 0, -1, [""] * numRows + for char in s: + res[row] += char + if row == 0 or row == numRows - 1: direction *= -1 + row += direction + return "".join(res) \ No newline at end of file diff --git a/solutions/python3/bak/60.py.bak b/solutions/python3/bak/60.py.bak new file mode 100644 index 0000000..10b3ab0 --- /dev/null +++ b/solutions/python3/bak/60.py.bak @@ -0,0 +1,6 @@ +class Solution: + def getPermutation(self, n, k): + p = itertools.permutations(range(1, n + 1)) + for i in range(k): + res = next(p) + return ''.join([str(i) for i in res]) \ No newline at end of file diff --git a/solutions/python3/bak/600.py.bak b/solutions/python3/bak/600.py.bak new file mode 100644 index 0000000..8ae4ee6 --- /dev/null +++ b/solutions/python3/bak/600.py.bak @@ -0,0 +1,10 @@ +class Solution: + def findIntegers(self, num): + num, sub = bin(num)[2:], 0 + zero, one = [1] * len(num), [1] * len(num) + for i in range(1, len(num)): + zero[i], one[i] = zero[i - 1] + one[i - 1], zero[i - 1] + for i in range(1, len(num)): + if num[i] == num[i - 1] == "1": break + if num[i] == num[i - 1] == "0": sub += one[-1 - i] + return zero[-1] + one[-1] - sub \ No newline at end of file diff --git a/solutions/python3/bak/604.py.bak b/solutions/python3/bak/604.py.bak new file mode 100644 index 0000000..fa365d1 --- /dev/null +++ b/solutions/python3/bak/604.py.bak @@ -0,0 +1,23 @@ +class StringIterator: + def findCount(self): + j = self.ind + 1 + while j < self.n and self.s[j].isnumeric(): j += 1 + self.count = int(self.s[self.ind + 1:j]) + self.new = j + + def __init__(self, compressedString): + self.s, self.n = compressedString, len(compressedString) + self.ind = self.count = self.new = 0 + self.findCount() + + def next(self): + if not self.count: + if self.new >= self.n: return " " + elif self.new < self.n: + self.ind = self.new + self.findCount() + self.count -= 1 + return self.s[self.ind] + + def hasNext(self): + return self.count > 0 or self.new < self.n - 1 \ No newline at end of file diff --git a/solutions/python3/bak/605.py.bak b/solutions/python3/bak/605.py.bak new file mode 100644 index 0000000..23cdd9e --- /dev/null +++ b/solutions/python3/bak/605.py.bak @@ -0,0 +1,27 @@ +class Solution: + def canPlaceFlowers(self, flowerbed, n): + """ + :type flowerbed: List[int] + :type n: int + :rtype: bool + """ + num=n + if len(flowerbed)<=1: + if (num==1 and flowerbed==[0]) or (num==0): + return True + else: + return False + if flowerbed[0]==0 and flowerbed[1]==0: + flowerbed[0]=1 + num-=1 + if flowerbed[-1]==0 and flowerbed[-2]==0: + flowerbed[-1]=1 + num-=1 + for i in range(1,len(flowerbed)-2): + if flowerbed[i]!=1 and flowerbed[i+1]!=1 and flowerbed[i-1]!=1: + flowerbed[i]=1 + num-=1 + if num<=0: + return True + return False + \ No newline at end of file diff --git a/solutions/python3/bak/606.py.bak b/solutions/python3/bak/606.py.bak new file mode 100644 index 0000000..7ec3320 --- /dev/null +++ b/solutions/python3/bak/606.py.bak @@ -0,0 +1,12 @@ +class Solution: + def tree2str(self, t): + """ + :type t: TreeNode + :rtype: str + """ + if not t: return "" + parent="%s" %t.val + left, right= "", "" + if t.left or t.right: left= "(%s)" % self.tree2str(t.left) + if t.right: right= "(%s)" % self.tree2str(t.right) + return parent+left+right \ No newline at end of file diff --git a/solutions/python3/bak/609.py.bak b/solutions/python3/bak/609.py.bak new file mode 100644 index 0000000..dd642b6 --- /dev/null +++ b/solutions/python3/bak/609.py.bak @@ -0,0 +1,9 @@ +class Solution: + def findDuplicate(self, paths): + dic = collections.defaultdict(list) + for path in paths: + root, *f = path.split(" ") + for file in f: + txt, content = file.split("(") + dic[content] += root + "/" + txt, + return [dic[key] for key in dic if len(dic[key]) > 1] \ No newline at end of file diff --git a/solutions/python3/bak/61.py.bak b/solutions/python3/bak/61.py.bak new file mode 100644 index 0000000..c16a944 --- /dev/null +++ b/solutions/python3/bak/61.py.bak @@ -0,0 +1,17 @@ +class Solution: + def rotateRight(self, head, k): + arr, count = [head], 0 + root = last = head + while last and last.next and count < k: + last, count = last.next, count+1 + arr.append(last) + if k != count: + k = k % (count+1) + last = arr[k] + if k == 0 or not last: + return head + curr = root + while last.next: + last, curr = last.next, curr.next + last.next, curr.next, start = root, None, curr.next + return start \ No newline at end of file diff --git a/solutions/python3/bak/611.py.bak b/solutions/python3/bak/611.py.bak new file mode 100644 index 0000000..ff35439 --- /dev/null +++ b/solutions/python3/bak/611.py.bak @@ -0,0 +1,9 @@ +class Solution: + def triangleNumber(self, nums): + res, n = 0, len(nums); nums.sort() + for i in range(n - 1, 1, -1): + j, k = i - 1, 0 + while k < j: + if nums[j] + nums[k] > nums[i]: res, j = res + j - k, j - 1 + else: k += 1 + return res \ No newline at end of file diff --git a/solutions/python3/bak/616.py.bak b/solutions/python3/bak/616.py.bak new file mode 100644 index 0000000..587c936 --- /dev/null +++ b/solutions/python3/bak/616.py.bak @@ -0,0 +1,24 @@ +class Solution: + def addBoldTag(self, S, words): + trie, n, mask, res = {}, len(S), set(), "" + for w in words: + cur = trie + for c in w: + if c not in cur: + cur[c] = {} + cur = cur[c] + cur["#"] = cur.get("#", set()) | {w} + for i in range(n): + cur, j = trie, i + while j < n and S[j] in cur: + cur = cur[S[j]] + if "#" in cur: + mask |= {ind for ind in range(i, j + 1)} + j += 1 + for i in range(n): + if i in mask and (not i or i - 1 not in mask): + res += "" + res += S[i] + if i in mask and (i == n - 1 or i + 1 not in mask): + res += "" + return res \ No newline at end of file diff --git a/solutions/python3/bak/617.py.bak b/solutions/python3/bak/617.py.bak new file mode 100644 index 0000000..280bd37 --- /dev/null +++ b/solutions/python3/bak/617.py.bak @@ -0,0 +1,11 @@ +class Solution: + def mergeTrees(self, t1, t2): + """ + :type t1: TreeNode + :type t2: TreeNode + :rtype: TreeNode + """ + if t1 and t2: + root, root.left, root.right = TreeNode(t1.val + t2.val), self.mergeTrees(t1.left, t2.left), self.mergeTrees(t1.right, t2.right) + return root + else: return t1 or t2 \ No newline at end of file diff --git a/solutions/python3/bak/62.py.bak b/solutions/python3/bak/62.py.bak new file mode 100644 index 0000000..af1a50d --- /dev/null +++ b/solutions/python3/bak/62.py.bak @@ -0,0 +1,11 @@ +class Solution: + def uniquePaths(self, m: int, n: int) -> int: + dp = [[0] * m for _ in range(n)] + dp[0][0] = 1 + for i in range(n): + for j in range(m): + if i - 1 >= 0: + dp[i][j] += dp[i - 1][j] + if j - 1 >= 0: + dp[i][j] += dp[i][j - 1] + return dp[-1][-1] \ No newline at end of file diff --git a/solutions/python3/bak/621.py.bak b/solutions/python3/bak/621.py.bak new file mode 100644 index 0000000..8029df8 --- /dev/null +++ b/solutions/python3/bak/621.py.bak @@ -0,0 +1,6 @@ +class Solution: + def leastInterval(self, tasks, n): + cnt = sorted(collections.Counter(tasks).values()) + idles = (cnt[-1] - 1) * n + for i in range(len(cnt) - 1): idles -= min(cnt[i], cnt[-1] - 1) + return idles > 0 and idles + len(tasks) or len(tasks) \ No newline at end of file diff --git a/solutions/python3/bak/622.py.bak b/solutions/python3/bak/622.py.bak new file mode 100644 index 0000000..c0c9164 --- /dev/null +++ b/solutions/python3/bak/622.py.bak @@ -0,0 +1,43 @@ +class Node: + def __init__(self, value): + self.val = value + self.next = self.pre = None +class MyCircularQueue: + + def __init__(self, k): + self.size = k + self.curSize = 0 + self.head = self.tail = Node(-1) + self.head.next = self.tail + self.tail.pre = self.head + + def enQueue(self, value): + if self.curSize < self.size: + node = Node(value) + node.pre = self.tail.pre + node.next = self.tail + node.pre.next = node.next.pre = node + self.curSize += 1 + return True + return False + + def deQueue(self): + if self.curSize > 0: + node = self.head.next + node.pre.next = node.next + node.next.pre = node.pre + self.curSize -= 1 + return True + return False + + def Front(self): + return self.head.next.val + + def Rear(self): + return self.tail.pre.val + + def isEmpty(self): + return self.curSize == 0 + + def isFull(self): + return self.curSize == self.size \ No newline at end of file diff --git a/solutions/python3/bak/623.py.bak b/solutions/python3/bak/623.py.bak new file mode 100644 index 0000000..8bbf5d5 --- /dev/null +++ b/solutions/python3/bak/623.py.bak @@ -0,0 +1,16 @@ +class Solution: + def addOneRow(self, root, v, d): + """ + :type root: TreeNode + :type v: int + :type d: int + :rtype: TreeNode + """ + q, depth = [root], 1 + while depth != d: parent, q, depth = q, [kid for node in q for kid in (node.left, node.right) if kid], depth+1 + if d != 1: + for node in parent: node.left, node.right, node.left.left, node.right.right = TreeNode(v), TreeNode(v), node.left, node.right + return root + else: + first, first.left = TreeNode(v), root + return first \ No newline at end of file diff --git a/solutions/python3/bak/624.py.bak b/solutions/python3/bak/624.py.bak new file mode 100644 index 0000000..f910bc7 --- /dev/null +++ b/solutions/python3/bak/624.py.bak @@ -0,0 +1,7 @@ +class Solution: + def maxDistance(self, arrays): + arrays.sort(key = lambda x: x[0]) + d1 = max(arr[-1] for arr in arrays[1:]) - arrays[0][0] + arrays.sort(key = lambda x: x[-1]) + d2 = arrays[-1][-1] - min(arr[0] for arr in arrays[:-1]) + return max(d1, d2) \ No newline at end of file diff --git a/solutions/python3/bak/625.py.bak b/solutions/python3/bak/625.py.bak new file mode 100644 index 0000000..7d0f1f1 --- /dev/null +++ b/solutions/python3/bak/625.py.bak @@ -0,0 +1,12 @@ +class Solution: + def smallestFactorization(self, a): + res = [] + def dfs(num): + if num == 1: return True + for n in range(9, 1, -1): + if not num % n: + res.append(str(n)) + return dfs(num // n) + return False + bol, num = dfs(a), int("".join(sorted(res))) if res else 1 + return num if bol and -(2 ** 31) <= num <= 2 ** 31 - 1 else 0 \ No newline at end of file diff --git a/solutions/python3/bak/628.py.bak b/solutions/python3/bak/628.py.bak new file mode 100644 index 0000000..74719e4 --- /dev/null +++ b/solutions/python3/bak/628.py.bak @@ -0,0 +1,8 @@ +class Solution: + def maximumProduct(self, nums): + """ + :type nums: List[int] + :rtype: int + """ + nums.sort() + return max(nums[-1]*nums[-2]*nums[-3], nums[-1]*nums[0]*nums[1]) \ No newline at end of file diff --git a/solutions/python3/bak/629.py.bak b/solutions/python3/bak/629.py.bak new file mode 100644 index 0000000..6792bfd --- /dev/null +++ b/solutions/python3/bak/629.py.bak @@ -0,0 +1,7 @@ +class Solution: + def kInversePairs(self, n, k): + dp = [1] + [0] * k + for i in range(2, n + 1): + for j in range(1, k + 1): dp[j] += dp[j - 1] + for j in range(k, 0, -1): dp[j] -= j - i >= 0 and dp[j - i] + return dp[-1] % (10 ** 9 + 7) \ No newline at end of file diff --git a/solutions/python3/bak/63.py.bak b/solutions/python3/bak/63.py.bak new file mode 100644 index 0000000..1b0a6af --- /dev/null +++ b/solutions/python3/bak/63.py.bak @@ -0,0 +1,12 @@ +class Solution: + def uniquePathsWithObstacles(self, obstacleGrid): + if obstacleGrid[0][0] == 1: return 0 + for i in range(len(obstacleGrid)): + for j in range(len(obstacleGrid[0])): + if obstacleGrid[i][j] == 1 or i == j == 0: + obstacleGrid[i][j] -= 1 + else: + add1 = obstacleGrid[i - 1][j] if i > 0 else 0 + add2 = obstacleGrid[i][j - 1] if j > 0 else 0 + obstacleGrid[i][j] += add1 + add2 + return abs(obstacleGrid[-1][-1]) \ No newline at end of file diff --git a/solutions/python3/bak/630.py.bak b/solutions/python3/bak/630.py.bak new file mode 100644 index 0000000..c0a2996 --- /dev/null +++ b/solutions/python3/bak/630.py.bak @@ -0,0 +1,10 @@ +class Solution: + def scheduleCourse(self, courses): + pq = [] + start = 0 + for t, end in sorted(courses, key = lambda x: x[1]): + start += t + heapq.heappush(pq, -t) + while start > end: + start += heapq.heappop(pq) + return len(pq) \ No newline at end of file diff --git a/solutions/python3/bak/631.py.bak b/solutions/python3/bak/631.py.bak new file mode 100644 index 0000000..a17426b --- /dev/null +++ b/solutions/python3/bak/631.py.bak @@ -0,0 +1,25 @@ +class Excel(object): + + def __init__(self, H, W): + self.M = [[{'v': 0, 'sum': None} for i in range(H)] for j in range(ord(W) - 64)] + + def set(self, r, c, v): + self.M[r - 1][ord(c) - 65] = {'v': v, 'sum': None} + + def get(self, r, c): + cell = self.M[r - 1][ord(c) - 65] + if not cell['sum']: return cell['v'] + return sum(self.get(*pos) * cell['sum'][pos] for pos in cell['sum']) + + def sum(self, r, c, strs): + self.M[r - 1][ord(c) - 65]['sum'] = self.parse(strs) + return self.get(r, c) + + def parse(self, strs): + c = collections.Counter() + for s in strs: + s, e = s.split(':')[0], s.split(':')[1] if ':' in s else s + for i in range(int(s[1:]), int(e[1:]) + 1): + for j in range(ord(s[0]) - 64, ord(e[0]) - 64 + 1): + c[(i, chr(j + 64))] += 1 + return c \ No newline at end of file diff --git a/solutions/python3/bak/632.py.bak b/solutions/python3/bak/632.py.bak new file mode 100644 index 0000000..d9627f2 --- /dev/null +++ b/solutions/python3/bak/632.py.bak @@ -0,0 +1,19 @@ +class Solution: + def smallestRange(self, nums): + L = R = None + while True: + mn = mx = nums[0][-1] + ind = [0] + for i, ls in enumerate(nums[1:]): + if ls[-1] > mx: + mx, ind = ls[-1], [i + 1] + elif ls[-1] == mx: + ind.append(i + 1) + elif ls[-1] < mn: + mn = ls[-1] + if L == None or mx - mn <= R - L: + L, R = mn, mx + for j in ind: + nums[j].pop() + if not nums[j]: + return [L, R] \ No newline at end of file diff --git a/solutions/python3/bak/633.py.bak b/solutions/python3/bak/633.py.bak new file mode 100644 index 0000000..ec73e8f --- /dev/null +++ b/solutions/python3/bak/633.py.bak @@ -0,0 +1,3 @@ +class Solution: + def judgeSquareSum(self, c: int) -> bool: + return not all(((c - i ** 2) ** 0.5) % 1 for i in range(int(c ** 0.5) + 1)) \ No newline at end of file diff --git a/solutions/python3/bak/635.py.bak b/solutions/python3/bak/635.py.bak new file mode 100644 index 0000000..0ae0819 --- /dev/null +++ b/solutions/python3/bak/635.py.bak @@ -0,0 +1,13 @@ +class LogSystem: + + def __init__(self): + self.times = [] + self.g = {"Year": 4, "Month": 7, "Day": 10, "Hour": 13, "Minute": 16, "Second": 19} + + def put(self, id, timestamp): + self.times.append([timestamp, id]) + + def retrieve(self, s, e, gra): + ind = self.g[gra] + s, e = s[:ind], e[:ind] + return [i for time, i in self.times if s <= time[:ind] <= e] \ No newline at end of file diff --git a/solutions/python3/bak/636.py.bak b/solutions/python3/bak/636.py.bak new file mode 100644 index 0000000..43073eb --- /dev/null +++ b/solutions/python3/bak/636.py.bak @@ -0,0 +1,14 @@ +class Solution: + def exclusiveTime(self, n, logs): + res, stack = [0] * n, [] + for log in logs: + log = log.split(":") + if log[1] == "start": + stack.append([int(log[2]), 0]) + else: + start = stack.pop() + time = int(log[2]) - start[0] + 1 + res[int(log[0])] += time - start[1] + if stack: + stack[-1][1] += time + return res \ No newline at end of file diff --git a/solutions/python3/bak/637.py.bak b/solutions/python3/bak/637.py.bak new file mode 100644 index 0000000..1b2848b --- /dev/null +++ b/solutions/python3/bak/637.py.bak @@ -0,0 +1,24 @@ +# Definition for a binary tree node. +# class TreeNode: +# def __init__(self, x): +# self.val = x +# self.left = None +# self.right = None + +class Solution: + def averageOfLevels(self, root): + """ + :type root: TreeNode + :rtype: List[float] + """ + from collections import deque + q, target, avg = deque([root]), root, [float(root.val)] + while q: + node=q.popleft() + if node.left: q.append(node.left) + if node.right: q.append(node.right) + if q and node==target: + target, sm = q[-1], 0 + for item in q: sm+=item.val + avg.append(sm/len(q)) + return avg \ No newline at end of file diff --git a/solutions/python3/bak/638.py.bak b/solutions/python3/bak/638.py.bak new file mode 100644 index 0000000..883144e --- /dev/null +++ b/solutions/python3/bak/638.py.bak @@ -0,0 +1,8 @@ +class Solution: + def shoppingOffers(self, price, special, needs): + def dfs(cur, needs): + val = cur + sum(p * needs[i] for i, p in enumerate(price)) + for s in special: + if all(n >= s[i] for i,n in enumerate(needs)): val = min(val, dfs(cur + s[-1], [n - s[i] for i,n in enumerate(needs)])) + return val + return dfs(0, needs) \ No newline at end of file diff --git a/solutions/python3/bak/639.py.bak b/solutions/python3/bak/639.py.bak new file mode 100644 index 0000000..4c318f8 --- /dev/null +++ b/solutions/python3/bak/639.py.bak @@ -0,0 +1,19 @@ +class Solution: + def numDecodings(self, s): + if s[0] == "0": return 0 + dp1 = dp2 = 1 + if s[0] == "*": dp2 = 9 + for i in range(1, len(s)): + couple, newDp1 = s[i -1: i + 1], dp2 + if s[i] == "0": + if s[i - 1] == "0" or s[i - 1] >= "3": return 0 + dp2 = 2 * dp1 if s[i - 1] == "*" else dp1 + elif s[i] == "*": + dp2 *= 9 + if s[i - 1] == "2": dp2 += 6 * dp1 + elif s[i - 1] == "1": dp2 += 9 * dp1 + elif s[i - 1] == "*": dp2 += 15 * dp1 + elif "10" <= couple <= "26": dp2 += dp1 + elif s[i - 1] == "*": dp2 += 2 * dp1 if s[i] <= "6" else dp1 + dp1 = newDp1 + return dp2 % (10 ** 9 + 7) \ No newline at end of file diff --git a/solutions/python3/bak/64.py.bak b/solutions/python3/bak/64.py.bak new file mode 100644 index 0000000..a1b33d2 --- /dev/null +++ b/solutions/python3/bak/64.py.bak @@ -0,0 +1,10 @@ +class Solution: + def minPathSum(self, grid): + """ + :type grid: List[List[int]] + :rtype: int + """ + for i in range(len(grid)): + for j in range(len(grid[0])): + grid[i][j] += min(grid[i][j - 1] if j > 0 else float("inf"), grid[i - 1][j] if i > 0 else float("inf")) if i!=0 or j != 0 else 0 + return grid[-1][-1] \ No newline at end of file diff --git a/solutions/python3/bak/640.py.bak b/solutions/python3/bak/640.py.bak new file mode 100644 index 0000000..cd69b13 --- /dev/null +++ b/solutions/python3/bak/640.py.bak @@ -0,0 +1,20 @@ +class Solution: + def solveEquation(self, equation): + def calc(eq): + smX = smNum = 0 + add, num = True, "" + for c in eq + "+": + if c.isdigit(): + num += c + elif c == "x": + smX += int(num) if add and num else -int(num) if num else 1 if add else -1 + num = "" + else: + smNum += int(num) if add and num else -int(num) if num else 0 + num, add = "", c == "+" + return smX, smNum + eq = equation.split("=") + lX, lNum, rX, rNum = calc(eq[0]) + calc(eq[1]) + if lX == rX: + return "No solution" if lNum != rNum else "Infinite solutions" + return "x=" + str((lNum - rNum) // (rX - lX)) \ No newline at end of file diff --git a/solutions/python3/bak/641.py.bak b/solutions/python3/bak/641.py.bak new file mode 100644 index 0000000..e20c2bc --- /dev/null +++ b/solutions/python3/bak/641.py.bak @@ -0,0 +1,66 @@ +class Node: + def __init__(self, value): + self.val = value + self.next = self.pre = None + +class MyCircularDeque: + + def __init__(self, k): + self.head = self.tail = Node(-1) + self.head.next = self.tail + self.tail.pre = self.head + self.size = k + self.curSize = 0 + + def add(self, value, preNode): + new = Node(value) + new.pre = preNode + new.next = preNode.next + new.pre.next = new.next.pre = new + self.curSize += 1 + + def remove(self, preNode): + node = preNode.next + node.pre.next = node.next + node.next.pre = node.pre + self.curSize -= 1 + + def insertFront(self, value): + if self.curSize < self.size: + self.add(value, self.head) + return True + return False + + def insertLast(self, value): + if self.curSize < self.size: + self.add(value, self.tail.pre) + return True + return False + + def deleteFront(self): + if self.curSize: + self.remove(self.head) + return True + return False + + def deleteLast(self): + if self.curSize: + self.remove(self.tail.pre.pre) + return True + return False + + def getFront(self): + if self.curSize: + return self.head.next.val + return -1 + + def getRear(self): + if self.curSize: + return self.tail.pre.val + return -1 + + def isEmpty(self): + return self.curSize == 0 + + def isFull(self): + return self.curSize == self.size \ No newline at end of file diff --git a/solutions/python3/bak/642.py.bak b/solutions/python3/bak/642.py.bak new file mode 100644 index 0000000..2e95bdb --- /dev/null +++ b/solutions/python3/bak/642.py.bak @@ -0,0 +1,53 @@ +class AutocompleteSystem: + + def __init__(self, sentences: List[str], times: List[int]): + self.cur = self.root = {} + self.rank = collections.defaultdict(int) + for i, s in enumerate(sentences): + self.s = s + self.rank[s] = times[i] - 1 + self.input('#') + + def move(self, c): + if c not in self.cur: + self.cur[c] = {} + self.cur = self.cur[c] + if 'sentences' not in self.cur: + self.cur['sentences'] = [] + + def addSentence(self): + self.cur = self.root + for c in self.s: + self.move(c) + self.search() + heapq.heappush(self.cur['sentences'], [-self.rank[self.s], self.s]) + + def search(self): + q, used, i = [], set(), 0 + while i < 3 and self.cur['sentences']: + r, s = heapq.heappop(self.cur['sentences']) + if s not in used: + used.add(s) + q.append([r, s]) + i += 1 + for r, s in q: + heapq.heappush(self.cur['sentences'], [r, s]) + return [s for r, s in q] + + def input(self, c: str) -> List[str]: + if c == '#': + self.rank[self.s] += 1 + self.addSentence() + self.s = '' + self.cur = self.root + return [] + else: + self.s += c + self.move(c) + return self.search() + + + +# Your AutocompleteSystem object will be instantiated and called as such: +# obj = AutocompleteSystem(sentences, times) +# param_1 = obj.input(c) \ No newline at end of file diff --git a/solutions/python3/bak/643.py.bak b/solutions/python3/bak/643.py.bak new file mode 100644 index 0000000..e81d713 --- /dev/null +++ b/solutions/python3/bak/643.py.bak @@ -0,0 +1,11 @@ +class Solution: + def findMaxAverage(self, nums, k): + """ + :type nums: List[int] + :type k: int + :rtype: float + """ + sm=sum(nums[:k]) + mx,j=sm/k, 0 + for i in range(k,len(nums)): sm+=nums[i]; sm-=nums[j]; curr=sm/k; mx=max(curr,mx); j+=1 + return mx \ No newline at end of file diff --git a/solutions/python3/bak/644.py.bak b/solutions/python3/bak/644.py.bak new file mode 100644 index 0000000..bd0062c --- /dev/null +++ b/solutions/python3/bak/644.py.bak @@ -0,0 +1,23 @@ +class Solution: + def findMaxAverage(self, nums: List[int], k: int) -> float: + def sub(mid): + sm = pre = mn = 0 + for i in range(k): + sm += nums[i] - mid + if sm >= 0: + return True + for i in range(k, len(nums)): + sm += nums[i] - mid + pre += nums[i - k] - mid + mn = min(mn, pre) + if sm >= mn: + return True + return False + l, r = min(nums), max(nums) + while l + 1E-6 < r: + mid = (l + r) / 2 + if sub(mid): + l = mid + else: + r = mid + return l \ No newline at end of file diff --git a/solutions/python3/bak/645.py.bak b/solutions/python3/bak/645.py.bak new file mode 100644 index 0000000..bcbccc6 --- /dev/null +++ b/solutions/python3/bak/645.py.bak @@ -0,0 +1,4 @@ +class Solution: + def findErrorNums(self, nums: List[int]) -> List[int]: + cnt = collections.Counter(nums) + return [k for k in cnt if cnt[k] == 2] + [i for i in range(1, len(nums) + 1) if i not in cnt] \ No newline at end of file diff --git a/solutions/python3/bak/646.py.bak b/solutions/python3/bak/646.py.bak new file mode 100644 index 0000000..a5ee1f5 --- /dev/null +++ b/solutions/python3/bak/646.py.bak @@ -0,0 +1,9 @@ +class Solution: + def findLongestChain(self, pairs): + pairs.sort(key = lambda x: x[1]) + res, pre = 1, pairs[0][1] + for c, d in pairs[1:]: + if pre < c: + pre = d + res += 1 + return res \ No newline at end of file diff --git a/solutions/python3/bak/647.py.bak b/solutions/python3/bak/647.py.bak new file mode 100644 index 0000000..33ebb22 --- /dev/null +++ b/solutions/python3/bak/647.py.bak @@ -0,0 +1,15 @@ +class Solution: + def countSubstrings(self, s): + res = 0 + for k in range(len(s)): + i = j = k + while 0 <= i and j < len(s): + if s[i] == s[j]: res += 1 + else: break + i , j = i - 1, j + 1 + i , j =k , k + 1 + while 0 <= i and j < len(s): + if s[i] == s[j]: res += 1 + else: break + i , j = i - 1, j + 1 + return res \ No newline at end of file diff --git a/solutions/python3/bak/648.py.bak b/solutions/python3/bak/648.py.bak new file mode 100644 index 0000000..92a12ce --- /dev/null +++ b/solutions/python3/bak/648.py.bak @@ -0,0 +1,15 @@ +class Solution: + def replaceWords(self, dict, sentence): + """ + :type dict: List[str] + :type sentence: str + :rtype: str + """ + s = set(dict) + sentence = sentence.split() + for j, w in enumerate(sentence): + for i in range(1, len(w)): + if w[:i] in s: + sentence[j] = w[:i] + break + return " ".join(sentence) \ No newline at end of file diff --git a/solutions/python3/bak/649.py.bak b/solutions/python3/bak/649.py.bak new file mode 100644 index 0000000..ef59418 --- /dev/null +++ b/solutions/python3/bak/649.py.bak @@ -0,0 +1,28 @@ +class Solution: + def predictPartyVictory(self, senate): + ban_r = ban_d = 0 + while True: + new = [] + r_cnt = d_cnt = 0 + for s in senate: + if s == 'R': + r_cnt += 1 + if ban_r > 0: + ban_r -= 1 + else: + ban_d += 1 + d_cnt -= 1 + new.append(s) + elif s == 'D': + d_cnt += 1 + if ban_d > 0: + ban_d -= 1 + else: + ban_r += 1 + r_cnt -= 1 + new.append(s) + if d_cnt < 0 < r_cnt: + return "Radiant" + elif r_cnt < 0 < d_cnt: + return "Dire" + senate = new \ No newline at end of file diff --git a/solutions/python3/bak/65.py.bak b/solutions/python3/bak/65.py.bak new file mode 100644 index 0000000..e2ed303 --- /dev/null +++ b/solutions/python3/bak/65.py.bak @@ -0,0 +1,23 @@ +class Solution: + def isNumber(self, s): + s = s.strip() + pointSeen = eSeen = numberSeen = False + numberAfterE = True + for i, c in enumerate(s): + if "0" <= c <= "9": + numberSeen = numberAfterE = True + elif c == ".": + if eSeen or pointSeen: + return False + pointSeen = True + elif c == "e": + if eSeen or not numberSeen: + return False + numberAfterE = False + eSeen = True + elif c in "-+": + if i and s[i - 1] != "e": + return False + else: + return False + return numberSeen and numberAfterE \ No newline at end of file diff --git a/solutions/python3/bak/650.py.bak b/solutions/python3/bak/650.py.bak new file mode 100644 index 0000000..88b1a9d --- /dev/null +++ b/solutions/python3/bak/650.py.bak @@ -0,0 +1,10 @@ +class Solution: + def minSteps(self, n): + cur, copy, steps = 1, 0, 0 + while cur != n: + if copy < cur and not (n - cur) % cur: + copy = cur + else: + cur += copy + steps += 1 + return steps \ No newline at end of file diff --git a/solutions/python3/bak/651.py.bak b/solutions/python3/bak/651.py.bak new file mode 100644 index 0000000..13c0c70 --- /dev/null +++ b/solutions/python3/bak/651.py.bak @@ -0,0 +1,8 @@ +class Solution: + def maxA(self, N): + dp = [0] * (N + 1) + for i in range(N + 1): + dp[i] = i + for j in range(1, i - 2): + dp[i] = max(dp[i], dp[j] * (i - j - 1)) + return dp[N] \ No newline at end of file diff --git a/solutions/python3/bak/652.py.bak b/solutions/python3/bak/652.py.bak new file mode 100644 index 0000000..28e6598 --- /dev/null +++ b/solutions/python3/bak/652.py.bak @@ -0,0 +1,11 @@ +class Solution: + def findDuplicateSubtrees(self, root): + def dfs(root): + if not root: return "null" + struct = "%s,%s,%s" % (str(root.val), dfs(root.left), dfs(root.right)) + nodes[struct].append(root) + return struct + + nodes = collections.defaultdict(list) + dfs(root) + return [nodes[struct][0] for struct in nodes if len(nodes[struct]) > 1] \ No newline at end of file diff --git a/solutions/python3/bak/653.py.bak b/solutions/python3/bak/653.py.bak new file mode 100644 index 0000000..05453e4 --- /dev/null +++ b/solutions/python3/bak/653.py.bak @@ -0,0 +1,14 @@ +class Solution: + def findTarget(self, root, k): + """ + :type root: TreeNode + :type k: int + :rtype: bool + """ + def traverse(node): + if not node: return False + if not node.val in dic: dic[k-node.val]=1 + else: return True + return traverse(node.left) or traverse(node.right) + dic={} + return traverse(root) \ No newline at end of file diff --git a/solutions/python3/bak/654.py.bak b/solutions/python3/bak/654.py.bak new file mode 100644 index 0000000..9544c35 --- /dev/null +++ b/solutions/python3/bak/654.py.bak @@ -0,0 +1,12 @@ +class Solution: + def constructMaximumBinaryTree(self, nums): + """ + :type nums: List[int] + :rtype: TreeNode + """ + if nums: + pos = nums.index(max(nums)) + root = TreeNode(nums[pos]) + root.left = self.constructMaximumBinaryTree(nums[:pos]) + root.right = self.constructMaximumBinaryTree(nums[pos+1:]) + return root \ No newline at end of file diff --git a/solutions/python3/bak/655.py.bak b/solutions/python3/bak/655.py.bak new file mode 100644 index 0000000..3e52196 --- /dev/null +++ b/solutions/python3/bak/655.py.bak @@ -0,0 +1,24 @@ +class Solution: + def printTree(self, root): + """ + :type root: TreeNode + :rtype: List[List[str]] + """ + def traverse(node): + if not node: return 0 + return max(traverse(node.left), traverse(node.right)) * 2 + 1 + length = traverse(root) + stack, dic, res, padding = [root], {root : length // 2}, [], length // 2 + while any(stack): + out, tmp, padding = [""] * length, [], padding // 2 + for i, node in enumerate(stack): + out[dic[node]] = str(node.val) + if node.left: + dic[node.left] = dic[node] - padding - 1 + tmp.append(node.left) + if node.right: + dic[node.right] = dic[node] + padding + 1 + tmp.append(node.right) + res.append(out) + stack = tmp + return res \ No newline at end of file diff --git a/solutions/python3/bak/656.py.bak b/solutions/python3/bak/656.py.bak new file mode 100644 index 0000000..bdb557d --- /dev/null +++ b/solutions/python3/bak/656.py.bak @@ -0,0 +1,17 @@ +class Solution: + def cheapestJump(self, A, B): + n = len(A) + preMin = {n - 1:[n]} + for i in range(n - 2, -1, -1): + if A[i] == -1: + continue + mn, preIndex = float("inf"), None + for ind in range(i + 1, i + B + 1 <= n and i + B + 1 or n): + if -1 < A[ind] < mn: + mn, preIndex = A[ind], ind + if preIndex: + A[i] += A[preIndex] + preMin[i] = preMin[preIndex] + [i + 1] + else: + A[i] = -1 + return 0 in preMin and preMin[0][::-1] or [] \ No newline at end of file diff --git a/solutions/python3/bak/657.py.bak b/solutions/python3/bak/657.py.bak new file mode 100644 index 0000000..3d08980 --- /dev/null +++ b/solutions/python3/bak/657.py.bak @@ -0,0 +1,14 @@ +class Solution: + def judgeCircle(self, moves): + """ + :type moves: str + :rtype: bool + """ + x,y = 0, 0 + for char in moves: + if char=="R": x+=1 + if char=="L": x-=1 + if char=="U": y+=1 + if char=="D": y-=1 + return True if x==0 and y==0 else False + \ No newline at end of file diff --git a/solutions/python3/bak/658.py.bak b/solutions/python3/bak/658.py.bak new file mode 100644 index 0000000..f55ef58 --- /dev/null +++ b/solutions/python3/bak/658.py.bak @@ -0,0 +1,9 @@ +class Solution: + def findClosestElements(self, arr, k, x): + ind, n = bisect.bisect_left(arr, x), len(arr) + if ind > 0 and x - arr[ind - 1] < arr[ind] - x: ind -= 1 + l, r = ind, ind + 1 + for _ in range(k - 1): + if r >= n or (l > 0 and x - arr[l - 1] <= arr[r] - x): l -= 1 + else: r += 1 + return arr[l:r] \ No newline at end of file diff --git a/solutions/python3/bak/659.py.bak b/solutions/python3/bak/659.py.bak new file mode 100644 index 0000000..355977c --- /dev/null +++ b/solutions/python3/bak/659.py.bak @@ -0,0 +1,18 @@ +class Solution: + def isPossible(self, nums): + heap, last = [], collections.defaultdict(int) + for num in nums: + last[num] += 1 + if heap and heap[0][0] <= num - 1: + if heap[0][0] < num - 1: + return False + else: + last[num - 1] -= 1 + n, l = heapq.heappop(heap) + if l == -1: + heapq.heappush(heap, (num, -2)) + elif num - 1 not in last or not last[num - 1]: + heapq.heappush(heap, (num, -1)) + else: + last[num - 1] -= 1 + return not heap \ No newline at end of file diff --git a/solutions/python3/bak/66.py.bak b/solutions/python3/bak/66.py.bak new file mode 100644 index 0000000..22f4af5 --- /dev/null +++ b/solutions/python3/bak/66.py.bak @@ -0,0 +1,3 @@ +class Solution: + def plusOne(self, digits, add = 1): + return add and [1] or [] if not digits else self.plusOne(digits[:-1], +(digits[-1] + add > 9)) + [(digits[-1] + add) % 10] \ No newline at end of file diff --git a/solutions/python3/bak/660.py.bak b/solutions/python3/bak/660.py.bak new file mode 100644 index 0000000..50b703f --- /dev/null +++ b/solutions/python3/bak/660.py.bak @@ -0,0 +1,7 @@ +class Solution: + def newInteger(self, n): + base9 = "" + while n: + base9 += str(n % 9) + n //= 9 + return int(base9[::-1]) \ No newline at end of file diff --git a/solutions/python3/bak/661.py.bak b/solutions/python3/bak/661.py.bak new file mode 100644 index 0000000..f2c8232 --- /dev/null +++ b/solutions/python3/bak/661.py.bak @@ -0,0 +1,11 @@ +class Solution: + def imageSmoother(self, M: List[List[int]]) -> List[List[int]]: + m, n = len(M), len(M[0]) + grid = [[0] * n for _ in range(m)] + for i in range(m): + for j in range(n): + adj = [M[i + x][j + y] for x, y in ((0, 0), (-1, 0), (1, 0), (0, -1), (0, 1), (-1, -1), (-1, 1), (1, 1), (1, -1)) if 0 <= i + x < m and 0 <= j + y < n] + grid[i][j] = sum(adj) // len(adj) + return grid + + \ No newline at end of file diff --git a/solutions/python3/bak/662.py.bak b/solutions/python3/bak/662.py.bak new file mode 100644 index 0000000..99954c7 --- /dev/null +++ b/solutions/python3/bak/662.py.bak @@ -0,0 +1,15 @@ +class Solution: + def widthOfBinaryTree(self, root): + """ + :type root: TreeNode + :rtype: int + """ + dic, stack, res = {root: 1}, [root], 0 + while any(stack): + tmp, mn ,mx = [], float("inf"), - float("inf") + for node in stack: + res = max(res, dic[stack[-1]] - dic[stack[0]] + 1) + if node.left: tmp, dic[node.left] = tmp + [node.left], dic[node] * 2 - 1 + if node.right: tmp, dic[node.right] = tmp + [node.right], dic[node] * 2 + stack = tmp + return res \ No newline at end of file diff --git a/solutions/python3/bak/663.py.bak b/solutions/python3/bak/663.py.bak new file mode 100644 index 0000000..72bc855 --- /dev/null +++ b/solutions/python3/bak/663.py.bak @@ -0,0 +1,20 @@ +# Definition for a binary tree node. +# class TreeNode: +# def __init__(self, x): +# self.val = x +# self.left = None +# self.right = None + +class Solution: + def checkEqualTree(self, root): + nodeSum = collections.defaultdict(int) + def dfs(node): + if not node: + return 0 + sm = node.val + dfs(node.left) + dfs(node.right) + nodeSum[sm] += 1 + return sm + totalSum = dfs(root) + if not totalSum: + return nodeSum[0] > 1 + return totalSum % 2 == 0 and totalSum // 2 in nodeSum \ No newline at end of file diff --git a/solutions/python3/bak/664.py.bak b/solutions/python3/bak/664.py.bak new file mode 100644 index 0000000..bcbf4ef --- /dev/null +++ b/solutions/python3/bak/664.py.bak @@ -0,0 +1,13 @@ +class Solution: + def strangePrinter(self, s): + memo = {} + def dp(i, j): + if i > j: return 0 + if (i, j) not in memo: + ans = dp(i+1, j) + 1 + for k in range(i+1, j+1): + if s[k] == s[i]: + ans = min(ans, dp(i, k-1) + dp(k+1, j)) + memo[i, j] = ans + return memo[i, j] + return dp(0, len(s) - 1) \ No newline at end of file diff --git a/solutions/python3/bak/665.py.bak b/solutions/python3/bak/665.py.bak new file mode 100644 index 0000000..0889b48 --- /dev/null +++ b/solutions/python3/bak/665.py.bak @@ -0,0 +1,12 @@ +class Solution: + def checkPossibility(self, nums): + """ + :type nums: List[int] + :rtype: bool + """ + for i in range(len(nums)-1): + if nums[i]>nums[i+1]: + mod1, mod2=list(nums), list(nums) + mod1[i], mod2[i+1]=mod1[i+1], mod2[i] + if mod1!=sorted(mod1) and mod2!=sorted(mod2): return False + return True \ No newline at end of file diff --git a/solutions/python3/bak/666.py.bak b/solutions/python3/bak/666.py.bak new file mode 100644 index 0000000..6dad0df --- /dev/null +++ b/solutions/python3/bak/666.py.bak @@ -0,0 +1,7 @@ +class Solution: + def pathSum(self, nums): + dp = {(0, 1) : 0} + for num in nums: + d, p, v = map(int, str(num)) + dp[(d, p)] = v + dp[(d - 1, (p + 1) // 2)] + return sum(dp[k] for k in dp if (k[0] + 1, k[1] * 2) not in dp and (k[0] + 1, k[1] * 2 - 1) not in dp) \ No newline at end of file diff --git a/solutions/python3/bak/667.py.bak b/solutions/python3/bak/667.py.bak new file mode 100644 index 0000000..d0337d9 --- /dev/null +++ b/solutions/python3/bak/667.py.bak @@ -0,0 +1,19 @@ +class Solution: + def constructArray(self, n, k): + """ + :type n: int + :type k: int + :rtype: List[int] + """ + left, right, res = 0, n+1, [None]*n + for i in range(n): + if k == 1: + if i%2 == 0: + while iR or root.val str: + return bin(int(a, 2) + int(b, 2))[2:] \ No newline at end of file diff --git a/solutions/python3/bak/670.py.bak b/solutions/python3/bak/670.py.bak new file mode 100644 index 0000000..3a7af00 --- /dev/null +++ b/solutions/python3/bak/670.py.bak @@ -0,0 +1,9 @@ +class Solution: + def maximumSwap(self, num): + res, num = num, list(str(num)) + for i in range(len(num) - 1): + for j in range(i + 1, len(num)): + if int(num[j]) > int(num[i]): + tmp = int("".join(num[:i] + [num[j]] + num[i + 1:j] + [num[i]] + num[j + 1:])) + if tmp > res: res = tmp + return res \ No newline at end of file diff --git a/solutions/python3/bak/671.py.bak b/solutions/python3/bak/671.py.bak new file mode 100644 index 0000000..248695f --- /dev/null +++ b/solutions/python3/bak/671.py.bak @@ -0,0 +1,18 @@ +# Definition for a binary tree node. +# class TreeNode: +# def __init__(self, x): +# self.val = x +# self.left = None +# self.right = None + +class Solution: + def findSecondMinimumValue(self, root: TreeNode) -> int: + self.sec = float('inf') + def dfs(node): + if not node: return + dfs(node.left) + dfs(node.right) + if root.val < node.val < self.sec: + self.sec = node.val + dfs(root) + return self.sec if self.sec < float('inf') else -1 \ No newline at end of file diff --git a/solutions/python3/bak/672.py.bak b/solutions/python3/bak/672.py.bak new file mode 100644 index 0000000..3b1d177 --- /dev/null +++ b/solutions/python3/bak/672.py.bak @@ -0,0 +1,4 @@ +class Solution: + def flipLights(self, n, m): + n = min(n, 3) + return min(1 << n, 1 + m * n) \ No newline at end of file diff --git a/solutions/python3/bak/673.py.bak b/solutions/python3/bak/673.py.bak new file mode 100644 index 0000000..880494b --- /dev/null +++ b/solutions/python3/bak/673.py.bak @@ -0,0 +1,10 @@ +class Solution: + def findNumberOfLIS(self, nums): + dp = [[1, 1] for _ in range(len(nums))] + for i in range(len(nums) - 1): + for j in range(i + 1, len(nums)): + if nums[j] > nums[i]: + if dp[i][0] >= dp[j][0]: dp[j] = [dp[i][0] + 1, dp[i][1]] + elif dp[i][0] == dp[j][0] - 1: dp[j][1] += dp[i][1] + dp.sort() + return dp and sum(d[1] for d in dp if d[0] == dp[-1][0]) or 0 \ No newline at end of file diff --git a/solutions/python3/bak/674.py.bak b/solutions/python3/bak/674.py.bak new file mode 100644 index 0000000..d7e64b4 --- /dev/null +++ b/solutions/python3/bak/674.py.bak @@ -0,0 +1,12 @@ +class Solution: + def findLengthOfLCIS(self, nums): + """ + :type nums: List[int] + :rtype: int + """ + if nums==[]: return 0 + curr, mx=1, 1 + for i in range(len(nums)-1): + if nums[i+1]>nums[i]: curr+=1; mx=max(mx,curr) + else: curr=1 + return mx \ No newline at end of file diff --git a/solutions/python3/bak/675.py.bak b/solutions/python3/bak/675.py.bak new file mode 100644 index 0000000..72588ed --- /dev/null +++ b/solutions/python3/bak/675.py.bak @@ -0,0 +1,29 @@ +class Solution: + def cutOffTree(self, forest): + def hadlocks(forest, sr, sc, tr, tc): + R, C = len(forest), len(forest[0]) + processed = set() + deque = collections.deque([(0, sr, sc)]) + while deque: + detours, r, c = deque.popleft() + if (r, c) not in processed: + processed.add((r, c)) + if r == tr and c == tc: + return abs(sr-tr) + abs(sc-tc) + 2*detours + for nr, nc, closer in ((r-1, c, r > tr), (r+1, c, r < tr), + (r, c-1, c > tc), (r, c+1, c < tc)): + if 0 <= nr < R and 0 <= nc < C and forest[nr][nc]: + if closer: + deque.appendleft((detours, nr, nc)) + else: + deque.append((detours+1, nr, nc)) + return -1 + trees = sorted((v, r, c) for r, row in enumerate(forest) + for c, v in enumerate(row) if v > 1) + sr = sc = ans = 0 + for _, tr, tc in trees: + d = hadlocks(forest, sr, sc, tr, tc) + if d < 0: return -1 + ans += d + sr, sc = tr, tc + return ans \ No newline at end of file diff --git a/solutions/python3/bak/676.py.bak b/solutions/python3/bak/676.py.bak new file mode 100644 index 0000000..2a218d2 --- /dev/null +++ b/solutions/python3/bak/676.py.bak @@ -0,0 +1,33 @@ +class MagicDictionary: + + def __init__(self): + """ + Initialize your data structure here. + """ + from collections import defaultdict + self.var = defaultdict(set) + + def buildDict(self, dict): + """ + Build a dictionary through a list of words + :type dict: List[str] + :rtype: void + """ + for w in dict: + for i in range(len(w)): self.var[(i, w[:i] + w[i + 1:])].add(w[i]) + + def search(self, word): + """ + Returns if there is any word in the trie that equals to the given word after modifying exactly one character + :type word: str + :rtype: bool + """ + for i in range(len(word)): + if self.var[(i, word[:i] + word[i + 1:])] - {word[i]}: return True + return False + + +# Your MagicDictionary object will be instantiated and called as such: +# obj = MagicDictionary() +# obj.buildDict(dict) +# param_2 = obj.search(word) \ No newline at end of file diff --git a/solutions/python3/bak/677.py.bak b/solutions/python3/bak/677.py.bak new file mode 100644 index 0000000..aef8b25 --- /dev/null +++ b/solutions/python3/bak/677.py.bak @@ -0,0 +1,32 @@ +class MapSum: + + def __init__(self): + """ + Initialize your data structure here. + """ + from collections import defaultdict + self.dic = defaultdict(int) + + def insert(self, key, val): + """ + :type key: str + :type val: int + :rtype: void + """ + self.dic[key] = val + + def sum(self, prefix): + """ + :type prefix: str + :rtype: int + """ + sm = 0 + for k in self.dic: + if k[:len(prefix)] == prefix: sm += self.dic[k] + return sm + + +# Your MapSum object will be instantiated and called as such: +# obj = MapSum() +# obj.insert(key,val) +# param_2 = obj.sum(prefix) \ No newline at end of file diff --git a/solutions/python3/bak/678.py.bak b/solutions/python3/bak/678.py.bak new file mode 100644 index 0000000..6712929 --- /dev/null +++ b/solutions/python3/bak/678.py.bak @@ -0,0 +1,15 @@ +class Solution: + def checkValidString(self, s): + """ + :type s: str + :rtype: bool + """ + left, left_star = [], [] + for i in range(len(s)): + if s[i] == "(": left.append([s[i], i]) + elif s[i] == "*": left_star.append([s[i], i]) + elif left and left[-1][0] == "(": left.pop() + elif left_star: left_star.pop() + else: return False + while left and left_star and left[-1][1]< left_star[-1][1]: left.pop(); left_star.pop() + return not left \ No newline at end of file diff --git a/solutions/python3/bak/679.py.bak b/solutions/python3/bak/679.py.bak new file mode 100644 index 0000000..6d931e5 --- /dev/null +++ b/solutions/python3/bak/679.py.bak @@ -0,0 +1,24 @@ +class Solution: + def judgePoint24(self, nums): + q = [[None, nums[i]] + nums[:i] + nums[i + 1:] for i in range(len(nums))] + while q: + new = [] + for group1, group2, *rest in q: + if not rest and group1: + for res in (group1 + group2, group1 - group2, group1 * group2, group2 and group1 / group2): + if 23.999 <= res <= 24.0001: return True + if not rest and not group1 and 23.999 <= group2 <= 24.0001: return True + for i in range(len(rest)): + for newGroup2 in (group2 + rest[i], group2 - rest[i], rest[i] - group2, group2 * rest[i], group2 / rest[i]): + new.append([group1, newGroup2] + rest[:i] + rest[i + 1:]) + if group2: + new.append([group1, rest[i] / group2] + rest[:i] + rest[i + 1:]) + if group1 != None: + for newGroup1 in (group1 + group2, group1 - group2, group1 * group2): + new.append([newGroup1, rest[i]] + rest[:i] + rest[i + 1:]) + if group2: + new.append([group1 / group2, rest[i]] + rest[:i] + rest[i + 1:]) + else: + new.append([group2, rest[i]] + rest[:i] + rest[i + 1:]) + q = new + return False \ No newline at end of file diff --git a/solutions/python3/bak/68.py.bak b/solutions/python3/bak/68.py.bak new file mode 100644 index 0000000..6172532 --- /dev/null +++ b/solutions/python3/bak/68.py.bak @@ -0,0 +1,15 @@ +class Solution: + def fullJustify(self, words: List[str], maxWidth: int) -> List[str]: + res, used, s = [], 0, [] + for i, w in enumerate(words): + if not s or len(w) + used + len(s) <= maxWidth: + used += len(w) + s += [w] + else: + if len(s) == 1: + res.append(s[0] + (maxWidth - used) * ' ') + else: + br = (maxWidth - used) // (len(s) - 1) + res.append(''.join((br + (i <= (maxWidth - used) % (len(s) - 1))) * ' ' + c for i, c in enumerate(s)).lstrip()) + used, s = len(w), [w] + return res + [' '.join(c for c in s) + (maxWidth - used - len(s) + 1) * ' '] \ No newline at end of file diff --git a/solutions/python3/bak/680.py.bak b/solutions/python3/bak/680.py.bak new file mode 100644 index 0000000..d39516c --- /dev/null +++ b/solutions/python3/bak/680.py.bak @@ -0,0 +1,27 @@ +class Solution: + def validPalindrome(self, s): + """ + :type s: str + :rtype: bool + """ + memo = {} + def dfs(l, r, cnt): + if (l, r, cnt) in memo: + return memo[(l, r, cnt)] + if l >= r: + return True + elif s[l] != s[r]: + cnt += 1 + if cnt > 1: + memo[(l, r, cnt)] = False + return False + elif (s[l + 1] == s[r] and dfs(l + 1, r, cnt + 1)) or (s[l] == s[r - 1] and dfs(l, r - 1, cnt + 1)): + memo[(l, r, cnt)] = True + return True + else: + memo[(l, r, cnt)] = False + return False + else: + memo[(l, r, cnt)] = dfs(l + 1, r - 1, cnt) + return memo[(l, r, cnt)] + return dfs(0, len(s) - 1, 0) \ No newline at end of file diff --git a/solutions/python3/bak/681.py.bak b/solutions/python3/bak/681.py.bak new file mode 100644 index 0000000..a2f00ff --- /dev/null +++ b/solutions/python3/bak/681.py.bak @@ -0,0 +1,13 @@ +class Solution: + def nextClosestTime(self, time): + t = sorted(set(time))[:-1] + nex = {a: b for a, b in zip(t, t[1:])} + for i, d in enumerate(time[::-1]): + if d in nex: + if i == 0: + return time[:4] + nex[d] + elif i == 1 and nex[d] < '6': + return time[:3] + nex[d] + t[0] + elif i == 3 and int(time[0] + nex[d]) < 24: + return time[0] + nex[d] + ':' + t[0] * 2 + return t[0] * 2 + ':' + t[0] * 2 \ No newline at end of file diff --git a/solutions/python3/bak/682.py.bak b/solutions/python3/bak/682.py.bak new file mode 100644 index 0000000..70e0401 --- /dev/null +++ b/solutions/python3/bak/682.py.bak @@ -0,0 +1,15 @@ +class Solution: + def calPoints(self, ops: List[str]) -> int: + arr = [] + for op in ops: + #print(arr) + if op.isdigit() or op[0] == '-': + arr.append(int(op)) + elif op == 'C' and arr: + arr.pop() + elif op == 'D' and arr: + arr.append(arr[-1] * 2) + elif len(arr) >= 2: + arr.append(arr[-1] + arr[-2]) + #print(arr) + return sum(arr) \ No newline at end of file diff --git a/solutions/python3/bak/684.py.bak b/solutions/python3/bak/684.py.bak new file mode 100644 index 0000000..8f9c905 --- /dev/null +++ b/solutions/python3/bak/684.py.bak @@ -0,0 +1,23 @@ +class Solution: + def findRedundantConnection(self, edges: List[List[int]]) -> List[int]: + parent = [0] * len(edges) + + def find(x): + if parent[x] == 0: + return x + parent[x] = find(parent[x]) + return parent[x] + + def union(x, y): + rootX = find(x) + rootY = find(y) + if rootX == rootY: + return False + parent[rootX] = rootY + return True + + res = [0, 0] + for x, y in edges: + if not union(x - 1, y - 1): + res = [x, y] + return res \ No newline at end of file diff --git a/solutions/python3/bak/685.py.bak b/solutions/python3/bak/685.py.bak new file mode 100644 index 0000000..a1f167b --- /dev/null +++ b/solutions/python3/bak/685.py.bak @@ -0,0 +1,19 @@ +class Solution: + def findRedundantDirectedConnection(self, edges): + def root(i): + return parent[i] == i and i or root(parent[i]) + + parent, a, b, c = [0] * (len(edges) + 1), None, None, None + for i, edge in enumerate(edges): + if parent[edge[1]]: + a, b, c, edges[i][0]= parent[edge[1]], edge[0], edge[1], 0 + else: + parent[edge[1]] = edge[0] + + parent = [i for i in range(len(edges) + 1)] + for u, v in edges: + if u: + if root(u) == v: + return a and [a, c] or [u, v] + parent[v] = u + return [b, c] \ No newline at end of file diff --git a/solutions/python3/bak/686.py.bak b/solutions/python3/bak/686.py.bak new file mode 100644 index 0000000..24eae26 --- /dev/null +++ b/solutions/python3/bak/686.py.bak @@ -0,0 +1,5 @@ +class Solution: + def repeatedStringMatch(self, A: str, B: str) -> int: + for i in range(1,2+len(B)//len(A)+1): + if B in A*i: return i + return -1 \ No newline at end of file diff --git a/solutions/python3/bak/688.py.bak b/solutions/python3/bak/688.py.bak new file mode 100644 index 0000000..33446b1 --- /dev/null +++ b/solutions/python3/bak/688.py.bak @@ -0,0 +1,14 @@ +class Solution: + def knightProbability(self, N, K, r, c): + memo = {} + def dfs(i, j, p, k): + if 0 <= i < N and 0 <= j < N and k < K: + sm = 0 + for x, y in ((-1, -2), (-2, -1), (-2, 1), (-1, 2), (1, 2), (2, 1), (2, -1), (1, -2)): + if (i + x, j + y, k) not in memo: + memo[(i + x, j + y, k)] = dfs(i + x, j + y, p / 8, k + 1) + sm += memo[(i + x, j + y, k)] + return sm + else: + return 0 <= i < N and 0 <= j < N and p or 0 + return dfs(r, c, 1, 0) \ No newline at end of file diff --git a/solutions/python3/bak/689.py.bak b/solutions/python3/bak/689.py.bak new file mode 100644 index 0000000..563529c --- /dev/null +++ b/solutions/python3/bak/689.py.bak @@ -0,0 +1,19 @@ +class Solution: + def maxSumOfThreeSubarrays(self, nums, k): + single, double, sm, n, cur = {}, {}, 0, len(nums), sum(nums[:k - 1]) + for i in range(k - 1, n): + cur += nums[i] + single[i - k + 1] = cur + cur -= nums[i - k + 1] + cur = n - k, single[n - k] + for i in range(n - k, k * 2 - 1, -1): + if single[i] >= cur[1]: + cur = i, single[i] + double[i - k] = cur[1] + single[i - k], i - k, cur[0] + cur = double[n - 2 * k] + for i in range(n - 2 * k, k - 1, -1): + if double[i][0] >= cur[0]: + cur = double[i] + if single[i - k] + cur[0] >= sm: + sm, res = single[i - k] + cur[0], [i - k, cur[1], cur[2]] + return res \ No newline at end of file diff --git a/solutions/python3/bak/69.py.bak b/solutions/python3/bak/69.py.bak new file mode 100644 index 0000000..b95eed9 --- /dev/null +++ b/solutions/python3/bak/69.py.bak @@ -0,0 +1,10 @@ +class Solution: + def mySqrt(self, x: int) -> int: + l, r = 0, x + while l <= r: + mid = (l + r) // 2 + if mid * mid <= x: + l = mid + 1 + else: + r = mid - 1 + return l - 1 \ No newline at end of file diff --git a/solutions/python3/bak/690.py.bak b/solutions/python3/bak/690.py.bak new file mode 100644 index 0000000..b301ba1 --- /dev/null +++ b/solutions/python3/bak/690.py.bak @@ -0,0 +1,29 @@ +""" +# Employee info +class Employee: + def __init__(self, id, importance, subordinates): + # It's the unique id of each node. + # unique id of this employee + self.id = id + # the importance value of this employee + self.importance = importance + # the id of direct subordinates + self.subordinates = subordinates +""" +class Solution: + def getImportance(self, employees, id): + """ + :type employees: Employee + :type id: int + :rtype: int + """ + def dfs(id): + self.val += dic[id].importance + for sub in dic[id].subordinates: + dfs(sub) + dic = {} + for emp in employees: + dic[emp.id] = emp + self.val = 0 + dfs(id) + return self.val \ No newline at end of file diff --git a/solutions/python3/bak/691.py.bak b/solutions/python3/bak/691.py.bak new file mode 100644 index 0000000..ff4efb8 --- /dev/null +++ b/solutions/python3/bak/691.py.bak @@ -0,0 +1,18 @@ +class Solution: + def minStickers(self, stickers, target): + cnt, res, n = collections.Counter(target), [float("inf")], len(target) + def dfs(dic, used, i): + if i == n: + res[0] = min(res[0], used) + elif dic[target[i]] >= cnt[target[i]]: + dfs(dic, used, i + 1) + elif used < res[0] - 1: + for sticker in stickers: + if target[i] in sticker: + for s in sticker: + dic[s] += 1 + dfs(dic, used + 1, i + 1) + for s in sticker: + dic[s] -= 1 + dfs(collections.defaultdict(int), 0, 0) + return res[0] < float("inf") and res[0] or -1 \ No newline at end of file diff --git a/solutions/python3/bak/692.py.bak b/solutions/python3/bak/692.py.bak new file mode 100644 index 0000000..1312f5d --- /dev/null +++ b/solutions/python3/bak/692.py.bak @@ -0,0 +1,3 @@ +class Solution: + def topKFrequent(self, words, k): + return [w for w, v in sorted(collections.Counter(words).items(), key = lambda x: (-x[1], x[0])) [:k]] \ No newline at end of file diff --git a/solutions/python3/bak/693.py.bak b/solutions/python3/bak/693.py.bak new file mode 100644 index 0000000..a22868e --- /dev/null +++ b/solutions/python3/bak/693.py.bak @@ -0,0 +1,4 @@ +class Solution: + def hasAlternatingBits(self, n: int) -> bool: + return all(a != b for a, b in zip(bin(n)[2:], bin(n)[3:])) + \ No newline at end of file diff --git a/solutions/python3/bak/694.py.bak b/solutions/python3/bak/694.py.bak new file mode 100644 index 0000000..6041f21 --- /dev/null +++ b/solutions/python3/bak/694.py.bak @@ -0,0 +1,15 @@ +class Solution: + def numDistinctIslands(self, grid): + visited, pattern, m, n = set(), collections.defaultdict(str), len(grid), len(grid[0]) + def dfs(ri, rj, i, j, pi, pj): + visited.add((i, j)) + pattern[(ri, rj)] += str(pi) + str(pj) + for x, y in ((-1, 0), (1, 0), (0, -1), (0, 1)): + if 0 <= i + x < m and 0 <= j + y < n and grid[i + x][j + y] and (i + x, j + y) not in visited: + dfs(ri, rj, i + x, j + y, pi + x, pj + y) + + for i in range(m): + for j in range(n): + if grid[i][j] and (i, j) not in visited: + dfs(i, j, i, j, 0, 0) + return len(set(pattern.values())) \ No newline at end of file diff --git a/solutions/python3/bak/695.py.bak b/solutions/python3/bak/695.py.bak new file mode 100644 index 0000000..6464622 --- /dev/null +++ b/solutions/python3/bak/695.py.bak @@ -0,0 +1,7 @@ +class Solution: + def maxAreaOfIsland(self, grid): + m, n = len(grid), len(grid and grid[0]) + def explore(i, j): + grid[i][j] = 0 + return 1 + sum(explore(x,y) for x,y in ((i-1,j),(i+1,j),(i,j-1),(i,j+1)) if 0<=x List[int]: + height = [0] + pos = [0] + res = [] + max_h = 0 + for left, side in positions: + i = bisect.bisect_right(pos, left) + j = bisect.bisect_left(pos, left + side) + high = max(height[i - 1:j] or [0]) + side + pos[i:j] = [left, left + side] + height[i:j] = [high, height[j - 1]] + max_h = max(max_h, high) + res.append(max_h) + return res \ No newline at end of file diff --git a/solutions/python3/bak/7.py.bak b/solutions/python3/bak/7.py.bak new file mode 100644 index 0000000..1efd77b --- /dev/null +++ b/solutions/python3/bak/7.py.bak @@ -0,0 +1,3 @@ +class Solution: + def reverse(self, x): + x = int(str(x)[::-1]) if x >= 0 else int("-" + str(x)[::-1][:-1]); return -2 ** 31 <= x <= 2 ** 31 - 1 and x or 0 \ No newline at end of file diff --git a/solutions/python3/bak/70.py.bak b/solutions/python3/bak/70.py.bak new file mode 100644 index 0000000..aec35bd --- /dev/null +++ b/solutions/python3/bak/70.py.bak @@ -0,0 +1,9 @@ +class Solution: + def climbStairs(self, n: int) -> int: + memo = {} + def dfs(i): + if i >= n: return 1 if i == n else 0 + if i not in memo: + memo[i] = dfs(i + 1) + dfs(i + 2) + return memo[i] + return dfs(0) \ No newline at end of file diff --git a/solutions/python3/bak/700.py.bak b/solutions/python3/bak/700.py.bak new file mode 100644 index 0000000..e91c193 --- /dev/null +++ b/solutions/python3/bak/700.py.bak @@ -0,0 +1,5 @@ +class Solution: + def searchBST(self, root, val): + if root and val < root.val: return self.searchBST(root.left, val) + elif root and val > root.val: return self.searchBST(root.right, val) + return root \ No newline at end of file diff --git a/solutions/python3/bak/701.py.bak b/solutions/python3/bak/701.py.bak new file mode 100644 index 0000000..a6024c1 --- /dev/null +++ b/solutions/python3/bak/701.py.bak @@ -0,0 +1,5 @@ +class Solution: + def insertIntoBST(self, root, val): + if root and root.val > val and not self.insertIntoBST(root.left, val): root.left = TreeNode(val) + elif root and root.val < val and not self.insertIntoBST(root.right, val): root.right = TreeNode(val) + return root \ No newline at end of file diff --git a/solutions/python3/bak/702.py.bak b/solutions/python3/bak/702.py.bak new file mode 100644 index 0000000..7109c07 --- /dev/null +++ b/solutions/python3/bak/702.py.bak @@ -0,0 +1,13 @@ +class Solution(object): + def search(self, reader, target): + l, r = 0, 20000 + while l <= r: + index = (l + r) // 2 + response = reader.get(index) + if response > target: + r = index - 1 + elif response < target: + l = index + 1 + else: + return index + return -1 \ No newline at end of file diff --git a/solutions/python3/bak/703.py.bak b/solutions/python3/bak/703.py.bak new file mode 100644 index 0000000..fb5d724 --- /dev/null +++ b/solutions/python3/bak/703.py.bak @@ -0,0 +1,16 @@ +class KthLargest(object): + + def __init__(self, k, nums): + self.pool = nums + self.k = k + heapq.heapify(self.pool) + while len(self.pool) > k: + heapq.heappop(self.pool) + + + def add(self, val): + if len(self.pool) < self.k: + heapq.heappush(self.pool, val) + elif val > self.pool[0]: + heapq.heapreplace(self.pool, val) + return self.pool[0] \ No newline at end of file diff --git a/solutions/python3/bak/704.py.bak b/solutions/python3/bak/704.py.bak new file mode 100644 index 0000000..0ed0cb5 --- /dev/null +++ b/solutions/python3/bak/704.py.bak @@ -0,0 +1,3 @@ +class Solution: + def search(self, nums: List[int], target: int) -> int: + return bisect.bisect_left(nums, target) if target in nums else -1 \ No newline at end of file diff --git a/solutions/python3/bak/705.py.bak b/solutions/python3/bak/705.py.bak new file mode 100644 index 0000000..5dfe6ca --- /dev/null +++ b/solutions/python3/bak/705.py.bak @@ -0,0 +1,107 @@ + + + + + + + +leetcode.com | 502: Bad gateway + + + + + + + + + + + + + +
Retry for a live version

This page (https://leetcode.com/submissions/detail/163424957/) is currently offline. However, because the site uses Cloudflare's Always Online™ technology you can continue to surf a snapshot of the site. We will keep checking in the background and, as soon as the site comes back, you will automatically be served the live version. Always Online™ is powered by Cloudflare | Hide this Alert

+
+ + + +
+
+

+ + Error + 502 + Ray ID: 52beb9bebad1d8bd • 2019-10-26 19:09:36 UTC +

+

Bad gateway

+
+ +
+
+
+ +
+
+ + +
+ You +

Browser

+ Working +
+ +
+
+ + +
+ Amsterdam +

Cloudflare

+ Working +
+ +
+
+ + +
+ leetcode.com +

Host

+ Error +
+ +
+ +
+
+ +
+
+
+

What happened?

+

The web server reported a bad gateway error.

+
+ +
+

What can I do?

+

Please try again in a few minutes.

+
+
+ +
+ + + + +
+
+ + int: + if not grid or not grid[0]: return 0 + m,n=len(grid),len(grid[0]) + + # augment matrix to void length check + grid.append([0]*n) + for row in grid: row.append(0) + + self.pool=set() + self.res=0 + + def bfs(i0,j0): + grid[i0][j0]=-1 + q=[(i0,j0)] + for i,j in q: + for I,J in (i-1,j),(i+1,j),(i,j-1),(i,j+1): + if grid[I][J]==1: + grid[I][J]=-1 + q.append([I,J]) + self.addisland(q) + + for i in range(m): + for j in range(n): + if grid[i][j]==1: bfs(i,j) + + return self.res + + def addisland(self,q): + Imin=min(x for x,y in q) + Jmin=min(y for x,y in q) + island1=tuple(sorted((x-Imin,y-Jmin) for x,y in q)) # original island + + if island1 in self.pool: return None + self.res+=1 + + Imax=max(x for x,y in island1) + Jmax=max(y for x,y in island1) + + island2=tuple(sorted((-x+Imax,y) for x,y in island1)) # x axis mirror + island3=tuple(sorted((x,-y+Jmax) for x,y in island1)) # y axis mirror + island4=tuple(sorted((-x+Imax,-y+Jmax) for x,y in island1)) # origin mirror + + island5=tuple(sorted((y,x) for x,y in island1)) # diagonal mirror + island6=tuple(sorted((-x+Jmax,y) for x,y in island5)) + island7=tuple(sorted((x,-y+Imax) for x,y in island5)) + island8=tuple(sorted((-x+Jmax,-y+Imax) for x,y in island5)) + + self.pool |= set([island1,island2,island3,island4,island5,island6,island7,island8]) \ No newline at end of file diff --git a/solutions/python3/bak/712.py.bak b/solutions/python3/bak/712.py.bak new file mode 100644 index 0000000..0a2609f --- /dev/null +++ b/solutions/python3/bak/712.py.bak @@ -0,0 +1,14 @@ +class Solution: + def minimumDeleteSum(self, s1, s2): + l1, l2 = len(s1) + 1, len(s2) + 1 + d = [[0] * l2 for i in range(l1)] + for i in range(l1): + for j in range(l2): + c1, c2 = ord(s1[i - 1]), ord(s2[j - 1]) + if not i * j: + d[i][j] = d[i - 1][j] + c1 if i else d[i][j - 1] + c2 if j else 0 + elif s1[i - 1] == s2[j - 1]: + d[i][j] = d[i - 1][j - 1] + else: + d[i][j] = min(d[i - 1][j] + c1, d[i][j - 1] + c2, d[i - 1][j - 1] + c1 + c2) + return d[-1][-1] \ No newline at end of file diff --git a/solutions/python3/bak/713.py.bak b/solutions/python3/bak/713.py.bak new file mode 100644 index 0000000..b3ae431 --- /dev/null +++ b/solutions/python3/bak/713.py.bak @@ -0,0 +1,8 @@ +class Solution: + def numSubarrayProductLessThanK(self, nums, k): + l, res, cur = 0, 0, 1 + for i in range(len(nums)): + cur *= nums[i] + while cur >= k and l < i: l, cur = l + 1, cur // nums[l] + if cur < k: res += i - l + 1 + return res \ No newline at end of file diff --git a/solutions/python3/bak/714.py.bak b/solutions/python3/bak/714.py.bak new file mode 100644 index 0000000..7b823e7 --- /dev/null +++ b/solutions/python3/bak/714.py.bak @@ -0,0 +1,8 @@ +class Solution: + def maxProfit(self, prices, fee): + pre = [0, -float("inf")] + for p in prices: + p0, p1 = pre[1] + p - fee, pre[0] - p + if p0 > pre[0]: pre[0] = p0 + if p1 > pre[1]: pre[1] = p1 + return pre[0] \ No newline at end of file diff --git a/solutions/python3/bak/715.py.bak b/solutions/python3/bak/715.py.bak new file mode 100644 index 0000000..fafdbdb --- /dev/null +++ b/solutions/python3/bak/715.py.bak @@ -0,0 +1,18 @@ +from bisect import bisect_left as bl, bisect_right as br + +class RangeModule: + + def __init__(self): + self._X = [] + + def addRange(self, left, right): + i, j = bl(self._X, left), br(self._X, right) + self._X[i:j] = [left]*(i%2 == 0) + [right]*(j%2 == 0) + + def queryRange(self, left, right): + i, j = br(self._X, left), bl(self._X, right) + return i == j and i%2 == 1 + + def removeRange(self, left, right): + i, j = bl(self._X, left), br(self._X, right) + self._X[i:j] = [left]*(i%2 == 1) + [right]*(j%2 == 1) \ No newline at end of file diff --git a/solutions/python3/bak/716.py.bak b/solutions/python3/bak/716.py.bak new file mode 100644 index 0000000..e308696 --- /dev/null +++ b/solutions/python3/bak/716.py.bak @@ -0,0 +1,75 @@ +class Node: + def __init__(self, value, index): + self.val = value + self.i = index + self.pre = self.next = None +class MaxStack: + + def __init__(self): + """ + initialize your data structure here. + """ + self.heap = [] + self.Nodes = {} + self.head = self.tail = Node(0, -1) + self.head.next = self.tail + self.tail.pre = self.head + + + def push(self, x): + """ + :type x: int + :rtype: void + """ + newNode = Node(x, self.tail.pre.i + 1) + newNode.pre = self.tail.pre + newNode.next = self.tail + self.tail.pre.next = self.tail.pre = newNode + self.Nodes[newNode.i] = newNode + heapq.heappush(self.heap, (-x, -newNode.i)) + + def pop(self): + """ + :rtype: int + """ + node = self.tail.pre + node.pre.next = self.tail + self.tail.pre = node.pre + self.Nodes.pop(node.i) + if node.i == -self.heap[0][1]: + heapq.heappop(self.heap) + return node.val + + def top(self): + """ + :rtype: int + """ + return self.tail.pre.val + + def peekMax(self): + """ + :rtype: int + """ + while -self.heap[0][1] not in self.Nodes or self.Nodes[-self.heap[0][1]].val != -self.heap[0][0]: + heapq.heappop(self.heap) + return -self.heap[0][0] + + def popMax(self): + """ + :rtype: int + """ + while -self.heap[0][1] not in self.Nodes or self.Nodes[-self.heap[0][1]].val != -self.heap[0][0]: + heapq.heappop(self.heap) + node = self.Nodes.pop(-self.heap[0][1]) + node.pre.next = node.next + node.next.pre = node.pre + return -heapq.heappop(self.heap)[0] + + +# Your MaxStack object will be instantiated and called as such: +# obj = MaxStack() +# obj.push(x) +# param_2 = obj.pop() +# param_3 = obj.top() +# param_4 = obj.peekMax() +# param_5 = obj.popMax() \ No newline at end of file diff --git a/solutions/python3/bak/717.py.bak b/solutions/python3/bak/717.py.bak new file mode 100644 index 0000000..5ba7942 --- /dev/null +++ b/solutions/python3/bak/717.py.bak @@ -0,0 +1,10 @@ +class Solution: + def isOneBitCharacter(self, bits): + """ + :type bits: List[int] + :rtype: bool + """ + while bits: + last=bits.pop(0) + if last==1:bits.pop(0) + return True if last==0 else False \ No newline at end of file diff --git a/solutions/python3/bak/718.py.bak b/solutions/python3/bak/718.py.bak new file mode 100644 index 0000000..35b7bc5 --- /dev/null +++ b/solutions/python3/bak/718.py.bak @@ -0,0 +1,8 @@ +class Solution: + def findLength(self, A, B): + A, res, sub = "X%sX" % "X".join(map(str, A)), 0, "X" + for num in B: + sub += str(num) + "X" + if sub in A: res += 1 + else: sub = sub[sub[1:].index("X") + 1:] + return res \ No newline at end of file diff --git a/solutions/python3/bak/719.py.bak b/solutions/python3/bak/719.py.bak new file mode 100644 index 0000000..c1e922f --- /dev/null +++ b/solutions/python3/bak/719.py.bak @@ -0,0 +1,14 @@ +class Solution(object): + def countPairsLTE(self, array, value): + return sum(bisect.bisect_right(array, array[i] + value, lo = i) - i - 1 for i in range(len(array))) + + def smallestDistancePair(self, nums, k): + nums.sort() + low, high = min([nums[i + 1] - nums[i] for i in range(len(nums) - 1)]), nums[-1] - nums[0] + while low < high: + mid = (low + high) // 2 + if self.countPairsLTE(nums, mid) < k: + low = mid + 1 + else: + high = mid + return low \ No newline at end of file diff --git a/solutions/python3/bak/72.py.bak b/solutions/python3/bak/72.py.bak new file mode 100644 index 0000000..30a4a90 --- /dev/null +++ b/solutions/python3/bak/72.py.bak @@ -0,0 +1,12 @@ +class Solution: + def minDistance(self, w1: str, w2: str) -> int: + dp = [[0] * (len(w2) + 1) for i in range(len(w1) + 1)] + for i in range(len(w1) + 1): + for j in range(len(w2) + 1): + if not (i and j): + dp[i][j] = i or j + elif w1[i - 1] == w2[j - 1]: + dp[i][j] += dp[i - 1][j - 1] + else: + dp[i][j] += min(dp[i - 1][j], dp[i][j - 1], dp[i - 1][j - 1]) + 1 + return dp[-1][-1] \ No newline at end of file diff --git a/solutions/python3/bak/720.py.bak b/solutions/python3/bak/720.py.bak new file mode 100644 index 0000000..697d27d --- /dev/null +++ b/solutions/python3/bak/720.py.bak @@ -0,0 +1,9 @@ +class Solution: + def longestWord(self, words): + """ + :type words: List[str] + :rtype: str + """ + for w in sorted(words, key = lambda x: (-len(x), x)): + if all([True if w[:i] in set(words) - {w} else False for i in range(1, len(w))]): return w + return "" \ No newline at end of file diff --git a/solutions/python3/bak/721.py.bak b/solutions/python3/bak/721.py.bak new file mode 100644 index 0000000..899ea68 --- /dev/null +++ b/solutions/python3/bak/721.py.bak @@ -0,0 +1,18 @@ +class Solution: + def accountsMerge(self, accounts): + def explore(mail, q): + q += mail, + visited.add(mail) + for v in edges[mail]: + if v not in visited: explore(v, q) + return q + edges, owner, visited, res = collections.defaultdict(list), {}, set(), [] + for acc in accounts: + owner[acc[1]] = acc[0] + for i in range(1, len(acc) - 1): + if acc[i] != acc[i + 1]: + edges[acc[i]] += acc[i + 1], + edges[acc[i + 1]] += acc[i], + for acc in accounts: + if acc[1] not in visited: res += [acc[0]] + sorted(explore(acc[1], [])), + return res \ No newline at end of file diff --git a/solutions/python3/bak/722.py.bak b/solutions/python3/bak/722.py.bak new file mode 100644 index 0000000..27daf0e --- /dev/null +++ b/solutions/python3/bak/722.py.bak @@ -0,0 +1,17 @@ +class Solution: + def removeComments(self, source): + res, block, cont, blockStart = [], False, False, -1 + for line in source: + if not cont: cache = "" + for i, c in enumerate(line): + if not block: cache += c + if cache[-2:] == "//": + cache = cache[:-2] + break + elif cache[-2:] == "/*": blockStart, cache, block = i, cache[:-2], True + elif line[i - 1:i + 1] == "*/" and blockStart < i - 1: block = False + if not block: + if cache: res += cache, + cont = False + else: cont, blockStart = True, -1 + return res \ No newline at end of file diff --git a/solutions/python3/bak/723.py.bak b/solutions/python3/bak/723.py.bak new file mode 100644 index 0000000..025f5d7 --- /dev/null +++ b/solutions/python3/bak/723.py.bak @@ -0,0 +1,23 @@ +class Solution: + def candyCrush(self, board): + m, n = len(board), len(board[0]) + def gravity(): + for j in range(n): + stack = [board[i][j] for i in range(m - 1, -1, -1) if board[i][j] > 0] + stack += [0] * (m - len(stack)) + for i in range(m): board[i][j] = stack.pop() + def crush(): + crush = False + for i in range(m): + for j in range(n): + if j > 1 and board[i][j] > 0 and board[i][j] == abs(board[i][j - 1]) == abs(board[i][j - 2]): + board[i][j - 2:j + 1] = [-abs(board[i][j]) for _ in range(3)] + crush = True + if i > 1 and board[i][j] != 0 and abs(board[i][j]) == abs(board[i - 1][j]) == abs(board[i - 2][j]): + if board[i][j] > 0: board[i][j] *= -1 + if board[i - 1][j] > 0: board[i - 1][j] *= -1 + if board[i - 2][j] > 0: board[i - 2][j] *= -1 + crush = True + return crush + while crush(): gravity() + return board \ No newline at end of file diff --git a/solutions/python3/bak/724.py.bak b/solutions/python3/bak/724.py.bak new file mode 100644 index 0000000..189e21b --- /dev/null +++ b/solutions/python3/bak/724.py.bak @@ -0,0 +1,9 @@ +class Solution: + def pivotIndex(self, nums: List[int]) -> int: + sm = sum(nums) + cur = 0 + for i in range(len(nums)): + if cur == sm - cur - nums[i]: + return i + cur += nums[i] + return -1 \ No newline at end of file diff --git a/solutions/python3/bak/725.py.bak b/solutions/python3/bak/725.py.bak new file mode 100644 index 0000000..b7dd08f --- /dev/null +++ b/solutions/python3/bak/725.py.bak @@ -0,0 +1,29 @@ +class Solution: + def splitListToParts(self, root: ListNode, k: int) -> List[ListNode]: + n = 0 + node = root + while node: + n += 1 + node = node.next + count = n // k + residual = n % k + + i = 0 + ret = [[] for _ in range(k)] + prev = root + while prev and k > 0: + node = prev + leftover = count + ret[i] = node + i += 1 + while node and leftover > 1: + node = node.next + leftover -= 1 + if node and count != 0 and residual: + node = node.next + residual -= 1 + prev = node.next if node else None + if node: + node.next = None + k -= 1 + return ret diff --git a/solutions/python3/bak/726.py.bak b/solutions/python3/bak/726.py.bak new file mode 100644 index 0000000..47630d9 --- /dev/null +++ b/solutions/python3/bak/726.py.bak @@ -0,0 +1,22 @@ +class Solution: + def countOfAtoms(self, formula): + dic, coeff, stack, elem, cnt, i = collections.defaultdict(int), 1, [], "", 0, 0 + for c in formula[::-1]: + if c.isdigit(): + cnt += int(c) * (10 ** i) + i += 1 + elif c == ")": + stack.append(cnt) + coeff *= cnt + i = cnt = 0 + elif c == "(": + coeff //= stack.pop() + i = cnt = 0 + elif c.isupper(): + elem += c + dic[elem[::-1]] += (cnt or 1) * coeff + elem = "" + i = cnt = 0 + elif c.islower(): + elem += c + return "".join(k + str(v > 1 and v or "") for k, v in sorted(dic.items())) \ No newline at end of file diff --git a/solutions/python3/bak/727.py.bak b/solutions/python3/bak/727.py.bak new file mode 100644 index 0000000..948cad2 --- /dev/null +++ b/solutions/python3/bak/727.py.bak @@ -0,0 +1,16 @@ +class Solution: + def minWindow(self, S: str, T: str) -> str: + def dfs(i, j): + if j == len(T): return i + if (i, j) not in memo: + ind = S.find(T[j], i + 1) + memo[(i, j)] = float('inf') if ind == -1 else dfs(ind, j + 1) + return memo[(i, j)] + + l, res, memo = float('inf'), '', {} + for i, s in enumerate(S): + if s == T[0]: + j = dfs(i, 1) + if j - i < l: + l, res = j - i, S[i:j + 1] + return res \ No newline at end of file diff --git a/solutions/python3/bak/728.py.bak b/solutions/python3/bak/728.py.bak new file mode 100644 index 0000000..2e4d4ac --- /dev/null +++ b/solutions/python3/bak/728.py.bak @@ -0,0 +1,8 @@ +class Solution: + def selfDividingNumbers(self, left, right): + """ + :type left: int + :type right: int + :rtype: List[int] + """ + return [num for num in range(left,right+1) if len([char for char in str(num) if int(char)!=0 and num%int(char)==0])==len(str(num)) ] \ No newline at end of file diff --git a/solutions/python3/bak/729.py.bak b/solutions/python3/bak/729.py.bak new file mode 100644 index 0000000..1166a02 --- /dev/null +++ b/solutions/python3/bak/729.py.bak @@ -0,0 +1,38 @@ +class Node: + def __init__(self,s,e): + self.e = e + self.s = s + self.left = None + self.right = None +class MyCalendar: + + def __init__(self): + self.root = None + + def book_helper(self,s,e,node): + if s>=node.e: + if node.right: return self.book_helper(s,e,node.right) + else: + node.right = Node(s,e) + return True + elif e<=node.s: + if node.left: return self.book_helper(s,e,node.left) + else: + node.left = Node(s,e) + return True + else: return False + def book(self, start, end): + """ + :type start: int + :type end: int + :rtype: bool + """ + if not self.root: + self.root = Node(start,end) + return True + return self.book_helper(start,end,self.root) + + +# Your MyCalendar object will be instantiated and called as such: +# obj = MyCalendar() +# param_1 = obj.book(start,end) \ No newline at end of file diff --git a/solutions/python3/bak/73.py.bak b/solutions/python3/bak/73.py.bak new file mode 100644 index 0000000..f7b1296 --- /dev/null +++ b/solutions/python3/bak/73.py.bak @@ -0,0 +1,16 @@ +class Solution: + def setZeroes(self, matrix): + m, n, x = len(matrix), len(matrix and matrix[0]), 0 + for i in range(m): + for j in range(n): + if i < m - 1 and not matrix[i][j] and matrix[i + 1][j]: matrix[i + 1][j] = None + for i in range(m - 1, -1, -1): + for j in range(n - 1, -1, -1): + if i > 0 and not matrix[i][j] and matrix[i - 1][j]: matrix[i - 1][j] = None + while x < m: + y = 0 + while y < n: + if matrix[x][y] == 0: matrix[x], y = [0] * n, n + elif not matrix[x][y]: matrix[x][y] = 0 + y += 1 + x += 1 \ No newline at end of file diff --git a/solutions/python3/bak/730.py.bak b/solutions/python3/bak/730.py.bak new file mode 100644 index 0000000..b2c9512 --- /dev/null +++ b/solutions/python3/bak/730.py.bak @@ -0,0 +1,13 @@ +class Solution: + def countPalindromicSubsequences(self, S): + mod, memo = 10 ** 9 + 7, {} + def dfs(i, j): + if (i, j) not in memo: + cnt = 0 + for x in "abcd": + try: l, r = S[i:j + 1].index(x) + i, S[i:j + 1].rindex(x) + i + except: continue + cnt += l != r and dfs(l + 1, r - 1) + 2 or 1 + memo[(i, j)] = cnt % mod + return memo[(i, j)] + return dfs(0, len(S) - 1) \ No newline at end of file diff --git a/solutions/python3/bak/731.py.bak b/solutions/python3/bak/731.py.bak new file mode 100644 index 0000000..1300c22 --- /dev/null +++ b/solutions/python3/bak/731.py.bak @@ -0,0 +1,14 @@ +class MyCalendarTwo: + def __init__(self): + self.overlaps = [] + self.calendar = [] + + def book(self, start, end): + for i, j in self.overlaps: + if start < j and end > i: + return False + for i, j in self.calendar: + if start < j and end > i: + self.overlaps.append((max(start, i), min(end, j))) + self.calendar.append((start, end)) + return True \ No newline at end of file diff --git a/solutions/python3/bak/732.py.bak b/solutions/python3/bak/732.py.bak new file mode 100644 index 0000000..bd8d007 --- /dev/null +++ b/solutions/python3/bak/732.py.bak @@ -0,0 +1,13 @@ +class MyCalendarThree: + + def __init__(self): + self.times = [] + + def book(self, start, end): + bisect.insort(self.times, (start, 1)) + bisect.insort(self.times, (end, -1)) + res = cur = 0 + for _, x in self.times: + cur += x + res = max(res, cur) + return res \ No newline at end of file diff --git a/solutions/python3/bak/733.py.bak b/solutions/python3/bak/733.py.bak new file mode 100644 index 0000000..9f7c028 --- /dev/null +++ b/solutions/python3/bak/733.py.bak @@ -0,0 +1,12 @@ +class Solution: + def floodFill(self, image, sr, sc, newColor): + old, m, n = image[sr][sc], len(image), len(image[0]) + if old != newColor: + q = collections.deque([(sr, sc)]) + while q: + i, j = q.popleft() + image[i][j] = newColor + for x, y in ((i - 1, j), (i + 1, j), (i, j - 1), (i, j + 1)): + if 0 <= x < m and 0 <= y < n and image[x][y] == old: + q.append((x, y)) + return image \ No newline at end of file diff --git a/solutions/python3/bak/734.py.bak b/solutions/python3/bak/734.py.bak new file mode 100644 index 0000000..9e7e09f --- /dev/null +++ b/solutions/python3/bak/734.py.bak @@ -0,0 +1,7 @@ +class Solution: + def areSentencesSimilar(self, words1: List[str], words2: List[str], pairs: List[List[str]]) -> bool: + sim = collections.defaultdict(set) + for a, b in pairs: + sim[a].add(b) + sim[b].add(a) + return len(words1) == len(words2) and all(w1 == w2 or w2 in sim[w1] for w1, w2 in zip(words1, words2)) \ No newline at end of file diff --git a/solutions/python3/bak/735.py.bak b/solutions/python3/bak/735.py.bak new file mode 100644 index 0000000..2296703 --- /dev/null +++ b/solutions/python3/bak/735.py.bak @@ -0,0 +1,14 @@ +class Solution: + def asteroidCollision(self, asteroids): + """ + :type asteroids: List[int] + :rtype: List[int] + """ + stack = [] + for asteroid in asteroids: + stack.append(asteroid) + while len(stack) > 1 and stack[-2] > 0 and stack[-1] < 0: + if stack[-2] < abs(stack[-1]): stack[-2] = stack[-1] + elif stack[-2] == abs(stack[-1]): stack.pop() + stack.pop() + return stack \ No newline at end of file diff --git a/solutions/python3/bak/736.py.bak b/solutions/python3/bak/736.py.bak new file mode 100644 index 0000000..6ae6d8e --- /dev/null +++ b/solutions/python3/bak/736.py.bak @@ -0,0 +1,26 @@ +class Solution: + def evaluate(self, expression): + scopes, items = [{}], [["root"]] + for item in expression.replace(")", " )").split(): + if item[0] == "(": + items.append([item[1:]]) + if item[1:] == "let": + scopes.append(dict(scopes[-1])) + continue + elif item == ")": + if items[-1][0] == "add": + item = str(int(items[-1][1]) + int(items[-1][-1])) + elif items[-1][0] == "mult": + item = str(int(items[-1][1]) * int(items[-1][-1])) + else: + item = items[-1][-1] + if item in scopes[-1]: + item = scopes[-1][item] + scopes.pop() + items.pop() + if item in scopes[-1] and (items[-1][0] != "let" or len(items[-1]) % 2 == 0): + item = scopes[-1][item] + if items[-1][0] == "let" and item.lstrip("-").isdigit(): + scopes[-1][items[-1][-1]] = item + items[-1].append(item) + return int(items[-1][-1]) \ No newline at end of file diff --git a/solutions/python3/bak/737.py.bak b/solutions/python3/bak/737.py.bak new file mode 100644 index 0000000..8a6c98f --- /dev/null +++ b/solutions/python3/bak/737.py.bak @@ -0,0 +1,23 @@ +class Solution: + def areSentencesSimilarTwo(self, words1, words2, pairs): + def dfs(node, Id): + cc[node] = Id + for v in adj[node]: + if v not in cc: + dfs(v, Id) + l1, l2, adj, cc = len(words1), len(words2), collections.defaultdict(set), {} + if l1 != l2: + return False + for a, b in pairs: + adj[a].add(b) + adj[b].add(a) + for Id, k in enumerate(adj): + if k not in cc: + dfs(k, Id) + for w1, w2 in zip(words1, words2): + if w1 not in cc or w2 not in cc: + if w1 != w2: + return False + elif cc[w1] != cc[w2]: + return False + return True \ No newline at end of file diff --git a/solutions/python3/bak/738.py.bak b/solutions/python3/bak/738.py.bak new file mode 100644 index 0000000..a3f94d4 --- /dev/null +++ b/solutions/python3/bak/738.py.bak @@ -0,0 +1,11 @@ +class Solution: + def monotoneIncreasingDigits(self, N): + """ + :type N: int + :rtype: int + """ + n, pos = str(N), 0 + for i, char in enumerate(n): + if i>0 and int(n[i])1 else int("9"*(len(n)-1-pos)) + elif i>0 and n[i] != n[i-1]: pos = i + return N \ No newline at end of file diff --git a/solutions/python3/bak/739.py.bak b/solutions/python3/bak/739.py.bak new file mode 100644 index 0000000..c0f1f0d --- /dev/null +++ b/solutions/python3/bak/739.py.bak @@ -0,0 +1,11 @@ +class Solution: + def dailyTemperatures(self, T: List[int]) -> List[int]: + res = [0] * len(T) + heap = [] + for j, t in enumerate(T): + while heap and heap[0][0] < t: + temp, i = heapq.heappop(heap) + res[i] = j - i + heapq.heappush(heap, (t, j)) + return res + \ No newline at end of file diff --git a/solutions/python3/bak/74.py.bak b/solutions/python3/bak/74.py.bak new file mode 100644 index 0000000..9a3bd66 --- /dev/null +++ b/solutions/python3/bak/74.py.bak @@ -0,0 +1,4 @@ +class Solution: + def searchMatrix(self, matrix, target): + ls = list(itertools.chain(*matrix)) + return ls and ls[bisect.bisect(ls, target) - 1] == target or False \ No newline at end of file diff --git a/solutions/python3/bak/740.py.bak b/solutions/python3/bak/740.py.bak new file mode 100644 index 0000000..7584ef7 --- /dev/null +++ b/solutions/python3/bak/740.py.bak @@ -0,0 +1,21 @@ +class Solution: + def deleteAndEarn(self, nums): + cnt, dp, maxs = collections.Counter(nums), {}, {} + nums = sorted(set(nums)) + if len(nums) < 2: + return nums and nums[0] * cnt[nums[0]] or 0 + for i in range(len(nums)): + dp[i] = nums[i] * cnt[nums[i]] + if i >= 2: + if nums[i - 1] < nums[i] - 1: + dp[i] += maxs[i - 1] + else: + dp[i] += maxs[i - 2] + maxs[i] = max(dp[i], maxs[i - 1]) + elif i: + if nums[i - 1] < nums[i] - 1: + dp[i] += dp[i - 1] + maxs[i] = max(dp[i], dp[i - 1]) + else: + maxs[i] = dp[i] + return max(dp[len(nums) - 1], dp[len(nums) - 2]) \ No newline at end of file diff --git a/solutions/python3/bak/741.py.bak b/solutions/python3/bak/741.py.bak new file mode 100644 index 0000000..a543ba5 --- /dev/null +++ b/solutions/python3/bak/741.py.bak @@ -0,0 +1,15 @@ +class Solution(object): + def cherryPickup(self, grid): + if grid[-1][-1] == -1: return 0 + memo, n = {}, len(grid) + def dp(i1, j1, i2, j2): + if (i1, j1, i2, j2) in memo: return memo[(i1, j1, i2, j2)] + if n in (i1, j1, i2, j2) or -1 in (grid[i1][j1], grid[i2][j2]): return -1 + if i1 == i2 == j1 == j2 == n - 1: return grid[-1][-1] + mx = max(dp(i1+1, j1, i2+1, j2), dp(i1+1, j1, i2, j2+1), dp(i1, j1+1, i2+1, j2), dp(i1, j1+1, i2, j2+1)) + if mx == - 1: out = -1 + elif i1 == i2 and j1 == j2: out = mx + grid[i1][j1] + else: out = mx + grid[i1][j1] + grid[i2][j2] + memo[(i1, j1, i2, j2)] = out + return out + return max(0, dp(0, 0, 0, 0)) \ No newline at end of file diff --git a/solutions/python3/bak/742.py.bak b/solutions/python3/bak/742.py.bak new file mode 100644 index 0000000..f565587 --- /dev/null +++ b/solutions/python3/bak/742.py.bak @@ -0,0 +1,34 @@ +# Definition for a binary tree node. +# class TreeNode: +# def __init__(self, x): +# self.val = x +# self.left = None +# self.right = None + +class Solution: + def findClosestLeaf(self, root, k): + adj, q, visited = collections.defaultdict(list), [], collections.defaultdict(int) + def dfs(node): + if node: + if node.val == k: + q.append(node) + visited[node.val] = 1 + if node.left: + adj[node].append(node.left) + adj[node.left].append(node) + dfs(node.left) + if node.right: + adj[node].append(node.right) + adj[node.right].append(node) + dfs(node.right) + dfs(root) + while q: + new = [] + for node in q: + if not node.left and not node.right: + return node.val + for v in adj[node]: + if not visited[v.val]: + visited[v.val] = 1 + new.append(v) + q = new \ No newline at end of file diff --git a/solutions/python3/bak/743.py.bak b/solutions/python3/bak/743.py.bak new file mode 100644 index 0000000..c41b7f8 --- /dev/null +++ b/solutions/python3/bak/743.py.bak @@ -0,0 +1,12 @@ +class Solution: + def networkDelayTime(self, times, N, K): + q, t, adj = [(0, K)], {}, collections.defaultdict(list) + for u, v, w in times: + adj[u].append((v, w)) + while q: + time, node = heapq.heappop(q) + if node not in t: + t[node] = time + for v, w in adj[node]: + heapq.heappush(q, (time + w, v)) + return max(t.values()) if len(t) == N else -1 \ No newline at end of file diff --git a/solutions/python3/bak/744.py.bak b/solutions/python3/bak/744.py.bak new file mode 100644 index 0000000..8a28600 --- /dev/null +++ b/solutions/python3/bak/744.py.bak @@ -0,0 +1,3 @@ +class Solution: + def nextGreatestLetter(self, letters, target): + return letters[bisect.bisect(letters, target) % len(letters)] \ No newline at end of file diff --git a/solutions/python3/bak/745.py.bak b/solutions/python3/bak/745.py.bak new file mode 100644 index 0000000..e691acc --- /dev/null +++ b/solutions/python3/bak/745.py.bak @@ -0,0 +1,11 @@ +class WordFilter: + def __init__(self, words): + self.p, self.s, self.ind = collections.defaultdict(set), collections.defaultdict(set), {} + for i, w in enumerate(words): + self.ind[w] = i + self.p[""].add(w) + self.s[""].add(w) + for i in range(1, len(w) + 1): + self.p[w[:i]].add(w) + self.s[w[-i:]].add(w) + def f(self, prefix, suffix): return max((self.ind[c] for c in self.p[prefix] & self.s[suffix]), default = -1) \ No newline at end of file diff --git a/solutions/python3/bak/746.py.bak b/solutions/python3/bak/746.py.bak new file mode 100644 index 0000000..dfe2842 --- /dev/null +++ b/solutions/python3/bak/746.py.bak @@ -0,0 +1,8 @@ +class Solution: + def minCostClimbingStairs(self, cost): + """ + :type cost: List[int] + :rtype: int + """ + for i in range(2,len(cost)): cost[i]+=min(cost[i-1],cost[i-2]) + return min(cost[-1],cost[-2]) \ No newline at end of file diff --git a/solutions/python3/bak/747.py.bak b/solutions/python3/bak/747.py.bak new file mode 100644 index 0000000..7f816ed --- /dev/null +++ b/solutions/python3/bak/747.py.bak @@ -0,0 +1,4 @@ +class Solution: + def dominantIndex(self, nums: List[int]) -> int: + mx = max(nums) + return nums.index(mx) if all(num * 2 <= mx for num in nums if num < mx) else -1 \ No newline at end of file diff --git a/solutions/python3/bak/748.py.bak b/solutions/python3/bak/748.py.bak new file mode 100644 index 0000000..ec1ea82 --- /dev/null +++ b/solutions/python3/bak/748.py.bak @@ -0,0 +1,8 @@ +class Solution: + def shortestCompletingWord(self, lp, words): + cntr_lp, res = {k: v for k, v in collections.Counter(lp.lower()).items() if k.isalpha()}, [None, None] + for word in words: + check = collections.Counter(word.lower()) + if all(True if k in check and v <= check[k] else False for k, v in cntr_lp.items()): + if not any(res) or len(word) < res[1]: res = [word, len(word)] + return res[0] \ No newline at end of file diff --git a/solutions/python3/bak/749.py.bak b/solutions/python3/bak/749.py.bak new file mode 100644 index 0000000..11aa81e --- /dev/null +++ b/solutions/python3/bak/749.py.bak @@ -0,0 +1,85 @@ +class Solution(object): + def containVirus(self, grid): + """ + :type grid: List[List[int]] + :rtype: int + """ + if not grid: return None + N,M=len(grid),len(grid[0]) + + def around(r,c,t=None): + # all cells 1-step away from (r,c) + # optionally, if t!=None, target value must be t + for d in (-1,1): + for (rr,cc) in ((r+d,c), (r,c+d)): + if 0<=rr List[str]: + s = ''.join(bin(int(num))[2:].zfill(8) for num in ip.split('.')) + res = [] + while n: + for i in range(31 - s.rindex('1'), -1, -1): + if 2 ** i <= n: + res.append('.'.join(str(int(s[i:i + 8], 2)) for i in range(0, 32, 8)) + '/' + str(32 - i)) + n -= 2 ** i + s = bin(int(s, 2) + 2 ** i)[2:].zfill(32) + break + return res + \ No newline at end of file diff --git a/solutions/python3/bak/752.py.bak b/solutions/python3/bak/752.py.bak new file mode 100644 index 0000000..dad7806 --- /dev/null +++ b/solutions/python3/bak/752.py.bak @@ -0,0 +1,18 @@ +class Solution: + def openLock(self, deadends, target): + moved, q, cnt, move = set(deadends), ["0000"], 0, {str(i): [str((i + 1) % 10), str((i - 1) % 10)] for i in range(10)} + if "0000" in moved: + return -1 + while q: + new = [] + cnt += 1 + for s in q: + for i, c in enumerate(s): + for cur in (s[:i] + move[c][0] + s[i + 1:], s[:i] + move[c][1] + s[i + 1:]): + if cur not in moved: + if cur == target: + return cnt + new.append(cur) + moved.add(cur) + q = new + return -1 \ No newline at end of file diff --git a/solutions/python3/bak/753.py.bak b/solutions/python3/bak/753.py.bak new file mode 100644 index 0000000..7f54c78 --- /dev/null +++ b/solutions/python3/bak/753.py.bak @@ -0,0 +1,7 @@ +class Solution: + def crackSafe(self, n, k): + s = '0' * (n - 1) + D = '9876543210'[-k:] + for _ in range(k**n): + s += next(d for d in D if (s + d)[-n:] not in s) + return s \ No newline at end of file diff --git a/solutions/python3/bak/754.py.bak b/solutions/python3/bak/754.py.bak new file mode 100644 index 0000000..87250d3 --- /dev/null +++ b/solutions/python3/bak/754.py.bak @@ -0,0 +1,7 @@ +class Solution: + def reachNumber(self, target): + pos, step, target = 0, 0, abs(target) + while pos < target or (pos - target) % 2: + step += 1 + pos += step + return step \ No newline at end of file diff --git a/solutions/python3/bak/755.py.bak b/solutions/python3/bak/755.py.bak new file mode 100644 index 0000000..53a278f --- /dev/null +++ b/solutions/python3/bak/755.py.bak @@ -0,0 +1,22 @@ +class Solution: + def pourWater(self, heights, V, K): + for drop in range(V): + l = r = K + for i in range(K - 1, -1, -1): + if heights[i] > heights[l]: + break + elif heights[i] < heights[l]: + l = i + if l < K: + heights[l] += 1 + else: + for j in range(K + 1, len(heights)): + if heights[j] > heights[r]: + break + elif heights[j] < heights[r]: + r = j + if l == r == K: + heights[K] += 1 + elif r > K: + heights[r] += 1 + return heights \ No newline at end of file diff --git a/solutions/python3/bak/756.py.bak b/solutions/python3/bak/756.py.bak new file mode 100644 index 0000000..29aef32 --- /dev/null +++ b/solutions/python3/bak/756.py.bak @@ -0,0 +1,10 @@ +class Solution: + def pyramidTransition(self, bottom, allowed): + chars, allowed = 'ABCDEFG', set(allowed) + def dfs(r, q, i): + if len(r) == 1: + return True + for c in chars: + if r[i:i+2]+c in allowed and (i==len(r)-2 and dfs(q+c,"",0) or dfs(r,q+c,i+1)): return True + return False + return dfs(bottom, "", 0) \ No newline at end of file diff --git a/solutions/python3/bak/757.py.bak b/solutions/python3/bak/757.py.bak new file mode 100644 index 0000000..aad03df --- /dev/null +++ b/solutions/python3/bak/757.py.bak @@ -0,0 +1,11 @@ +class Solution(object): + def intersectionSizeTwo(self, intervals): + intervals.sort(key = lambda k: k[1]) + solution = [] + for start, end in intervals: + if not len(solution) or solution[-1] < start: + solution.append(end - 1) + solution.append(end) + elif solution[-2] < start: + solution.append(end) + return len(solution) \ No newline at end of file diff --git a/solutions/python3/bak/758.py.bak b/solutions/python3/bak/758.py.bak new file mode 100644 index 0000000..fc63da1 --- /dev/null +++ b/solutions/python3/bak/758.py.bak @@ -0,0 +1,24 @@ +class Solution: + def boldWords(self, words, S): + trie, n, mask, res = {}, len(S), set(), "" + for w in words: + cur = trie + for c in w: + if c not in cur: + cur[c] = {} + cur = cur[c] + cur["#"] = cur.get("#", set()) | {w} + for i in range(n): + cur, j = trie, i + while j < n and S[j] in cur: + cur = cur[S[j]] + if "#" in cur: + mask |= {ind for ind in range(i, j + 1)} + j += 1 + for i in range(n): + if i in mask and (not i or i - 1 not in mask): + res += "" + res += S[i] + if i in mask and (i == n - 1 or i + 1 not in mask): + res += "" + return res \ No newline at end of file diff --git a/solutions/python3/bak/759.py.bak b/solutions/python3/bak/759.py.bak new file mode 100644 index 0000000..ff5e1e3 --- /dev/null +++ b/solutions/python3/bak/759.py.bak @@ -0,0 +1,19 @@ +# Definition for an interval. +# class Interval: +# def __init__(self, s=0, e=0): +# self.start = s +# self.end = e + +class Solution: + def employeeFreeTime(self, schedule): + intervals = sorted(((intr.start, intr.end) for emp in schedule for intr in emp), key = lambda x: x[0]) + res, stack = [], [] + for s, e in intervals: + if not stack: + stack.append((s, e)) + elif s <= stack[-1][-1]: + stack.append((s, max(e, stack.pop()[1]))) + else: + res.append([stack[-1][1], s]) + stack.append((s, e)) + return res \ No newline at end of file diff --git a/solutions/python3/bak/76.py.bak b/solutions/python3/bak/76.py.bak new file mode 100644 index 0000000..3216e18 --- /dev/null +++ b/solutions/python3/bak/76.py.bak @@ -0,0 +1,24 @@ +class Solution: + def minWindow(self, s, t): + cnt_s, cnt_t, n, left, r = {}, {}, len(s), set(t), -1 + for c in t: + cnt_t[c] = cnt_t.get(c, 0) + 1 + L = l = 0 + while left: + r += 1 + if r >= n: + return "" + cnt_s[s[r]] = cnt_s.get(s[r], 0) + 1 + if s[r] in cnt_t and cnt_s[s[r]] == cnt_t[s[r]]: + left.discard(s[r]) + R = r + cnt_s[s[r]] -= 1 + while l < r < n: + cnt_s[s[r]] = cnt_s.get(s[r], 0) + 1 + while s[l] not in cnt_t or cnt_s[s[l]] > cnt_t[s[l]]: + cnt_s[s[l]] -= 1 + l += 1 + if r - l < R - L: + L, R = l, r + r += 1 + return s[L: R + 1] \ No newline at end of file diff --git a/solutions/python3/bak/760.py.bak b/solutions/python3/bak/760.py.bak new file mode 100644 index 0000000..20c5b59 --- /dev/null +++ b/solutions/python3/bak/760.py.bak @@ -0,0 +1,4 @@ +class Solution: + def anagramMappings(self, A, B): + ind = {num: j for j, num in enumerate(B)} + return [ind[num] for num in A] \ No newline at end of file diff --git a/solutions/python3/bak/761.py.bak b/solutions/python3/bak/761.py.bak new file mode 100644 index 0000000..aa861fb --- /dev/null +++ b/solutions/python3/bak/761.py.bak @@ -0,0 +1,10 @@ +class Solution: + def makeLargestSpecial(self, S: str) -> str: + count = i = 0 + res = [] + for j, v in enumerate(S): + count = count + 1 if v=='1' else count - 1 + if count == 0: + res.append('1' + self.makeLargestSpecial(S[i + 1:j]) + '0') + i = j + 1 + return ''.join(sorted(res)[::-1]) \ No newline at end of file diff --git a/solutions/python3/bak/762.py.bak b/solutions/python3/bak/762.py.bak new file mode 100644 index 0000000..c382476 --- /dev/null +++ b/solutions/python3/bak/762.py.bak @@ -0,0 +1,16 @@ +class Solution: + def countPrimeSetBits(self, L, R): + """ + :type L: int + :type R: int + :rtype: int + """ + count=0 + while L<=R: + if str(bin(L)[2:]).count("1") in [2,3,5,7,11,13,17,19]: count+=1 + if str(bin(R)[2:]).count("1") in [2,3,5,7,11,13,17,19]: + count+=1 + if L==R: count-=1 + L+=1 + R-=1 + return count \ No newline at end of file diff --git a/solutions/python3/bak/763.py.bak b/solutions/python3/bak/763.py.bak new file mode 100644 index 0000000..9595376 --- /dev/null +++ b/solutions/python3/bak/763.py.bak @@ -0,0 +1,14 @@ +class Solution: + def partitionLabels(self, S): + """ + :type S: str + :rtype: List[int] + """ + sizes = [] + while S: + i = 1 + while set(S[:i]) & set(S[i:]): + i += 1 + sizes.append(i) + S = S[i:] + return sizes \ No newline at end of file diff --git a/solutions/python3/bak/764.py.bak b/solutions/python3/bak/764.py.bak new file mode 100644 index 0000000..6d0f042 --- /dev/null +++ b/solutions/python3/bak/764.py.bak @@ -0,0 +1,28 @@ +class Solution: + def orderOfLargestPlusSign(self, N, mines): + #up, left, down, right + dp, res, mines = [[[0, 0, 0, 0] for j in range(N)] for i in range(N)], 0, {(i, j) for i, j in mines} + for i in range(N): + for j in range(N): + if (i, j) not in mines: + try: + dp[i][j][0] = dp[i - 1][j][0] + 1 + except: + dp[i][j][0] = 1 + try: + dp[i][j][1] = dp[i][j - 1][1] + 1 + except: + dp[i][j][1] = 1 + for i in range(N - 1, -1, -1): + for j in range(N - 1, -1, -1): + if (i, j) not in mines: + try: + dp[i][j][2] = dp[i + 1][j][2] + 1 + except: + dp[i][j][2] = 1 + try: + dp[i][j][3] = dp[i][j + 1][3] + 1 + except: + dp[i][j][3] = 1 + res = max(res, min(dp[i][j])) + return res \ No newline at end of file diff --git a/solutions/python3/bak/765.py.bak b/solutions/python3/bak/765.py.bak new file mode 100644 index 0000000..f5b0f00 --- /dev/null +++ b/solutions/python3/bak/765.py.bak @@ -0,0 +1,15 @@ +class Solution: + def minSwapsCouples(self, row): + res, index = 0, {num: i for i, num in enumerate(row)} + for i in range(0, len(row), 2): + if row[i] % 2 == 0 and row[i + 1] != row[i] + 1: + f = row[i + 1] + row[i + 1], row[index[row[i] + 1]] = row[i] + 1, row[i + 1] + index[row[i] + 1], index[f] = i + 1, index[row[i] + 1] + res += 1 + elif row[i] % 2 != 0 and row[i + 1] != row[i] - 1: + f = row[i + 1] + row[i + 1], row[index[row[i] - 1]], index[row[i + 1]] = row[i] - 1, row[i + 1], index[row[i] - 1] + index[row[i] - 1], index[f] = i + 1, index[row[i] - 1] + res += 1 + return res \ No newline at end of file diff --git a/solutions/python3/bak/766.py.bak b/solutions/python3/bak/766.py.bak new file mode 100644 index 0000000..fc8c10f --- /dev/null +++ b/solutions/python3/bak/766.py.bak @@ -0,0 +1,3 @@ +class Solution: + def isToeplitzMatrix(self, matrix): + return all(matrix[i][j] == matrix[i - 1][j - 1] for i in range(1, len(matrix)) for j in range(1, len(matrix[0]))) \ No newline at end of file diff --git a/solutions/python3/bak/767.py.bak b/solutions/python3/bak/767.py.bak new file mode 100644 index 0000000..b74b9a4 --- /dev/null +++ b/solutions/python3/bak/767.py.bak @@ -0,0 +1,9 @@ +class Solution: + def reorganizeString(self, S): + cnt, res = collections.Counter(S), "" + while len(res) < len(S): + c, i = cnt.most_common()[0], 0 + while i + 1 < len(cnt) and (res and res[-1] == c[0] or cnt[c[0]] == 0): c, i = cnt.most_common()[i + 1], i + 1 + if not cnt[c[0]] or res and res[-1] == c[0]: return "" + else: res, cnt[c[0]] = res + c[0], cnt[c[0]] - 1 + return res \ No newline at end of file diff --git a/solutions/python3/bak/768.py.bak b/solutions/python3/bak/768.py.bak new file mode 100644 index 0000000..80de3f5 --- /dev/null +++ b/solutions/python3/bak/768.py.bak @@ -0,0 +1,12 @@ +class Solution: + def maxChunksToSorted(self, arr): + mx, mn, res, check = 0, 10 ** 9, 0, [[0, 0] for _ in range(len(arr))] + for i in range(len(arr)): + if arr[i] > mx: mx = arr[i] + check[i][0] = mx + for i in range(len(arr) -1, -1, -1): + check[i][1] = mn + if arr[i] < mn: mn = arr[i] + for c in check: + if c[0] <= c[1]: res += 1 + return res \ No newline at end of file diff --git a/solutions/python3/bak/769.py.bak b/solutions/python3/bak/769.py.bak new file mode 100644 index 0000000..c94f34d --- /dev/null +++ b/solutions/python3/bak/769.py.bak @@ -0,0 +1,13 @@ +class Solution: + def maxChunksToSorted(self, arr): + """ + :type arr: List[int] + :rtype: int + """ + max_seen, total_seen, res_count = 0, 0, 0 + for num in arr: + max_seen = max(max_seen, num) + total_seen += 1 + if max_seen == total_seen - 1: + res_count += 1 + return res_count \ No newline at end of file diff --git a/solutions/python3/bak/77.py.bak b/solutions/python3/bak/77.py.bak new file mode 100644 index 0000000..c452199 --- /dev/null +++ b/solutions/python3/bak/77.py.bak @@ -0,0 +1,6 @@ +class Solution: + def combine(self, n: int, k: int) -> List[List[int]]: + bfs = [[]] + for num in range(1, n + 1): + bfs += [arr + [num] for arr in bfs if len(arr) < k] + return [arr for arr in bfs if len(arr) == k] \ No newline at end of file diff --git a/solutions/python3/bak/770.py.bak b/solutions/python3/bak/770.py.bak new file mode 100644 index 0000000..26f0a7c --- /dev/null +++ b/solutions/python3/bak/770.py.bak @@ -0,0 +1,91 @@ +class Solution(object): + def basicCalculatorIV(self, s, evalvars, evalints): + s.strip() + d = dict(zip(evalvars, evalints)) + s = s.replace(' ', '') + ts = re.findall('\u005Cd+|[-()+*]|[^-()+*]+', s) + + def add(p, q): + i, j = 0, 0 + r = [] + while i < len(p) and j < len(q): + v, c = p[i] + v2, c2 = q[j] + if v == v2: + if c + c2 != 0: + r.append((v, c + c2)) + i += 1 + j += 1 + elif len(v) > len(v2) or len(v) == len(v2) and v < v2: + r.append(p[i]) + i += 1 + else: + r.append(q[j]) + j += 1 + + r += p[i:] + r += q[j:] + return r + + def neg(p): + r = [] + for v, c in p: + r.append((v, -c)) + return r + + def sub(p, q): + return add(p, neg(q)) + + def mult(p, q): + r = [] + for v, c in p: + for v2, c2 in q: + r = add(r, [(sorted(v + v2), c * c2)]) + return r + + def prec(c): + return 0 if c in [')'] else 1 if c in ['+', '-'] else 2 + + i = 0 + def expr(p): + nonlocal i, ts + if ts[i] == '(': + i += 1 + v = expr(0) + i += 1 + elif ts[i] == '-': + i += 1 + v = neg(expr(3)) + elif re.match('\u005Cd+', ts[i]): + if ts[i] != '0': + v = [([], int(ts[i]))] + else: + v = [] + else: + if ts[i] in d: + if d[ts[i]] != 0: + v = [([], d[ts[i]])] + else: + v = [] + else: + v = [([ts[i]], 1)] + while i < len(ts) - 2 and prec(ts[i+1]) > p: + op = ts[i+1] + i += 2 + v2 = expr(prec(op)) + if op == '+': v = add(v, v2) + if op == '-': v = sub(v, v2) + if op == '*': v = mult(v, v2) + + return v + + def tostrings(p): + r = [] + for v, c in p: + if v == []: + r.append(str(c)) + else: + r.append(str(c) + '*' + '*'.join(v)) + return r + + return tostrings(expr(0)) \ No newline at end of file diff --git a/solutions/python3/bak/771.py.bak b/solutions/python3/bak/771.py.bak new file mode 100644 index 0000000..1207177 --- /dev/null +++ b/solutions/python3/bak/771.py.bak @@ -0,0 +1,4 @@ +class Solution: + def numJewelsInStones(self, J, S): + sj = set(J) + return sum(s in sj for s in S) \ No newline at end of file diff --git a/solutions/python3/bak/772.py.bak b/solutions/python3/bak/772.py.bak new file mode 100644 index 0000000..1c57a8e --- /dev/null +++ b/solutions/python3/bak/772.py.bak @@ -0,0 +1,28 @@ +class Solution: + def calculate(self, s: str) -> int: + def calc(n2, op, n1): + return n1 * n2 if op == '*' else n1 // n2 if op == '/' else n1 + n2 if op == '+' else n1 - n2 + def calc2(arr): + if len(arr) == 1: + return arr.pop() + res = arr[0] + for j in range(2, len(arr), 2): + res = calc(arr[j], arr[j - 1], res) + return res + stack, i, num = [], 0, 0 + while i < len(s): + j = i + while j < len(s) and s[j].isdigit(): + num, j = num * 10 + int(s[j]), j + 1 + if i != j: + stack.append(calc(num, stack.pop(), stack.pop()) if stack and stack[-1] in "*/" else num) + num, j = 0, j - 1 + elif s[i] == ")": + ind = len(stack) - stack[::-1].index('(') - 1 + stack[ind:] = [calc2(stack[ind + 1:])] + if len(stack) > 1 and stack[-2] in '*/': + stack.append(calc(stack.pop(), stack.pop(), stack.pop())) + elif s[i] != ' ': + stack.append(s[i]) + i = j + 1 + return calc2(stack) \ No newline at end of file diff --git a/solutions/python3/bak/773.py.bak b/solutions/python3/bak/773.py.bak new file mode 100644 index 0000000..4eae0b1 --- /dev/null +++ b/solutions/python3/bak/773.py.bak @@ -0,0 +1,21 @@ +class Solution: + def slidingPuzzle(self, board): + moves, used, cnt = {0: {1, 3}, 1:{0, 2, 4}, 2:{1, 5}, 3:{0, 4}, 4:{1, 3, 5}, 5:{2, 4}}, set(), 0 + s = "".join(str(c) for row in board for c in row) + q = [(s, s.index("0"))] + while q: + new = [] + for s, i in q: + used.add(s) + if s == "123450": + return cnt + arr = [c for c in s] + for move in moves[i]: + new_arr = arr[:] + new_arr[i], new_arr[move] = new_arr[move], new_arr[i] + new_s = "".join(new_arr) + if new_s not in used: + new.append((new_s, move)) + cnt += 1 + q = new + return -1 \ No newline at end of file diff --git a/solutions/python3/bak/774.py.bak b/solutions/python3/bak/774.py.bak new file mode 100644 index 0000000..a97a950 --- /dev/null +++ b/solutions/python3/bak/774.py.bak @@ -0,0 +1,13 @@ +class Solution: + def minmaxGasDist(self, st, K): + left, right = 1e-6, st[-1] - st[0] + while left + 1e-6 < right: + mid = (left + right) / 2 + count = 0 + for a, b in zip(st, st[1:]): + count += math.ceil((b - a) / mid) - 1 + if count > K: + left = mid + else: + right = mid + return right \ No newline at end of file diff --git a/solutions/python3/bak/775.py.bak b/solutions/python3/bak/775.py.bak new file mode 100644 index 0000000..02fd0a5 --- /dev/null +++ b/solutions/python3/bak/775.py.bak @@ -0,0 +1,5 @@ +class Solution: + def isIdealPermutation(self, A): + for i, num in enumerate(A): + if not (i - 1 <= num <= i + 1): return False + return True \ No newline at end of file diff --git a/solutions/python3/bak/776.py.bak b/solutions/python3/bak/776.py.bak new file mode 100644 index 0000000..9546e45 --- /dev/null +++ b/solutions/python3/bak/776.py.bak @@ -0,0 +1,16 @@ +class Solution: + def splitBST(self, root, V): + if not root: + return [None, None] + if root.val == V: + a = root.right + root.right = None + return [root, a] + elif root.val < V: + small, large = self.splitBST(root.right, V) + root.right = small + return [root, large] + else: + small, large = self.splitBST(root.left, V) + root.left = large + return [small, root] \ No newline at end of file diff --git a/solutions/python3/bak/777.py.bak b/solutions/python3/bak/777.py.bak new file mode 100644 index 0000000..8aa14dc --- /dev/null +++ b/solutions/python3/bak/777.py.bak @@ -0,0 +1,13 @@ +class Solution: + def canTransform(self, start, end): + s, e = collections.defaultdict(list), collections.defaultdict(list) + newS, newE = [c for c in start if c != "X"], [c for c in end if c != "X"] + for i in range(len(start)): + if start[i] != "X": + s[start[i]].append(i) + if end[i] != "X": + e[end[i]].append(i) + if newS == newE and len(s["L"]) == len(e["L"]) and len(s["R"]) == len(e["R"]): + if all(s["R"][i] <= e["R"][i] for i in range(len(s["R"]))) and all(s["L"][i] >= e["L"][i] for i in range(len(s["L"]))): + return True + return False \ No newline at end of file diff --git a/solutions/python3/bak/778.py.bak b/solutions/python3/bak/778.py.bak new file mode 100644 index 0000000..855f39c --- /dev/null +++ b/solutions/python3/bak/778.py.bak @@ -0,0 +1,11 @@ +class Solution: + def swimInWater(self, grid): + heap, res, n, visited = [(grid[0][0], 0, 0)], 0, len(grid), set() + while True: + d, i, j = heapq.heappop(heap) + if d > res: res = d + if i == j == n - 1: return res + for x, y in ((i - 1, j), (i + 1, j), (i, j - 1), (i, j + 1)): + if 0 <= x < n and 0 <= y < n and (x, y) not in visited: + visited.add((x, y)) + heapq.heappush(heap, (grid[x][y], x, y)) \ No newline at end of file diff --git a/solutions/python3/bak/779.py.bak b/solutions/python3/bak/779.py.bak new file mode 100644 index 0000000..4e3353a --- /dev/null +++ b/solutions/python3/bak/779.py.bak @@ -0,0 +1,3 @@ +class Solution: + def kthGrammar(self, N: int, K: int) -> int: + return N > 1 and self.kthGrammar(N - 1, (K + 1) // 2) ^ ((K -1) % 2) or 0 \ No newline at end of file diff --git a/solutions/python3/bak/78.py.bak b/solutions/python3/bak/78.py.bak new file mode 100644 index 0000000..82c4466 --- /dev/null +++ b/solutions/python3/bak/78.py.bak @@ -0,0 +1,10 @@ +class Solution: + def subsets(self, nums): + """ + :type nums: List[int] + :rtype: List[List[int]] + """ + res = [[]] + for num in nums: + res += [item+[num] for item in res] + return res \ No newline at end of file diff --git a/solutions/python3/bak/780.py.bak b/solutions/python3/bak/780.py.bak new file mode 100644 index 0000000..b86c612 --- /dev/null +++ b/solutions/python3/bak/780.py.bak @@ -0,0 +1,4 @@ +class Solution: + def reachingPoints(self, sx, sy, tx, ty): + while sx ans else (dic[ans] + 1, res) + return res \ No newline at end of file diff --git a/solutions/python3/bak/782.py.bak b/solutions/python3/bak/782.py.bak new file mode 100644 index 0000000..b7112b4 --- /dev/null +++ b/solutions/python3/bak/782.py.bak @@ -0,0 +1,15 @@ +class Solution: + def movesToChessboard(self, b): + N = len(b) + if any(b[0][0] ^ b[i][0] ^ b[0][j] ^ b[i][j] for i in range(N) for j in range(N)): return -1 + if not N // 2 <= sum(b[0]) <= (N + 1) // 2: return -1 + if not N // 2 <= sum(b[i][0] for i in range(N)) <= (N + 1) // 2: return -1 + col = sum(b[0][i] == i % 2 for i in range(N)) + row = sum(b[i][0] == i % 2 for i in range(N)) + if N % 2: + if col % 2: col = [col, N - col][col % 2] + if row % 2: row = N - row + else: + col = min(N - col, col) + row = min(N - row, row) + return (col + row) // 2 \ No newline at end of file diff --git a/solutions/python3/bak/783.py.bak b/solutions/python3/bak/783.py.bak new file mode 100644 index 0000000..5deab43 --- /dev/null +++ b/solutions/python3/bak/783.py.bak @@ -0,0 +1,8 @@ +class Solution: + def minDiffInBST(self, root): + def dfs(node): + if not node: return float("inf"), float("inf"), -float("inf") + l, lMn, lMx = dfs(node.left) + r, rMn, rMx = dfs(node.right) + return min(l, node.val - lMx, r, rMn - node.val), min(lMn, node.val), max(rMx, node.val) + return dfs(root)[0] \ No newline at end of file diff --git a/solutions/python3/bak/784.py.bak b/solutions/python3/bak/784.py.bak new file mode 100644 index 0000000..d63910f --- /dev/null +++ b/solutions/python3/bak/784.py.bak @@ -0,0 +1,9 @@ +class Solution: + def letterCasePermutation(self, S: str) -> List[str]: + bfs = [''] + for c in S: + if c.isdigit(): + bfs = [s + c for s in bfs] + else: + bfs = [s + c.lower() for s in bfs] + [s + c.upper() for s in bfs] + return bfs \ No newline at end of file diff --git a/solutions/python3/bak/785.py.bak b/solutions/python3/bak/785.py.bak new file mode 100644 index 0000000..e42ab39 --- /dev/null +++ b/solutions/python3/bak/785.py.bak @@ -0,0 +1,15 @@ +class Solution: + def isBipartite(self, graph): + side = [0] * len(graph) + def dfs(node): + for v in graph[node]: + if side[v] == 0: + side[v] = -side[node] + if not dfs(v): return False + elif side[v] == side[node]: return False + return True + for i in range(len(graph)): + if side[i] == 0: + side[i] = 1 + if not dfs(i): return False + return True \ No newline at end of file diff --git a/solutions/python3/bak/786.py.bak b/solutions/python3/bak/786.py.bak new file mode 100644 index 0000000..3bd3d7e --- /dev/null +++ b/solutions/python3/bak/786.py.bak @@ -0,0 +1,16 @@ +class Solution: + def kthSmallestPrimeFraction(self, A, K): + heap, used = [(A[0] / A[-1], 0, len(A) - 1)], {(0, len(A) - 1)} + for i in range(K): + try: + cur, l, r = heapq.heappop(heap) + used.add((l, r)) + if (l + 1, r) not in used: + heapq.heappush(heap, (A[l + 1] / A[r], l + 1, r)) + used.add((l + 1, r)) + if (l, r - 1) not in used: + heapq.heappush(heap, (A[l] / A[r - 1], l, r - 1)) + used.add((l, r - 1)) + except: + break + return [A[l], A[r]] \ No newline at end of file diff --git a/solutions/python3/bak/787.py.bak b/solutions/python3/bak/787.py.bak new file mode 100644 index 0000000..fee8802 --- /dev/null +++ b/solutions/python3/bak/787.py.bak @@ -0,0 +1,14 @@ +class Solution: + def findCheapestPrice(self, n, flights, src, dst, K): + flight = collections.defaultdict(list) + for s, e, p in flights: + flight[s].append((e, p)) + heap = [(0, src, K + 1)] + while heap: + price, city, stop = heapq.heappop(heap) + if city == dst: + return price + elif stop > 0: + for c, p in flight[city]: + heapq.heappush(heap, (price + p, c, stop - 1)) + return -1 \ No newline at end of file diff --git a/solutions/python3/bak/788.py.bak b/solutions/python3/bak/788.py.bak new file mode 100644 index 0000000..8e2d942 --- /dev/null +++ b/solutions/python3/bak/788.py.bak @@ -0,0 +1,27 @@ +class Solution: + def rotatedDigits(self, N): + """ + :type N: int + :rtype: int + """ + res = 0 + for i in range(1, N + 1): + i = str(i) + tmp = [] + check = True + for char in i: + if char in ("3", "4", "7"): + check = False + break + if char in ("0", "1", "8"): + tmp.append(char) + if char == "2": + tmp.append("5") + if char == "5": + tmp.append("2") + if char == "6": + tmp.append("9") + if char == "9": + tmp.append("6") + if check and i != "".join(tmp): res += 1 + return res \ No newline at end of file diff --git a/solutions/python3/bak/789.py.bak b/solutions/python3/bak/789.py.bak new file mode 100644 index 0000000..b96e4d9 --- /dev/null +++ b/solutions/python3/bak/789.py.bak @@ -0,0 +1,6 @@ +class Solution: + def escapeGhosts(self, ghosts, target): + d = abs(target[0]) + abs(target[1]) + for ghost in ghosts: + if abs(ghost[0] - target[0]) + abs(ghost[1] - target[1]) <= d: return False + return True \ No newline at end of file diff --git a/solutions/python3/bak/79.py.bak b/solutions/python3/bak/79.py.bak new file mode 100644 index 0000000..ed1a570 --- /dev/null +++ b/solutions/python3/bak/79.py.bak @@ -0,0 +1,11 @@ +class Solution: + def exist(self, board, word): + m, n, o = len(board), len(board and board[0]), len(word) + def explore(i, j, k, q): + for x, y in ((i - 1, j), (i, j - 1), (i + 1, j), (i, j + 1)): + if k>=o or (0<=x x_count or x_count-o_count>1: + return False + + if self.check_win_positions(board, 'O'): + if self.check_win_positions(board, 'X'): + return False + return o_count == x_count + + if self.check_win_positions(board, 'X') and x_count!=o_count+1: + return False + + return True \ No newline at end of file diff --git a/solutions/python3/bak/795.py.bak b/solutions/python3/bak/795.py.bak new file mode 100644 index 0000000..64ae34b --- /dev/null +++ b/solutions/python3/bak/795.py.bak @@ -0,0 +1,14 @@ +class Solution: + def numSubarrayBoundedMax(self, A, L, R): + """ + :type A: List[int] + :type L: int + :type R: int + :rtype: int + """ + res, start, diff = 0, -1, 0 + for i in range (len(A)): + if L <= A[i] <= R: diff, res = i - start, res + i - start + elif A[i] > R: diff, start = 0, i + else: res += diff + return res \ No newline at end of file diff --git a/solutions/python3/bak/797.py.bak b/solutions/python3/bak/797.py.bak new file mode 100644 index 0000000..02ab867 --- /dev/null +++ b/solutions/python3/bak/797.py.bak @@ -0,0 +1,10 @@ +class Solution: + def allPathsSourceTarget(self, graph, i = 0, q = [0]): + if i == 0: + global res + res = [] + if i == len(graph) - 1: + res.append(q) + for index in graph[i]: + self.allPathsSourceTarget(graph, index, q + [index]) + return res \ No newline at end of file diff --git a/solutions/python3/bak/798.py.bak b/solutions/python3/bak/798.py.bak new file mode 100644 index 0000000..d428d8e --- /dev/null +++ b/solutions/python3/bak/798.py.bak @@ -0,0 +1,7 @@ +class Solution: + def bestRotation(self, A): + N = len(A) + change = [1] * N + for i in range(N): change[(i - A[i] + 1) % N] -= 1 + for i in range(1, N): change[i] += change[i - 1] + return change.index(max(change)) \ No newline at end of file diff --git a/solutions/python3/bak/799.py.bak b/solutions/python3/bak/799.py.bak new file mode 100644 index 0000000..196762a --- /dev/null +++ b/solutions/python3/bak/799.py.bak @@ -0,0 +1,14 @@ +class Solution: + def champagneTower(self, poured, query_row, query_glass): + """ + :type poured: int + :type query_row: int + :type query_glass: int + :rtype: float + """ + glasses=[[poured if i==0 and j==0 else 0 for i in range(j+1)] for j in range(query_row+1)] + for i in range(1,len(glasses)): + for j in range(len(glasses[i])): + if j-1>=0 and glasses[i-1][j-1]>1: glasses[i][j]+=(glasses[i-1][j-1]-1)/2 + if j<=i-1 and glasses[i-1][j]>1: glasses[i][j]+=(glasses[i-1][j]-1)/2 + return glasses[query_row][query_glass] if glasses[query_row][query_glass]<=1 else 1 \ No newline at end of file diff --git a/solutions/python3/bak/8.py.bak b/solutions/python3/bak/8.py.bak new file mode 100644 index 0000000..daede67 --- /dev/null +++ b/solutions/python3/bak/8.py.bak @@ -0,0 +1,4 @@ +class Solution: + def myAtoi(self, str): + r = [int(c) for c in re.findall(r"^[-+]?\u005Cd+", str.lstrip())] + return (r and 2 ** 31 - 1 < r[0] and 2 ** 31 - 1) or (r and r[0] < -2 ** 31 and -2 ** 31) or (r and r[0]) or 0 \ No newline at end of file diff --git a/solutions/python3/bak/80.py.bak b/solutions/python3/bak/80.py.bak new file mode 100644 index 0000000..a2a8dfa --- /dev/null +++ b/solutions/python3/bak/80.py.bak @@ -0,0 +1,8 @@ +class Solution: + def removeDuplicates(self, nums: List[int]) -> int: + i = 2 + for j in range(2, len(nums)): + if nums[i - 2] != nums[j]: + nums[i] = nums[j] + i += 1 + return min(i, len(nums)) \ No newline at end of file diff --git a/solutions/python3/bak/800.py.bak b/solutions/python3/bak/800.py.bak new file mode 100644 index 0000000..af23cc7 --- /dev/null +++ b/solutions/python3/bak/800.py.bak @@ -0,0 +1,16 @@ +class Solution: + def similarRGB(self, color): + """ + :type color: str + :rtype: str + """ + import math + num1, num2, num3 = int(color[1:3],16), int(color[3:5],16), int(color[5:7],16) + letters = ["0","1","2","3","4","5","6","7","8","9","a","b","c","d","e","f"] + min1, min2, min3, res = math.inf, math.inf, math.inf, ["#","","",""] + for letter in letters: + min1, min2, min3 = min(min1,(num1-int(letter*2,16))**2), min(min2,(num2-int(letter*2,16))**2), min(min3,(num3-int(letter*2,16))**2) + if min1 == (num1-int(letter*2,16))**2: res[1] = letter*2 + if min2 == (num2-int(letter*2,16))**2: res[2] = letter*2 + if min3 == (num3-int(letter*2,16))**2: res[3] = letter*2 + return "".join(res) \ No newline at end of file diff --git a/solutions/python3/bak/802.py.bak b/solutions/python3/bak/802.py.bak new file mode 100644 index 0000000..c354881 --- /dev/null +++ b/solutions/python3/bak/802.py.bak @@ -0,0 +1,13 @@ +class Solution: + def eventualSafeNodes(self, graph): + def explore(i): + visited[i] = 0 + for v in graph[i]: + if visited[v] == 0 or (visited[v] == -1 and explore(v)): return True + visited[i] = 1 + res.append(i) + return False + visited, res = [-1] * len(graph), [] + for i in range(len(graph)): + if visited[i] == -1: explore(i) + return sorted(res) \ No newline at end of file diff --git a/solutions/python3/bak/803.py.bak b/solutions/python3/bak/803.py.bak new file mode 100644 index 0000000..26699dc --- /dev/null +++ b/solutions/python3/bak/803.py.bak @@ -0,0 +1,25 @@ +class Solution: + def hitBricks(self, grid, hits): + m, n, ret = len(grid), len(grid[0]), [0]*len(hits) + # Connect unconnected bricks and + def dfs(i, j): + if not (0 <= i len(A): return False + res = find(target - A[i], k - 1, i + 1) or find(target, k, i + 1) + if not res: not_found[(target, k)] = min(not_found.get((target, k), n), i) + return res + not_found = dict() + n, s = len(A), sum(A) + return any(find(s * i / n, i, 0) for i in range(1, n // 2 + 1) if s * i % n == 0) \ No newline at end of file diff --git a/solutions/python3/bak/806.py.bak b/solutions/python3/bak/806.py.bak new file mode 100644 index 0000000..4c5ffb5 --- /dev/null +++ b/solutions/python3/bak/806.py.bak @@ -0,0 +1,16 @@ +class Solution(object): + def numberOfLines(self, widths, S): + """ + :type widths: List[int] + :type S: str + :rtype: List[int] + """ + left=0 + lines=1 + for char in S: + if left+widths[ord(char)-ord("a")]<=100: + left+=widths[ord(char)-ord("a")] + else: + lines+=1 + left=widths[ord(char)-ord("a")] + return [lines, left] \ No newline at end of file diff --git a/solutions/python3/bak/807.py.bak b/solutions/python3/bak/807.py.bak new file mode 100644 index 0000000..7bfe27e --- /dev/null +++ b/solutions/python3/bak/807.py.bak @@ -0,0 +1,19 @@ +class Solution: + def maxIncreaseKeepingSkyline(self, grid): + """ + :type grid: List[List[int]] + :rtype: int + """ + n=len(grid) + m=len(grid[0]) + mx_i = [max(grid[i]) for i in range(n)] + mx_j=[-float("inf")]*m + for i in range(n): + for j in range(m): mx_j[j]=max(mx_j[j],grid[i][j]) + res=0 + for i in range(n): + for j in range(m): + prev=grid[i][j] + grid[i][j]=min(mx_i[i],mx_j[j]) + res+=grid[i][j]-prev + return res \ No newline at end of file diff --git a/solutions/python3/bak/808.py.bak b/solutions/python3/bak/808.py.bak new file mode 100644 index 0000000..9fe7262 --- /dev/null +++ b/solutions/python3/bak/808.py.bak @@ -0,0 +1,9 @@ +class Solution: + def soupServings(self, N): + visited = {} + def dfs(a, b): + if (a, b) in visited: return visited[(a, b)] + elif a <= 0 or b <= 0: return (a < b and 1) or (a == b and 0.5) or (b < a and 0) + visited[(a, b)] = 0.25 * (dfs(a - 100, b) + dfs(a - 75, b - 25) + dfs(a - 50, b -50) + dfs(a - 25, b - 75)) + return visited[(a, b)] + return N > 4800 and 1 or round(dfs(N, N), 5) \ No newline at end of file diff --git a/solutions/python3/bak/809.py.bak b/solutions/python3/bak/809.py.bak new file mode 100644 index 0000000..cc5d43e --- /dev/null +++ b/solutions/python3/bak/809.py.bak @@ -0,0 +1,16 @@ +class Solution: + def expressiveWords(self, S, words): + if not S: return 0 + guide, i, j, res = [], 0, 0, 0 + while i < len(S): + while j + 1 0 and nums[r] == nums[r - 1]: + r -= 1 + mid = (l + r) // 2 + if nums[mid] == target: + return True + elif sum((target < nums[l], nums[l] <= nums[mid], nums[mid] < target)) == 2: + l = mid + 1 + else: + r = mid - 1 + return False \ No newline at end of file diff --git a/solutions/python3/bak/810.py.bak b/solutions/python3/bak/810.py.bak new file mode 100644 index 0000000..2b94ec4 --- /dev/null +++ b/solutions/python3/bak/810.py.bak @@ -0,0 +1,5 @@ +class Solution: + def xorGame(self, nums): + xor = 0 + for i in nums: xor ^= i + return xor == 0 or len(nums) % 2 == 0 \ No newline at end of file diff --git a/solutions/python3/bak/811.py.bak b/solutions/python3/bak/811.py.bak new file mode 100644 index 0000000..fd658d2 --- /dev/null +++ b/solutions/python3/bak/811.py.bak @@ -0,0 +1,8 @@ +class Solution: + def subdomainVisits(self, cpdomains): + counter = collections.Counter() + for cpdomain in cpdomains: + count, *domains = cpdomain.replace(" ",".").split(".") + for i in range(len(domains)): + counter[".".join(domains[i:])] += int(count) + return [" ".join((str(v), k)) for k, v in counter.items()] \ No newline at end of file diff --git a/solutions/python3/bak/812.py.bak b/solutions/python3/bak/812.py.bak new file mode 100644 index 0000000..53b549e --- /dev/null +++ b/solutions/python3/bak/812.py.bak @@ -0,0 +1,11 @@ +class Solution: + def largestTriangleArea(self, p): + """ + :type points: List[List[int]] + :rtype: float + """ + from itertools import combinations as cb + def f(p1, p2, p3): + (x1, y1), (x2, y2), (x3, y3) = p1,p2,p3 + return 0.5 * abs(x2 * y3 + x1 * y2 + x3 * y1 - x3 * y2 - x2 * y1 - x1 * y3) + return max(f(a, b, c) for a, b, c in cb(p, 3)) \ No newline at end of file diff --git a/solutions/python3/bak/813.py.bak b/solutions/python3/bak/813.py.bak new file mode 100644 index 0000000..dd64d2a --- /dev/null +++ b/solutions/python3/bak/813.py.bak @@ -0,0 +1,14 @@ +class Solution: + def largestSumOfAverages(self, A, K): + memo = {} + def search(n, k): + if n < k: return 0 + if (n, k) not in memo: + if k == 1: memo[n, k] = sum(A[:n]) / float(n) + else: + cur = memo[n, k] = 0 + for i in range(n - 1, 0, -1): + cur += A[i] + memo[n, k] = max(memo[n, k], search(i, k - 1) + cur / float(n - i)) + return memo[n, k] + return search(len(A), K) \ No newline at end of file diff --git a/solutions/python3/bak/814.py.bak b/solutions/python3/bak/814.py.bak new file mode 100644 index 0000000..d99caac --- /dev/null +++ b/solutions/python3/bak/814.py.bak @@ -0,0 +1,21 @@ +# Definition for a binary tree node. +# class TreeNode: +# def __init__(self, x): +# self.val = x +# self.left = None +# self.right = None + +class Solution: + def pruneTree(self, root, parent = None): + """ + :type root: TreeNode + :rtype: TreeNode + """ + if not root: return + left = self.pruneTree(root.left, root) + right = self.pruneTree(root.right, root) + if not left and not right and root.val == 0: + if parent and parent.left == root: parent.left = None + elif parent and parent.right == root: parent.right = None + return + else: return root \ No newline at end of file diff --git a/solutions/python3/bak/815.py.bak b/solutions/python3/bak/815.py.bak new file mode 100644 index 0000000..aab9653 --- /dev/null +++ b/solutions/python3/bak/815.py.bak @@ -0,0 +1,20 @@ +class Solution: + def numBusesToDestination(self, routes, starterBus, targetBus): + path, travel, travelTaken, used = collections.defaultdict(set), [starterBus], 0, set() + for i, route in enumerate(routes): + for bus in route: + path[bus].add(i) + while travel: + new = [] + for bus in travel: + if bus == targetBus: + return travelTaken + for route in path[bus]: + if route not in used: + used.add(route) + for nextBus in routes[route]: + if nextBus != bus: + new.append(nextBus) + travelTaken += 1 + travel = new + return -1 \ No newline at end of file diff --git a/solutions/python3/bak/816.py.bak b/solutions/python3/bak/816.py.bak new file mode 100644 index 0000000..6b87b57 --- /dev/null +++ b/solutions/python3/bak/816.py.bak @@ -0,0 +1,27 @@ +class Solution: + def ambiguousCoordinates(self, S): + def properInt(s): + return len(s) > 1 and s[0] != "0" or len(s) == 1 + + def properFloat(s, i): + return s[-1] not in ".0" and properInt(s[:i]) + + s, res = S[1:-1], set() + for i in range(len(s)): + n1, n2 = s[:i + 1], s[i + 1:] + p1, p2 = properInt(n1), properInt(n2) + if p1 and p2: + res.add("({}, {})".format(n1, n2)) + for j in range(len(n1)): + for k in range(len(n2)): + n1f = n1[:j + 1] + "." + n1[j + 1:] + n2f = n2[:k + 1] + "." + n2[k + 1:] + p1f = properFloat(n1f, j + 1) + p2f = properFloat(n2f, k + 1) + if p1f and p2f: + res.add("({}, {})".format(n1f, n2f)) + if p1f and p2: + res.add("({}, {})".format(n1f, n2)) + if p1 and p2f: + res.add("({}, {})".format(n1, n2f)) + return list(res) \ No newline at end of file diff --git a/solutions/python3/bak/817.py.bak b/solutions/python3/bak/817.py.bak new file mode 100644 index 0000000..5249cfe --- /dev/null +++ b/solutions/python3/bak/817.py.bak @@ -0,0 +1,23 @@ +# Definition for singly-linked list. +# class ListNode: +# def __init__(self, x): +# self.val = x +# self.next = None + +class Solution: + def numComponents(self, head, G): + """ + :type head: ListNode + :type G: List[int] + :rtype: int + """ + num_connected = 0 + set_g = set(G) + while head: + if head.val not in set_g: + head = head.next + continue + while head and head.val in set_g: + head = head.next + num_connected += 1 + return num_connected \ No newline at end of file diff --git a/solutions/python3/bak/818.py.bak b/solutions/python3/bak/818.py.bak new file mode 100644 index 0000000..d3a65d9 --- /dev/null +++ b/solutions/python3/bak/818.py.bak @@ -0,0 +1,21 @@ +class Solution: + def racecar(self, target): + q, cnt, used = [(0, 1)], 0, {(0, 1)} + while q: + new = [] + for pos, speed in q: + if pos == target: + return cnt + elif pos > 20000 or -20000 > pos: + continue + if (pos + speed, speed * 2) not in used: + new.append((pos + speed, speed * 2)) + used.add((pos + speed, speed * 2)) + if speed > 0 and (pos, -1) not in used: + new.append((pos, -1)) + used.add((pos, -1)) + elif speed < 0 and (pos, 1) not in used: + new.append((pos, 1)) + used.add((pos, 1)) + q = new + cnt += 1 \ No newline at end of file diff --git a/solutions/python3/bak/819.py.bak b/solutions/python3/bak/819.py.bak new file mode 100644 index 0000000..3b85360 --- /dev/null +++ b/solutions/python3/bak/819.py.bak @@ -0,0 +1,19 @@ +class Solution: + def mostCommonWord(self, paragraph, banned): + """ + :type paragraph: str + :type banned: List[str] + :rtype: str + """ + paragraph = re.findall(r"\u005Cw+", paragraph) + dic = {} + mx = [0, 0] + for char in paragraph: + char = char.lower() + if char not in banned: + if char not in dic: dic[char] = 1 + else: dic[char] += 1 + mx[0] = max(mx[0], dic[char]) + if mx[0] == dic[char]: mx[1] = char + return mx[1] + \ No newline at end of file diff --git a/solutions/python3/bak/82.py.bak b/solutions/python3/bak/82.py.bak new file mode 100644 index 0000000..8d9b58b --- /dev/null +++ b/solutions/python3/bak/82.py.bak @@ -0,0 +1,22 @@ +# Definition for singly-linked list. +# class ListNode: +# def __init__(self, x): +# self.val = x +# self.next = None + +class Solution: + def deleteDuplicates(self, head): + dummy_left, dummy_left.next = ListNode(0), head + prev, prev_num = None, dummy_left + while head: + if prev and prev.val != head.val: + prev_num = prev + if prev and prev.val == head.val: + while head and head.next and head.next.val == head.val: + head = head.next + head = head.next + prev_num.next = head + prev = head + if head: + head = head.next + return dummy_left.next \ No newline at end of file diff --git a/solutions/python3/bak/820.py.bak b/solutions/python3/bak/820.py.bak new file mode 100644 index 0000000..73baedd --- /dev/null +++ b/solutions/python3/bak/820.py.bak @@ -0,0 +1,10 @@ +class Solution: + def minimumLengthEncoding(self, words): + """ + :type words: List[str] + :rtype: int + """ + s = set(words) + for word in words: + for i in range(1, len(word)): s.discard(word[i:]) + return sum(len(w) + 1 for w in s) \ No newline at end of file diff --git a/solutions/python3/bak/821.py.bak b/solutions/python3/bak/821.py.bak new file mode 100644 index 0000000..3f3e43a --- /dev/null +++ b/solutions/python3/bak/821.py.bak @@ -0,0 +1,14 @@ +class Solution: + def shortestToChar(self, S, C): + """ + :type S: str + :type C: str + :rtype: List[int] + """ + char1, char2, diff1, diff2, res = False, False, 0, 0, [None]* len(S) + for i in range(len(S)): + if char1: res[i], diff1 = min(res[i], diff1 + 1) if res[i] else diff1 + 1, diff1 + 1 + if S[i] == C: diff1, res[i], char1 = 0, 0, True + if char2: res[len(S) - 1 - i], diff2 = min(res[len(S) - 1 - i], diff2 + 1) if res[len(S) - 1 - i] else diff2 + 1, diff2 + 1 + if S[len(S) - 1 - i] == C: diff2, res[len(S) - 1 - i], char2 = 0, 0, True + return res \ No newline at end of file diff --git a/solutions/python3/bak/822.py.bak b/solutions/python3/bak/822.py.bak new file mode 100644 index 0000000..b487c91 --- /dev/null +++ b/solutions/python3/bak/822.py.bak @@ -0,0 +1,8 @@ +class Solution: + def flipgame(self, fronts, backs): + """ + :type fronts: List[int] + :type backs: List[int] + :rtype: int + """ + return min((set(fronts) | set(backs)) - set(fronts[i] for i in range(len(fronts)) if fronts[i] == backs[i]), default = 0) \ No newline at end of file diff --git a/solutions/python3/bak/823.py.bak b/solutions/python3/bak/823.py.bak new file mode 100644 index 0000000..1a620b1 --- /dev/null +++ b/solutions/python3/bak/823.py.bak @@ -0,0 +1,15 @@ +class Solution: + def numFactoredBinaryTrees(self, A): + """ + :type A: List[int] + :rtype: int + """ + A.sort() + nums, res, trees, factors = set(A), 0, {}, collections.defaultdict(set) + for i, num in enumerate(A): + for n in A[:i]: + if num % n == 0 and num // n in nums: factors[num].add(n) + for root in A: + trees[root] = 1 + for fac in factors[root]: trees[root] += trees[fac] * trees[root // fac] + return sum(trees.values()) % ((10 ** 9) + 7) \ No newline at end of file diff --git a/solutions/python3/bak/824.py.bak b/solutions/python3/bak/824.py.bak new file mode 100644 index 0000000..c395112 --- /dev/null +++ b/solutions/python3/bak/824.py.bak @@ -0,0 +1,4 @@ +class Solution: + def toGoatLatin(self, S): + s, vowels = S.split(), {"a", "e", "i", "o", "u"} + return " ".join([(s[i][0].lower() in vowels and s[i] or s[i][1:] + s[i][0]) + "m" + "a" * (i + 2) for i in range(len(s))]) \ No newline at end of file diff --git a/solutions/python3/bak/825.py.bak b/solutions/python3/bak/825.py.bak new file mode 100644 index 0000000..639ce1f --- /dev/null +++ b/solutions/python3/bak/825.py.bak @@ -0,0 +1,13 @@ +class Solution: + def numFriendRequests(self, ages): + """ + :type ages: List[int] + :rtype: int + """ + cntr, res = collections.Counter(ages), 0 + for A in cntr: + for B in cntr: + if B <= 0.5 * A + 7 or B > A: continue + if A == B: res += cntr[A] *(cntr[A] - 1) + else: res += cntr[A] * cntr[B] + return res \ No newline at end of file diff --git a/solutions/python3/bak/826.py.bak b/solutions/python3/bak/826.py.bak new file mode 100644 index 0000000..7b6f9ae --- /dev/null +++ b/solutions/python3/bak/826.py.bak @@ -0,0 +1,16 @@ +class Solution: + def maxProfitAssignment(self, difficulty, profit, worker): + """ + :type difficulty: List[int] + :type profit: List[int] + :type worker: List[int] + :rtype: int + """ + jobs = sorted([a, b] for a, b in zip(difficulty, profit)) + res = i = maxp = 0 + for ability in sorted(worker): + while i < len(jobs) and ability >= jobs[i][0]: + maxp = max(jobs[i][1], maxp) + i += 1 + res += maxp + return res \ No newline at end of file diff --git a/solutions/python3/bak/827.py.bak b/solutions/python3/bak/827.py.bak new file mode 100644 index 0000000..4514529 --- /dev/null +++ b/solutions/python3/bak/827.py.bak @@ -0,0 +1,23 @@ +class Solution: + def largestIsland(self, grid): + def explore(i, j): + dic[(i, j)], count[curr] = curr, count[curr] + 1 + if i > 0 and grid[i - 1][j] == 1 and (i - 1, j) not in dic: explore(i - 1, j) + if j > 0 and grid[i][j - 1] == 1 and (i, j - 1) not in dic: explore(i, j - 1) + if i + 1 < len(grid) and grid[i + 1][j] ==1 and (i + 1, j) not in dic: explore(i + 1, j) + if j + 1 < len(grid) and grid[i][j + 1] == 1 and (i, j + 1) not in dic: explore(i, j + 1) + def neighbours(i, j, adj): + if i > 0 and grid[i - 1][j] == 1 and dic[(i - 1, j)] not in adj: adj.add(dic[(i - 1, j)]) + if j > 0 and grid[i][j - 1] == 1 and dic[(i, j - 1)] not in adj: adj.add(dic[(i, j - 1)]) + if i + 1 < len(grid) and grid[i + 1][j] ==1 and dic[(i + 1, j)] not in adj: adj.add(dic[(i + 1, j)]) + if j + 1 < len(grid) and grid[i][j + 1] == 1 and dic[(i, j + 1)] not in adj: adj.add(dic[(i, j + 1)]) + return adj + curr, dic, count, res = 0, {}, collections.defaultdict(int), 0 + for i in range(len(grid)): + for j in range(len(grid)): + if grid[i][j] == 1 and (i, j) not in dic: curr += 1; explore(i, j) + for i in range(len(grid)): + for j in range(len(grid)): + if grid[i][j] == 1: res = max(res, count[dic[(i, j)]]) + else: res = max(res, sum(count[r] for r in neighbours(i, j, set())) + 1) + return res \ No newline at end of file diff --git a/solutions/python3/bak/828.py.bak b/solutions/python3/bak/828.py.bak new file mode 100644 index 0000000..d6a1898 --- /dev/null +++ b/solutions/python3/bak/828.py.bak @@ -0,0 +1,12 @@ +class Solution: + def uniqueLetterString(self, S): + index = {c: [-1, -1] for c in string.ascii_uppercase} + res = 0 + for i, c in enumerate(S): + k, j = index[c] + res += (i - j) * (j - k) + index[c] = [j, i] + for c in index: + k, j = index[c] + res += (len(S) - j) * (j - k) + return res % (10**9 + 7) \ No newline at end of file diff --git a/solutions/python3/bak/829.py.bak b/solutions/python3/bak/829.py.bak new file mode 100644 index 0000000..c7ee752 --- /dev/null +++ b/solutions/python3/bak/829.py.bak @@ -0,0 +1,10 @@ +class Solution: + def consecutiveNumbersSum(self, N): + cnt=0 + for d in range(1, N+1): + diff=d*(d-1)//2 + nd = N - diff + if nd<=0: break + if nd%d==0: + cnt+=1 + return cnt \ No newline at end of file diff --git a/solutions/python3/bak/83.py.bak b/solutions/python3/bak/83.py.bak new file mode 100644 index 0000000..5fcf85a --- /dev/null +++ b/solutions/python3/bak/83.py.bak @@ -0,0 +1,8 @@ +class Solution: + def deleteDuplicates(self, head): + cur = root = head + while head: + if head.val != cur.val: + cur.next = cur = head + head = cur.next = head.next + return root \ No newline at end of file diff --git a/solutions/python3/bak/830.py.bak b/solutions/python3/bak/830.py.bak new file mode 100644 index 0000000..1251548 --- /dev/null +++ b/solutions/python3/bak/830.py.bak @@ -0,0 +1,9 @@ +class Solution: + def largeGroupPositions(self, S): + res = [] + l = r = 0 + for i in range(1, len(S)): + if S[i] == S[i - 1]: r += 1 + if r - l >= 2 and (S[i] != S[i - 1] or i == len(S) - 1): res.append([l, r]) + if S[i] != S[i - 1]: l = r = i + return res \ No newline at end of file diff --git a/solutions/python3/bak/831.py.bak b/solutions/python3/bak/831.py.bak new file mode 100644 index 0000000..ecd184d --- /dev/null +++ b/solutions/python3/bak/831.py.bak @@ -0,0 +1,10 @@ +class Solution: + def maskPII(self, S): + if "@" in S: + s = S.lower().split("@") + return s[0][0] + "*" * 5 + s[0][-1] + "@" + s[1] + else: + nums, tmp = {"0","1","2","3","4","5","6","7","8","9"}, "" + for c in S: + if c in nums: tmp += c + return "+" + "*" * (len(tmp) - 10) + "-***-***-" + tmp[-4:] if len(tmp) > 10 else "***-***-" + tmp[-4:] \ No newline at end of file diff --git a/solutions/python3/bak/832.py.bak b/solutions/python3/bak/832.py.bak new file mode 100644 index 0000000..e978fe8 --- /dev/null +++ b/solutions/python3/bak/832.py.bak @@ -0,0 +1,3 @@ +class Solution(object): + def flipAndInvertImage(self, A): + return [[1 - x for x in A[i][::-1]] for i in range(len(A))] \ No newline at end of file diff --git a/solutions/python3/bak/833.py.bak b/solutions/python3/bak/833.py.bak new file mode 100644 index 0000000..aedd85f --- /dev/null +++ b/solutions/python3/bak/833.py.bak @@ -0,0 +1,9 @@ +class Solution: + def findReplaceString(self, s, indexes, sources, targets): + res, dic, j = "", {}, 0 + for i in range(len(sources)): + if s.find(sources[i], indexes[i]) == indexes[i]: dic[indexes[i]] = (sources[i], targets[i]) + while j < len(s): + res += j in dic and dic[j][1] or s[j] + j += j in dic and len(dic[j][0]) or 1 + return res \ No newline at end of file diff --git a/solutions/python3/bak/834.py.bak b/solutions/python3/bak/834.py.bak new file mode 100644 index 0000000..f40a752 --- /dev/null +++ b/solutions/python3/bak/834.py.bak @@ -0,0 +1,24 @@ +class Solution: + def sumOfDistancesInTree(self, N, edges): + tree = collections.defaultdict(set) + res = [0] * N + count = [1] * N + for i, j in edges: + tree[i].add(j) + tree[j].add(i) + + def dfs(root, pre): + for i in tree[root]: + if i != pre: + dfs(i, root) + count[root] += count[i] + res[root] += res[i] + count[i] + + def dfs2(root, pre): + for i in tree[root]: + if i != pre: + res[i] = res[root] - count[i] + N - count[i] + dfs2(i, root) + dfs(0, -1) + dfs2(0, -1) + return res \ No newline at end of file diff --git a/solutions/python3/bak/835.py.bak b/solutions/python3/bak/835.py.bak new file mode 100644 index 0000000..22f6451 --- /dev/null +++ b/solutions/python3/bak/835.py.bak @@ -0,0 +1,4 @@ +class Solution: + def largestOverlap(self, A, B): + n, shift, rn = len(A), range(-1 * len(A) + 1, len(A)), range(len(A)) + return max(sum(A[i][j] and B[i + v][j + h] for i in rn for j in rn if 0 <= i + v < n > j + h >= 0) for h in shift for v in shift) \ No newline at end of file diff --git a/solutions/python3/bak/836.py.bak b/solutions/python3/bak/836.py.bak new file mode 100644 index 0000000..609f871 --- /dev/null +++ b/solutions/python3/bak/836.py.bak @@ -0,0 +1,5 @@ +class Solution: + def isRectangleOverlap(self, rec1, rec2): + x = (rec1[2] - rec1[0] + rec2[2] - rec2[0]) > (max(rec1[2], rec2[2]) - min(rec1[0], rec2[0])) + y = (rec1[3] - rec1[1] + rec2[3] - rec2[1]) > (max(rec1[3], rec2[3]) - min(rec1[1], rec2[1])) + return x and y \ No newline at end of file diff --git a/solutions/python3/bak/837.py.bak b/solutions/python3/bak/837.py.bak new file mode 100644 index 0000000..6e21e14 --- /dev/null +++ b/solutions/python3/bak/837.py.bak @@ -0,0 +1,11 @@ +class Solution: + def new21Game(self, N, K, W): + if K == 0 or N >= K + W: return 1 + dp = [1.0] + [0.0] * N + Wsum, res = 1.0, 0.0 + for i in range(1, N + 1): + dp[i] += Wsum / W + if i < K: Wsum += dp[i] + else: res += dp[i] + if i - W >= 0: Wsum -= dp[i - W] + return res \ No newline at end of file diff --git a/solutions/python3/bak/838.py.bak b/solutions/python3/bak/838.py.bak new file mode 100644 index 0000000..a1984a5 --- /dev/null +++ b/solutions/python3/bak/838.py.bak @@ -0,0 +1,21 @@ +class Solution: + def pushDominoes(self, dominoes): + res, l, r , pre_l, pre_r = "", {}, {}, None, None, + for i, s in enumerate(dominoes): + if s == "." and pre_r != None: r[i] = i - pre_r + elif s == "R": pre_r = i + elif s == "L": pre_r = None + for i in range(len(dominoes) - 1, -1, -1): + if dominoes[i] == "." and pre_l != None: l[i] = pre_l - i + elif dominoes[i] == "L": pre_l = i + elif dominoes[i] == "R": pre_l = None + for i, s in enumerate(dominoes): + if s == "L" or s == "R": res += s + elif i in l and i in r: + if l[i] < r[i]: res += "L" + elif r[i] < l[i]: res += "R" + else: res += s + elif i in l: res += "L" + elif i in r: res += "R" + else: res += s + return res \ No newline at end of file diff --git a/solutions/python3/bak/839.py.bak b/solutions/python3/bak/839.py.bak new file mode 100644 index 0000000..dad3efc --- /dev/null +++ b/solutions/python3/bak/839.py.bak @@ -0,0 +1,35 @@ +class Solution: + def numSimilarGroups(self, A): + def explore(s): + visited.add(s) + for v in edges[s]: + if v not in visited: explore(v) + res, edges, visited = 0, {}, set() + if len(A) >= 2 * len(A[0]): + strs = set(A) + for s in A: + if s not in edges: edges[s] = set() + for i in range(len(s) - 1): + for j in range(i + 1, len(s)): + new = s[:i] + s[j] + s[i + 1:j] + s[i] + s[j + 1:] + if new in strs: + edges[s].add(new) + if new in edges: edges[new].add(s) + else: edges[new] = {s} + else: + for s in A: + if s not in edges: edges[s] = set() + for t in A: + if s != t: + same = 0 + for i, c in enumerate(t): + if c == s[i]: same += 1 + if same == len(s) - 2: + edges[s].add(t) + if t in edges: edges[t].add(s) + else: edges[t] = {s} + for s in A: + if s not in visited: + res += 1 + explore(s) + return res \ No newline at end of file diff --git a/solutions/python3/bak/84.py.bak b/solutions/python3/bak/84.py.bak new file mode 100644 index 0000000..0118e91 --- /dev/null +++ b/solutions/python3/bak/84.py.bak @@ -0,0 +1,13 @@ +class Solution: + def largestRectangleArea(self, heights): + heights.append(0) + stack = [-1] + ans = 0 + for i in range(len(heights)): + while heights[i] < heights[stack[-1]]: + h = heights[stack.pop()] + w = i - stack[-1] - 1 + ans = max(ans, h * w) + stack.append(i) + heights.pop() + return ans \ No newline at end of file diff --git a/solutions/python3/bak/840.py.bak b/solutions/python3/bak/840.py.bak new file mode 100644 index 0000000..8ccdbfd --- /dev/null +++ b/solutions/python3/bak/840.py.bak @@ -0,0 +1,13 @@ +class Solution: + def numMagicSquaresInside(self, grid): + """ + :type grid: List[List[int]] + :rtype: int + """ + res = 0 + for i in range(len(grid)-2): + for j in range(len(grid)-2): + if sum(grid[i][j: j + 3]) == sum(grid[i + 1][j : j +3]) == sum(grid[i + 2][j:j + 3]) == sum(grid[k][j] for k in range(i, i + 3)) == sum(grid[k][j + 1] for k in range(i, i + 3)) == sum(grid[k][j + 2] for k in range(i, i + 3)) == (grid[i][j] + grid[i + 1][j + 1] + grid[i + 2][j + 2]) == (grid[i+2][j]+ grid[i + 1][j + 1] + grid[i][j + 2]): + if set(grid[i][j: j + 3] + grid[i + 1][j: j +3] + grid[i + 2][j:j + 3]) == {1,2,3,4,5,6,7,8,9}: res += 1 + return res + \ No newline at end of file diff --git a/solutions/python3/bak/841.py.bak b/solutions/python3/bak/841.py.bak new file mode 100644 index 0000000..d843b63 --- /dev/null +++ b/solutions/python3/bak/841.py.bak @@ -0,0 +1,9 @@ +class Solution: + def canVisitAllRooms(self, rooms): + pool, stack = set(range(len(rooms))), [0] + while stack: + pool.discard(stack[-1]) + for nex in rooms[stack.pop()]: + if nex in pool: + stack.append(nex) + return not pool \ No newline at end of file diff --git a/solutions/python3/bak/842.py.bak b/solutions/python3/bak/842.py.bak new file mode 100644 index 0000000..953672c --- /dev/null +++ b/solutions/python3/bak/842.py.bak @@ -0,0 +1,24 @@ +class Solution: + def splitIntoFibonacci(self, S): + def getStarter(): + arr = [] + for i in range(1, len(S) - 1): + for j in range(i + 1, len(S)): + s1, s2 = S[:i], S[i:j] + if (s1[0] == "0" and len(s1) > 1) or (s2[0] == "0" and len(s2) > 1): + continue + arr.append((int(s1), int(s2), j)) + return arr + def dfs(arr, i): + if i == len(S): + return arr + sm = arr[-2] + arr[-1] + l = len(str(sm)) + new = int(S[i:i + l]) + return new == sm and 0 <= sm <= mx and dfs(arr + [new], i + l) + q, mx = getStarter(), 2 ** 31 - 1 + for p1, p2, i in q: + seq = dfs([p1, p2], i) + if seq: + return seq + return [] \ No newline at end of file diff --git a/solutions/python3/bak/843.py.bak b/solutions/python3/bak/843.py.bak new file mode 100644 index 0000000..94d7a17 --- /dev/null +++ b/solutions/python3/bak/843.py.bak @@ -0,0 +1,19 @@ +# """ +# This is Master's API interface. +# You should not implement it, or speculate about its implementation +# """ +#class Master: +# def guess(self, word): +# """ +# :type word: str +# :rtype int +# """ + +class Solution: + def findSecretWord(self, wordlist, master): + n = 0 + while n < 6: + count = collections.Counter(w1 for w1, w2 in itertools.permutations(wordlist, 2) if sum(i == j for i, j in zip(w1, w2)) == 0) + guess = min(wordlist, key = lambda w: count[w]) + n = master.guess(guess) + wordlist = [w for w in wordlist if sum(i == j for i, j in zip(w, guess)) == n] \ No newline at end of file diff --git a/solutions/python3/bak/844.py.bak b/solutions/python3/bak/844.py.bak new file mode 100644 index 0000000..2996c66 --- /dev/null +++ b/solutions/python3/bak/844.py.bak @@ -0,0 +1,12 @@ +class Solution: + def backspaceCompare(self, S, T): + def construct(s): + new_s = [] + for c in s: + if c == "#" and len(new_s) > 0: + new_s.pop() + elif c != "#": + new_s.append(c) + return new_s + s, t = construct(S), construct(T) + return s == t \ No newline at end of file diff --git a/solutions/python3/bak/845.py.bak b/solutions/python3/bak/845.py.bak new file mode 100644 index 0000000..ba09f2f --- /dev/null +++ b/solutions/python3/bak/845.py.bak @@ -0,0 +1,9 @@ +class Solution: + def longestMountain(self, A, res = 0): + for i in range(1, len(A) - 1): + if A[i + 1] < A[i] > A[i - 1]: + l = r = i + while l and A[l] > A[l - 1]: l -= 1 + while r + 1 < len(A) and A[r] > A[r + 1]: r += 1 + if r - l + 1 > res: res = r - l + 1 + return res \ No newline at end of file diff --git a/solutions/python3/bak/846.py.bak b/solutions/python3/bak/846.py.bak new file mode 100644 index 0000000..9b58f8c --- /dev/null +++ b/solutions/python3/bak/846.py.bak @@ -0,0 +1,11 @@ +class Solution: + def isNStraightHand(self, hand, W): + hand.sort() + while hand: + try: + base = hand[0] + for i in range(W): + hand.remove(base+i) + except: + return False + return True \ No newline at end of file diff --git a/solutions/python3/bak/847.py.bak b/solutions/python3/bak/847.py.bak new file mode 100644 index 0000000..a5b0786 --- /dev/null +++ b/solutions/python3/bak/847.py.bak @@ -0,0 +1,10 @@ +class Solution: + def shortestPathLength(self, graph): + memo, final, q = set(), (1 << len(graph)) - 1, collections.deque([(i, 0, 1 << i) for i in range(len(graph))]) + while q: + node, steps, state = q.popleft() + if state == final: return steps + for v in graph[node]: + if (state | 1 << v, v) not in memo: + q.append((v, steps + 1, state | 1 << v)) + memo.add((state | 1 << v, v)) \ No newline at end of file diff --git a/solutions/python3/bak/848.py.bak b/solutions/python3/bak/848.py.bak new file mode 100644 index 0000000..cd2c036 --- /dev/null +++ b/solutions/python3/bak/848.py.bak @@ -0,0 +1,7 @@ +class Solution: + def shiftingLetters(self, S, shifts): + sm, res = sum(shift % 26 for shift in shifts) % 26, "" + for i, s in enumerate(shifts): + move, sm = ord(S[i]) + sm % 26, sm - s + res += chr(move > 122 and move - 26 or move) + return res \ No newline at end of file diff --git a/solutions/python3/bak/849.py.bak b/solutions/python3/bak/849.py.bak new file mode 100644 index 0000000..6edc548 --- /dev/null +++ b/solutions/python3/bak/849.py.bak @@ -0,0 +1,11 @@ +class Solution: + def maxDistToClosest(self, seats): + d = {} + res = l = left = r = right = 0 + for i, s in enumerate(seats): + if not s and left: d[i] = l = l + 1 + elif s: l, left = 0, 1 + for i in range(len(seats) - 1, -1, -1): + if not seats[i] and right and (i not in d or d[i] > r): d[i] = r = r + 1 + elif seats[i]: r, right = 0, 1 + return max(d.values()) \ No newline at end of file diff --git a/solutions/python3/bak/85.py.bak b/solutions/python3/bak/85.py.bak new file mode 100644 index 0000000..2fa80a8 --- /dev/null +++ b/solutions/python3/bak/85.py.bak @@ -0,0 +1,20 @@ +class Solution: + def maximalRectangle(self, matrix): + res, m, n = 0, len(matrix), len(matrix and matrix[0]) + for i in range(m): + for j in range(n): + if matrix[i][j] != "0": + if j > 0 and matrix[i][j - 1] != "0": + matrix[i][j] = matrix[i][j - 1] + 1 + else: + matrix[i][j] = 1 + mn, sm, k = matrix[i][j], 0, i + 1 + while k > 0 and matrix[k - 1][j] != "0": + if matrix[k - 1][j] < mn: + sm, mn = (i - k + 2) * matrix[k - 1][j], matrix[k - 1][j] + else: + sm += mn + if sm > res: + res = sm + k -= 1 + return res \ No newline at end of file diff --git a/solutions/python3/bak/850.py.bak b/solutions/python3/bak/850.py.bak new file mode 100644 index 0000000..254a29c --- /dev/null +++ b/solutions/python3/bak/850.py.bak @@ -0,0 +1,18 @@ +class Solution: + def rectangleArea(self, rectangles): + xs = sorted(set([x for x1, y1, x2, y2 in rectangles for x in [x1, x2]] + [0])) + x_i = {v: i for i, v in enumerate(xs)} + count = [0] * len(x_i) + L = [] + for x1, y1, x2, y2 in rectangles: + L.append([y1, x1, x2, 1]) + L.append([y2, x1, x2, -1]) + L.sort() + cur_y = cur_x_sum = area = 0 + for y, x1, x2, sig in L: + area += (y - cur_y) * cur_x_sum + cur_y = y + for i in range(x_i[x1], x_i[x2]): + count[i] += sig + cur_x_sum = sum(x2 - x1 if c else 0 for x1, x2, c in zip(xs, xs[1:], count)) + return area % (10 ** 9 + 7) \ No newline at end of file diff --git a/solutions/python3/bak/851.py.bak b/solutions/python3/bak/851.py.bak new file mode 100644 index 0000000..d5ce585 --- /dev/null +++ b/solutions/python3/bak/851.py.bak @@ -0,0 +1,14 @@ +class Solution: + def loudAndRich(self, richer, quiet): + edges, memo, res = collections.defaultdict(list), {}, [i for i in range(len(quiet))] + for r, p in richer: edges[p].append(r) + def explore(i): + if i in memo: return memo[i] + cur_min = i + for v in edges[i]: + cur = explore(v) + if quiet[cur] < quiet[cur_min]: cur_min = cur + res[i] = memo[i] = cur_min + return cur_min + for i in range(len(quiet)): explore(i) + return res \ No newline at end of file diff --git a/solutions/python3/bak/852.py.bak b/solutions/python3/bak/852.py.bak new file mode 100644 index 0000000..31a939f --- /dev/null +++ b/solutions/python3/bak/852.py.bak @@ -0,0 +1,8 @@ +class Solution: + def peakIndexInMountainArray(self, A): + """ + :type A: List[int] + :rtype: int + """ + mx = max(A) + return A.index(mx) \ No newline at end of file diff --git a/solutions/python3/bak/853.py.bak b/solutions/python3/bak/853.py.bak new file mode 100644 index 0000000..02c28f8 --- /dev/null +++ b/solutions/python3/bak/853.py.bak @@ -0,0 +1,10 @@ +class Solution: + def carFleet(self, target, position, speed): + res, s = 0, {position[i]: speed[i] for i in range(len(position))} + position.sort() + while position: + cur = position.pop() + res += 1 + while position and (s[position[-1]] - s[cur]) * (target - cur) / s[cur] >= cur - position[-1]: + position.pop() + return res \ No newline at end of file diff --git a/solutions/python3/bak/854.py.bak b/solutions/python3/bak/854.py.bak new file mode 100644 index 0000000..8ec2b23 --- /dev/null +++ b/solutions/python3/bak/854.py.bak @@ -0,0 +1,17 @@ +class Solution: + def kSimilarity(self, A, B): + b, n, k, stack = [c for c in B], len(A), float("inf"), [(0, 0, [c for c in A])] + while stack: + i, cnt, s = stack.pop() + while i < n and s[i] == b[i]: + i += 1 + if i == n: + if cnt < k: + k = cnt + else: + for j in range(i + 1, n): + if s[j] == b[i] and s[j] != b[j]: + ls = s[:] + ls[i], ls[j] = ls[j], ls[i] + stack.append((i + 1, cnt + 1, ls)) + return k \ No newline at end of file diff --git a/solutions/python3/bak/855.py.bak b/solutions/python3/bak/855.py.bak new file mode 100644 index 0000000..9e6844f --- /dev/null +++ b/solutions/python3/bak/855.py.bak @@ -0,0 +1,27 @@ +class ExamRoom: + + def __init__(self, N): + self.seated, self.n = [], N - 1 + + + def seat(self): + if not self.seated: + self.seated += 0, + return 0 + mx = ind = 0 + for i in range(1, len(self.seated)): + l, r = self.seated[i - 1], self.seated[i] + if (r - l) // 2 > mx: + mx = (r - l) // 2 + ind = l + mx + if self.seated[-1] != self.n and self.n - self.seated[-1] > mx: + mx, ind = self.n - self.seated[-1], self.n + if self.seated[0] >= mx: + mx, ind = self.seated[0], 0 + self.seated.append(ind) + self.seated.sort() + return ind + + + def leave(self, p): + self.seated.remove(p) diff --git a/solutions/python3/bak/856.py.bak b/solutions/python3/bak/856.py.bak new file mode 100644 index 0000000..2943552 --- /dev/null +++ b/solutions/python3/bak/856.py.bak @@ -0,0 +1,13 @@ +class Solution: + def scoreOfParentheses(self, S): + stack, res = [], 0 + for c in S: + if c == "(": + stack.append(0) + else: + add = 2 * stack.pop() or 1 + if stack: + stack[-1] += add + else: + res += add + return res \ No newline at end of file diff --git a/solutions/python3/bak/857.py.bak b/solutions/python3/bak/857.py.bak new file mode 100644 index 0000000..0b8cd2d --- /dev/null +++ b/solutions/python3/bak/857.py.bak @@ -0,0 +1,11 @@ +class Solution: + def mincostToHireWorkers(self, quality, wage, K): + workers, res, heap, sumq = sorted((w / q, q, w) for q, w in zip(quality, wage)), float("inf"), [], 0 + for ratio, q, w in workers: + heapq.heappush(heap, -q) + sumq += q + if len(heap) > K: + sumq += heapq.heappop(heap) + if len(heap) == K: + res = min(res, ratio * sumq) + return res \ No newline at end of file diff --git a/solutions/python3/bak/858.py.bak b/solutions/python3/bak/858.py.bak new file mode 100644 index 0000000..e25d8e7 --- /dev/null +++ b/solutions/python3/bak/858.py.bak @@ -0,0 +1,16 @@ +class Solution: + def mirrorReflection(self, p, q): + side, up, h = 2, 1, 0 + while True: + h += q * up + side = (side + 1) % 2 + if side == 0: + side += 2 + if h < 0: + h *= -1 + up *= -1 + elif h > p: + h = p - (h - p) + up *= -1 + if h % p == 0: + return h and side or 0 \ No newline at end of file diff --git a/solutions/python3/bak/859.py.bak b/solutions/python3/bak/859.py.bak new file mode 100644 index 0000000..98e3d96 --- /dev/null +++ b/solutions/python3/bak/859.py.bak @@ -0,0 +1,6 @@ +class Solution: + def buddyStrings(self, A, B): + if len(A) != len(B): + return False + dif, dup = [[s1, B[i]] for i, s1 in enumerate(A) if s1 != B[i]], len(A) != len(set(A)) + return len(dif) == 2 and dif[0] == dif[1][::-1] or (not dif and dup) \ No newline at end of file diff --git a/solutions/python3/bak/86.py.bak b/solutions/python3/bak/86.py.bak new file mode 100644 index 0000000..5595649 --- /dev/null +++ b/solutions/python3/bak/86.py.bak @@ -0,0 +1,12 @@ +class Solution: + def partition(self, head, x): + lessHead = less = ListNode(-1) + greatHead = great = ListNode(-1) + while head: + if head.val < x: + less.next = less = head + else: + great.next = great = head + head = head.next + less.next, great.next = greatHead.next, None + return lessHead.next \ No newline at end of file diff --git a/solutions/python3/bak/860.py.bak b/solutions/python3/bak/860.py.bak new file mode 100644 index 0000000..4b67e5b --- /dev/null +++ b/solutions/python3/bak/860.py.bak @@ -0,0 +1,17 @@ +class Solution: + def lemonadeChange(self, bills): + five = ten = 0 + for num in bills: + if num == 5: + five += 1 + elif num == 10 and five: + ten += 1 + five -= 1 + elif num == 20 and five and ten: + five -= 1 + ten -= 1 + elif num == 20 and five >= 3: + five -= 3 + else: + return False + return True \ No newline at end of file diff --git a/solutions/python3/bak/861.py.bak b/solutions/python3/bak/861.py.bak new file mode 100644 index 0000000..8c407a1 --- /dev/null +++ b/solutions/python3/bak/861.py.bak @@ -0,0 +1,10 @@ +class Solution: + def matrixScore(self, A): + for i, row in enumerate(A): + if not row[0]: + A[i] = [1 - num for num in row] + m, n, sm = len(A), len(A and A[0]), 0 + for c in range(n): + cnt = sum(A[r][c] for r in range(m)) + sm += max(cnt, m - cnt) * 2 ** (n - c - 1) + return sm \ No newline at end of file diff --git a/solutions/python3/bak/862.py.bak b/solutions/python3/bak/862.py.bak new file mode 100644 index 0000000..761c9c6 --- /dev/null +++ b/solutions/python3/bak/862.py.bak @@ -0,0 +1,13 @@ +class Solution: + def shortestSubarray(self, A, K): + heap, l, sm = [], float("inf"), 0 + heapq.heappush(heap, (0, -1)) + for i, num in enumerate(A): + sm += num + dif = sm - K + while heap and (heap[0][0] <= dif or i - heap[0][1] >= l): + preSum, preIndex = heapq.heappop(heap) + if i - preIndex < l: + l = i - preIndex + heapq.heappush(heap, (sm, i)) + return l < float("inf") and l or -1 \ No newline at end of file diff --git a/solutions/python3/bak/863.py.bak b/solutions/python3/bak/863.py.bak new file mode 100644 index 0000000..d406283 --- /dev/null +++ b/solutions/python3/bak/863.py.bak @@ -0,0 +1,24 @@ +class Solution: + def distanceK(self, root, target, K): + adj, res, visited = collections.defaultdict(list), [], collections.defaultdict(int) + def dfs(node): + if node.left: + adj[node].append(node.left) + adj[node.left].append(node) + dfs(node.left) + if node.right: + adj[node].append(node.right) + adj[node.right].append(node) + dfs(node.right) + dfs(root) + def dfs2(node, d): + if d < K: + visited[node] = 1 + for v in adj[node]: + if not visited[v]: + dfs2(v, d + 1) + visited[node] = 0 + else: + res.append(node.val) + dfs2(target, 0) + return res \ No newline at end of file diff --git a/solutions/python3/bak/864.py.bak b/solutions/python3/bak/864.py.bak new file mode 100644 index 0000000..b7bcd6f --- /dev/null +++ b/solutions/python3/bak/864.py.bak @@ -0,0 +1,21 @@ +class Solution: + def shortestPathAllKeys(self, grid): + final, m, n, si, sj = 0, len(grid), len(grid[0]), 0, 0 + for i in range(m): + for j in range(n): + if grid[i][j] in "abcdef": + final |= 1 << ord(grid[i][j]) - ord("a") + elif grid[i][j] == "@": + si, sj = i, j + q, memo = [(0, si, sj, 0)], set() + while q: + moves, i, j, state = heapq.heappop(q) + if state == final: return moves + for x, y in ((i - 1, j), (i + 1, j), (i, j - 1), (i, j + 1)): + if 0 <= x < m and 0 <= y < n and grid[x][y] != "#": + if grid[x][y].isupper() and not state & 1 << (ord(grid[x][y].lower()) - ord("a")): continue + newState = ord(grid[x][y]) >= ord("a") and state | 1 << (ord(grid[x][y]) - ord("a")) or state + if (newState, x, y) not in memo: + memo.add((newState, x, y)) + heapq.heappush(q, (moves + 1, x, y, newState)) + return -1 \ No newline at end of file diff --git a/solutions/python3/bak/865.py.bak b/solutions/python3/bak/865.py.bak new file mode 100644 index 0000000..3d5e86a --- /dev/null +++ b/solutions/python3/bak/865.py.bak @@ -0,0 +1,33 @@ +# Definition for a binary tree node. +# class TreeNode: +# def __init__(self, x): +# self.val = x +# self.left = None +# self.right = None + +class Solution: + def subtreeWithAllDeepest(self, root: TreeNode) -> TreeNode: + self.l = 0 + self.nodes = set() + self.res = 0 + def dfs(node, l): + if node: + if l > self.l: + self.nodes = {node.val} + self.l = l + elif l == self.l: + self.nodes.add(node.val) + dfs(node.left, l + 1) + dfs(node.right, l + 1) + def dfs2(node): + if not node: return set() + l = dfs2(node.left) + r = dfs2(node.right) + total = l | r | {node.val} + if total & self.nodes == self.nodes: + self.res = node + return set() + return total + dfs(root, 0) + dfs2(root) + return self.res \ No newline at end of file diff --git a/solutions/python3/bak/866.py.bak b/solutions/python3/bak/866.py.bak new file mode 100644 index 0000000..1c23aec --- /dev/null +++ b/solutions/python3/bak/866.py.bak @@ -0,0 +1,11 @@ +class Solution: + def primePalindrome(self, N): + def isPrime(x): + if x < 2 or x % 2 == 0: return x == 2 + for i in range(3, int(x**0.5) + 1, 2): + if x % i == 0: return False + return True + if 8 <= N <= 11: return 11 + for x in range(10 ** (len(str(N)) // 2), 10**5): + y = int(str(x) + str(x)[-2::-1]) + if y >= N and isPrime(y): return y \ No newline at end of file diff --git a/solutions/python3/bak/867.py.bak b/solutions/python3/bak/867.py.bak new file mode 100644 index 0000000..421b293 --- /dev/null +++ b/solutions/python3/bak/867.py.bak @@ -0,0 +1,3 @@ +class Solution: + def transpose(self, A): + return [[A[i][j] for i in range(len(A))] for j in range(len(A[0]))] \ No newline at end of file diff --git a/solutions/python3/bak/868.py.bak b/solutions/python3/bak/868.py.bak new file mode 100644 index 0000000..7dfd611 --- /dev/null +++ b/solutions/python3/bak/868.py.bak @@ -0,0 +1,8 @@ +class Solution: + def binaryGap(self, N): + pre = dist = 0 + for i, c in enumerate(bin(N)[2:]): + if c == "1": + dist = max(dist, i - pre) + pre = i + return dist \ No newline at end of file diff --git a/solutions/python3/bak/869.py.bak b/solutions/python3/bak/869.py.bak new file mode 100644 index 0000000..675dfcb --- /dev/null +++ b/solutions/python3/bak/869.py.bak @@ -0,0 +1,4 @@ +class Solution: + def reorderedPowerOf2(self, N): + cnt = collections.Counter(str(N)) + return any(cnt == collections.Counter(str(1 << c)) for c in range(32)) \ No newline at end of file diff --git a/solutions/python3/bak/87.py.bak b/solutions/python3/bak/87.py.bak new file mode 100644 index 0000000..b64a872 --- /dev/null +++ b/solutions/python3/bak/87.py.bak @@ -0,0 +1,13 @@ +class Solution: + def isScramble(self, s1, s2): + n, m = len(s1), len(s2) + if n != m or sorted(s1) != sorted(s2): + return False + if n < 4 or s1 == s2: + return True + f = self.isScramble + for i in range(1, n): + if f(s1[:i], s2[:i]) and f(s1[i:], s2[i:]) or \u005C + f(s1[:i], s2[-i:]) and f(s1[i:], s2[:-i]): + return True + return False \ No newline at end of file diff --git a/solutions/python3/bak/870.py.bak b/solutions/python3/bak/870.py.bak new file mode 100644 index 0000000..45b42f1 --- /dev/null +++ b/solutions/python3/bak/870.py.bak @@ -0,0 +1,16 @@ +class Solution: + def advantageCount(self, A: List[int], B: List[int]) -> List[int]: + A.sort(reverse = True) + non = [] + res = [-1] * len(A) + for b, i in sorted([(b, i) for i, b in enumerate(B)]): + while A and A[-1] <= b: + non.append(A.pop()) + if A: + res[i] = A.pop() + else: + break + for i in range(len(res)): + if res[i] == -1: + res[i] = non.pop() + return res \ No newline at end of file diff --git a/solutions/python3/bak/871.py.bak b/solutions/python3/bak/871.py.bak new file mode 100644 index 0000000..3ecfb33 --- /dev/null +++ b/solutions/python3/bak/871.py.bak @@ -0,0 +1,18 @@ +class Solution: + def minRefuelStops(self, target, startFuel, stations): + q, n, memo = [(0, -startFuel, 0, 0)], len(stations), set() + while q: + refill, fuel, pos, index = heapq.heappop(q) + fuel *= -1 + if index == n: + if fuel - (target - pos) >= 0: + return refill + else: + sPos, add = stations[index] + if (index, refill) not in memo and fuel - (sPos - pos) >= 0: + memo.add((index, refill)) + f1 = (fuel - (sPos - pos) + add) * -1 + f2 = (fuel - (sPos - pos)) * -1 + heapq.heappush(q, (refill + 1, f1, sPos, index + 1)) + heapq.heappush(q, (refill, f2, sPos, index + 1)) + return -1 \ No newline at end of file diff --git a/solutions/python3/bak/872.py.bak b/solutions/python3/bak/872.py.bak new file mode 100644 index 0000000..49b095b --- /dev/null +++ b/solutions/python3/bak/872.py.bak @@ -0,0 +1,9 @@ +class Solution: + def leafSimilar(self, root1, root2): + def dfs(node, arr): + if node: + if not node.left and not node.right: arr += [node.val] + dfs(node.left, arr) + dfs(node.right, arr) + return arr + return dfs(root1, []) == dfs(root2, []) \ No newline at end of file diff --git a/solutions/python3/bak/873.py.bak b/solutions/python3/bak/873.py.bak new file mode 100644 index 0000000..24166fc --- /dev/null +++ b/solutions/python3/bak/873.py.bak @@ -0,0 +1,15 @@ +class Solution: + def lenLongestFibSubseq(self, A): + n, pair, res, back = len(A), {}, 0, set() + for i in range(n): + back.add(A[i]) + j = i + 1 + mx = 2 * A[i] + while j < n and A[j] < mx: + if (A[j] - A[i], A[i]) in pair: + pair[(A[i], A[j])] = pair[(A[j] - A[i], A[i])] + 1 + else: + pair[(A[i], A[j])] = A[j] - A[i] in back and 3 or 2 + res = max(res, pair[(A[i], A[j])]) + j += 1 + return res > 2 and res or 0 \ No newline at end of file diff --git a/solutions/python3/bak/874.py.bak b/solutions/python3/bak/874.py.bak new file mode 100644 index 0000000..4e82349 --- /dev/null +++ b/solutions/python3/bak/874.py.bak @@ -0,0 +1,15 @@ +class Solution: + def robotSim(self, commands, obstacles): + i = j = mx = 0 + d, move, obstacles = 3, [(-1, 0), (0, -1), (1, 0), (0, 1)], set(map(tuple, obstacles)) + for command in commands: + if command == -2: d = (d + 1) % 4 + elif command == -1: d = (d - 1) % 4 + else: + x, y = move[d] + while command and (i + x, j + y) not in obstacles: + i += x + j += y + command -= 1 + mx = max(mx, i ** 2 + j ** 2) + return mx \ No newline at end of file diff --git a/solutions/python3/bak/875.py.bak b/solutions/python3/bak/875.py.bak new file mode 100644 index 0000000..10dc7ab --- /dev/null +++ b/solutions/python3/bak/875.py.bak @@ -0,0 +1,14 @@ +class Solution: + def minEatingSpeed(self, piles, H): + piles.sort() + l, r = 1, max(piles) + while l <= r: + mid = (l + r) // 2 + h = sum(math.ceil(p / mid) for p in piles) + if h > H: + l = mid + 1 + elif h < H: + r = mid - 1 + else: + return mid + return l \ No newline at end of file diff --git a/solutions/python3/bak/876.py.bak b/solutions/python3/bak/876.py.bak new file mode 100644 index 0000000..35e53bc --- /dev/null +++ b/solutions/python3/bak/876.py.bak @@ -0,0 +1,9 @@ +class Solution: + def middleNode(self, head): + root, n = head, 0 + while head: + head = head.next + n += 1 + for _ in range(n // 2): + root = root.next + return root \ No newline at end of file diff --git a/solutions/python3/bak/877.py.bak b/solutions/python3/bak/877.py.bak new file mode 100644 index 0000000..0e61e3d --- /dev/null +++ b/solutions/python3/bak/877.py.bak @@ -0,0 +1,2 @@ +class Solution: + def stoneGame(self, piles): return True \ No newline at end of file diff --git a/solutions/python3/bak/878.py.bak b/solutions/python3/bak/878.py.bak new file mode 100644 index 0000000..0d7cd16 --- /dev/null +++ b/solutions/python3/bak/878.py.bak @@ -0,0 +1,19 @@ +class Solution: + + def gcd(self, a, b): + while b: + a, b = b, a % b + return a + + def count(self, num, A, B, C): + return num // A + num // B - num // C + + def nthMagicalNumber(self, N, A, B): + l, r, C = 2, 2 ** 63 - 1, A * B // self.gcd(A, B) + while l < r: + mid = (l + r) // 2 + if self.count(mid, A, B, C) < N: + l = mid + 1 + else: + r = mid + return l % (10 ** 9 + 7) \ No newline at end of file diff --git a/solutions/python3/bak/879.py.bak b/solutions/python3/bak/879.py.bak new file mode 100644 index 0000000..aa53d7a --- /dev/null +++ b/solutions/python3/bak/879.py.bak @@ -0,0 +1,9 @@ +class Solution: + def profitableSchemes(self, G: int, P: int, group: List[int], profit: List[int]) -> int: + dp = [[0] * (G + 1) for i in range(P + 1)] + dp[0][0] = 1 + for p, g in zip(profit, group): + for i in range(P, -1, -1): + for j in range(G - g, -1, -1): + dp[min(i + p, P)][j + g] += dp[i][j] + return sum(dp[P]) % (10**9 + 7) \ No newline at end of file diff --git a/solutions/python3/bak/88.py.bak b/solutions/python3/bak/88.py.bak new file mode 100644 index 0000000..4d4ac11 --- /dev/null +++ b/solutions/python3/bak/88.py.bak @@ -0,0 +1,20 @@ +class Solution: + def merge(self, nums1, m, nums2, n): + """ + :type nums1: List[int] + :type m: int + :type nums2: List[int] + :type n: int + :rtype: void Do not return anything, modify nums1 in-place instead. + """ + while m > 0 and n > 0: + if nums1[m-1] >= nums2[n-1]: + nums1[m+n-1] = nums1[m-1] + m -= 1 + else: + nums1[m+n-1] = nums2[n-1] + n -= 1 + if n > 0: + nums1[:n] = nums2[:n] + + \ No newline at end of file diff --git a/solutions/python3/bak/880.py.bak b/solutions/python3/bak/880.py.bak new file mode 100644 index 0000000..876ca02 --- /dev/null +++ b/solutions/python3/bak/880.py.bak @@ -0,0 +1,12 @@ +class Solution: + def decodeAtIndex(self, S, K): + stack, l = [], 0 + for c in S: + l = l + 1 if c.isalpha() else l * int(c) + stack += c, + while l >= K: + while stack[-1].isdigit(): l //= int(stack.pop()) + K = K % l + if not K: return stack[-1] + l -= 1 + stack.pop() \ No newline at end of file diff --git a/solutions/python3/bak/881.py.bak b/solutions/python3/bak/881.py.bak new file mode 100644 index 0000000..33e7eb6 --- /dev/null +++ b/solutions/python3/bak/881.py.bak @@ -0,0 +1,15 @@ +class Solution: + def numRescueBoats(self, people, limit): + """ + :type people: List[int] + :type limit: int + :rtype: int + """ + people.sort() + l, r, cnt = 0, len(people) - 1, 0 + while l <= r: + if l != r and people[l] + people[r] > limit: l -= 1 + l += 1 + r -= 1 + cnt += 1 + return cnt \ No newline at end of file diff --git a/solutions/python3/bak/882.py.bak b/solutions/python3/bak/882.py.bak new file mode 100644 index 0000000..664eb8c --- /dev/null +++ b/solutions/python3/bak/882.py.bak @@ -0,0 +1,18 @@ +class Solution: + def reachableNodes(self, edges, M, N): + adj, seen = collections.defaultdict(dict), set() + for a, b, l in edges: + adj[a][b] = [l, 0] + adj[b][a] = [l, 0] + q = [(0, M, None)] + while q: + new = [] + for i, moves, pre in q: + seen.add(i) + for j in adj[i]: + if moves > adj[i][j][1]: + adj[i][j][1] = moves + if moves > adj[i][j][0] and j != pre: + new.append((j, moves - adj[i][j][0] - 1, i)) + q = new + return sum(min(adj[i][j][1] + adj[j][i][1], l) for i, j, l in edges) + len(seen) \ No newline at end of file diff --git a/solutions/python3/bak/883.py.bak b/solutions/python3/bak/883.py.bak new file mode 100644 index 0000000..dad8dcd --- /dev/null +++ b/solutions/python3/bak/883.py.bak @@ -0,0 +1,11 @@ +class Solution: + def projectionArea(self, grid): + """ + :type grid: List[List[int]] + :rtype: int + """ + n = len(grid) + top = sum(grid[i][j] != 0 for i in range(n) for j in range(n)) + front = sum(max(grid[i]) for i in range(n)) + side = sum(max(grid[i][j] for i in range(n)) for j in range(n)) + return top + front + side \ No newline at end of file diff --git a/solutions/python3/bak/884.py.bak b/solutions/python3/bak/884.py.bak new file mode 100644 index 0000000..2435857 --- /dev/null +++ b/solutions/python3/bak/884.py.bak @@ -0,0 +1,5 @@ +class Solution: + def uncommonFromSentences(self, A: str, B: str) -> List[str]: + c1 = collections.Counter(A.split()) + c2 = collections.Counter(B.split()) + return list(c for c in c1 if c1[c] == 1 and c not in c2) + list(c for c in c2 if c2[c] == 1 and c not in c1) \ No newline at end of file diff --git a/solutions/python3/bak/885.py.bak b/solutions/python3/bak/885.py.bak new file mode 100644 index 0000000..a0c8288 --- /dev/null +++ b/solutions/python3/bak/885.py.bak @@ -0,0 +1,13 @@ +class Solution: + def spiralMatrixIII(self, R, C, r0, c0): + direct, res, n, l, ind = [(-1, 0), (0, 1), (1, 0), (0, -1)], [[r0, c0]], R * C, 1, 1 + while len(res) < n: + for __ in range(2): + for _ in range(l): + r0 += direct[ind][0] + c0 += direct[ind][1] + if 0 <= r0 < R and 0 <= c0 < C: + res.append([r0, c0]) + ind = (ind + 1) % 4 + l += 1 + return res \ No newline at end of file diff --git a/solutions/python3/bak/886.py.bak b/solutions/python3/bak/886.py.bak new file mode 100644 index 0000000..532a3c7 --- /dev/null +++ b/solutions/python3/bak/886.py.bak @@ -0,0 +1,15 @@ +class Solution: + def merge(self, node, p, group, disliked): + group[node] = p + for v in disliked[node]: + if group[v] == p or (group[v] == v and not self.merge(v, -p, group, disliked)): return False + return True + + def possibleBipartition(self, N, dislikes): + group, disliked = [i for i in range(N + 1)], collections.defaultdict(set) + for a, b in dislikes: + disliked[a].add(b) + disliked[b].add(a) + for i in range(1, N + 1): + if group[i] == i and not self.merge(i, 2001, group, disliked): return False + return True \ No newline at end of file diff --git a/solutions/python3/bak/887.py.bak b/solutions/python3/bak/887.py.bak new file mode 100644 index 0000000..23764b8 --- /dev/null +++ b/solutions/python3/bak/887.py.bak @@ -0,0 +1,12 @@ +class Solution: + def superEggDrop(self, K, N): + drops = 0 # the number of eggs dropped + floors = [0 for _ in range(K + 1)] # floors[i] is the number of floors that can be checked with i eggs + + while floors[K] < N: # until we can reach N floors with K eggs + + for eggs in range(K, 0, -1): + floors[eggs] += 1 + floors[eggs - 1] + drops += 1 + + return drops \ No newline at end of file diff --git a/solutions/python3/bak/888.py.bak b/solutions/python3/bak/888.py.bak new file mode 100644 index 0000000..767fb34 --- /dev/null +++ b/solutions/python3/bak/888.py.bak @@ -0,0 +1,12 @@ +class Solution: + def fairCandySwap(self, A, B): + """ + :type A: List[int] + :type B: List[int] + :rtype: List[int] + """ + a, b = set(A), set(B) + diff =(sum(A) - sum(B)) // 2 + for c in B: + if c + diff in a: + return [c + diff, c] \ No newline at end of file diff --git a/solutions/python3/bak/889.py.bak b/solutions/python3/bak/889.py.bak new file mode 100644 index 0000000..28bc02c --- /dev/null +++ b/solutions/python3/bak/889.py.bak @@ -0,0 +1,13 @@ +class Solution: + def constructFromPrePost(self, pre, post): + if pre: + root = TreeNode(pre.pop(0)) + post.pop() + if pre: + if pre[0] == post[-1]: + root.left = self.constructFromPrePost(pre, post) + else: + l, r = post.index(pre[0]), pre.index(post[-1]) + root.left = self.constructFromPrePost(pre[:r], post[:l + 1]) + root.right = self.constructFromPrePost(pre[r:], post[l + 1:]) + return root \ No newline at end of file diff --git a/solutions/python3/bak/89.py.bak b/solutions/python3/bak/89.py.bak new file mode 100644 index 0000000..c92f2ca --- /dev/null +++ b/solutions/python3/bak/89.py.bak @@ -0,0 +1,7 @@ +class Solution: + def grayCode(self, n: int) -> List[int]: + results = [0] + for i in range(n): + results += [x + pow(2, i) for x in reversed(results)] + return results + \ No newline at end of file diff --git a/solutions/python3/bak/890.py.bak b/solutions/python3/bak/890.py.bak new file mode 100644 index 0000000..96ac261 --- /dev/null +++ b/solutions/python3/bak/890.py.bak @@ -0,0 +1,17 @@ +class Solution: + def findAndReplacePattern(self, words, pattern): + """ + :type words: List[str] + :type pattern: str + :rtype: List[str] + """ + res = [] + for w in words: + mp12, mp21, match = {}, {}, True + for c1, c2 in zip(w, pattern): + if (c1 in mp12 and mp12[c1] != c2) or (c2 in mp21 and mp21[c2] != c1): + match = False + break + mp12[c1], mp21[c2] = c2, c1 + if match: res.append(w) + return res \ No newline at end of file diff --git a/solutions/python3/bak/891.py.bak b/solutions/python3/bak/891.py.bak new file mode 100644 index 0000000..7419c98 --- /dev/null +++ b/solutions/python3/bak/891.py.bak @@ -0,0 +1,9 @@ +class Solution: + def sumSubseqWidths(self, A): + A.sort() + res=0 + for i in range(len(A)): + res*=2 + res-=A[i] + res+=A[~i] + return res % (10**9+7) \ No newline at end of file diff --git a/solutions/python3/bak/892.py.bak b/solutions/python3/bak/892.py.bak new file mode 100644 index 0000000..150415e --- /dev/null +++ b/solutions/python3/bak/892.py.bak @@ -0,0 +1,11 @@ +class Solution: + def surfaceArea(self, grid): + n, sm = len(grid), 0 + for i in range(n): + for j in range(n): + sm += grid[i][j] and grid[i][j] * 4 + 2 + if i > 0: sm -= min(grid[i - 1][j], grid[i][j]) + if j > 0: sm -= min(grid[i][j - 1], grid[i][j]) + if i < n - 1: sm -= min(grid[i + 1][j], grid[i][j]) + if j < n - 1: sm -= min(grid[i][j + 1], grid[i][j]) + return sm \ No newline at end of file diff --git a/solutions/python3/bak/893.py.bak b/solutions/python3/bak/893.py.bak new file mode 100644 index 0000000..7b1dbd1 --- /dev/null +++ b/solutions/python3/bak/893.py.bak @@ -0,0 +1,3 @@ +class Solution: + def numSpecialEquivGroups(self, A): + return len(set("".join(sorted(s[0::2])) + "".join(sorted(s[1::2])) for s in A)) \ No newline at end of file diff --git a/solutions/python3/bak/894.py.bak b/solutions/python3/bak/894.py.bak new file mode 100644 index 0000000..fe48c3b --- /dev/null +++ b/solutions/python3/bak/894.py.bak @@ -0,0 +1,12 @@ +class Solution: + def allPossibleFBT(self, N): + def constr(N): + if N == 1: yield TreeNode(0) + for i in range(1, N, 2): + for l in constr(i): + for r in constr(N - i - 1): + m = TreeNode(0) + m.left = l + m.right = r + yield m + return list(constr(N)) \ No newline at end of file diff --git a/solutions/python3/bak/895.py.bak b/solutions/python3/bak/895.py.bak new file mode 100644 index 0000000..ffcbd6c --- /dev/null +++ b/solutions/python3/bak/895.py.bak @@ -0,0 +1,17 @@ +class FreqStack: + + def __init__(self): + self.stacks = collections.defaultdict(list) + self.freq = collections.Counter() + self.maxFreq = 0 + + def push(self, x): + self.freq[x] += 1 + self.maxFreq = max(self.maxFreq, self.freq[x]) + self.stacks[self.freq[x]].append(x) + + def pop(self): + num = self.stacks[self.maxFreq].pop() + self.freq[num] -= 1 + if not self.stacks[self.maxFreq]: self.maxFreq -= 1 + return num \ No newline at end of file diff --git a/solutions/python3/bak/896.py.bak b/solutions/python3/bak/896.py.bak new file mode 100644 index 0000000..6a81d5c --- /dev/null +++ b/solutions/python3/bak/896.py.bak @@ -0,0 +1,3 @@ +class Solution: + def isMonotonic(self, A): + return all(A[i] <= A[i - 1] for i in range(1, len(A))) or all(A[i] >= A[i - 1] for i in range(1, len(A))) \ No newline at end of file diff --git a/solutions/python3/bak/897.py.bak b/solutions/python3/bak/897.py.bak new file mode 100644 index 0000000..0392770 --- /dev/null +++ b/solutions/python3/bak/897.py.bak @@ -0,0 +1,14 @@ +# Definition for a binary tree node. +# class TreeNode: +# def __init__(self, x): +# self.val = x +# self.left = None +# self.right = None + +class Solution: + def increasingBST(self, root, tail = None): + if not root: return tail + res = self.increasingBST(root.left, root) + root.left = None + root.right = self.increasingBST(root.right, tail) + return res \ No newline at end of file diff --git a/solutions/python3/bak/898.py.bak b/solutions/python3/bak/898.py.bak new file mode 100644 index 0000000..cfbfb83 --- /dev/null +++ b/solutions/python3/bak/898.py.bak @@ -0,0 +1,7 @@ +class Solution: + def subarrayBitwiseORs(self, A): + nums, n, pre = set(), len(A), set() + for a in A: + pre = {a} | {num | a for num in pre} + nums |= pre + return len(nums) \ No newline at end of file diff --git a/solutions/python3/bak/899.py.bak b/solutions/python3/bak/899.py.bak new file mode 100644 index 0000000..cda2faa --- /dev/null +++ b/solutions/python3/bak/899.py.bak @@ -0,0 +1,3 @@ +class Solution: + def orderlyQueue(self, S, K): + return "".join(sorted(S)) if K > 1 else min(S[i:] + S[:i] for i in range(len(S))) \ No newline at end of file diff --git a/solutions/python3/bak/9.py.bak b/solutions/python3/bak/9.py.bak new file mode 100644 index 0000000..af02e91 --- /dev/null +++ b/solutions/python3/bak/9.py.bak @@ -0,0 +1,3 @@ +class Solution: + def isPalindrome(self, x): + return str(x) == str(x)[::-1] \ No newline at end of file diff --git a/solutions/python3/bak/90.py.bak b/solutions/python3/bak/90.py.bak new file mode 100644 index 0000000..2e12f79 --- /dev/null +++ b/solutions/python3/bak/90.py.bak @@ -0,0 +1,15 @@ +class Solution: + def subsetsWithDup(self, nums): + """ + :type nums: List[int] + :rtype: List[List[int]] + """ + from itertools import combinations as cb + res, dic = [], set() + for i in range(len(nums) + 1): + for item in cb(nums, i): + item = tuple(sorted(item)) + if item not in dic: + dic.add(item) + res.append(item) + return res \ No newline at end of file diff --git a/solutions/python3/bak/900.py.bak b/solutions/python3/bak/900.py.bak new file mode 100644 index 0000000..771c0ff --- /dev/null +++ b/solutions/python3/bak/900.py.bak @@ -0,0 +1,15 @@ +class RLEIterator: + + def __init__(self, A): + self.it = A[::-1] + + def next(self, n): + while self.it and self.it[-1] <= n: + if self.it[-1]: last = self.it[-2] + n -= self.it.pop() + self.it.pop() + if n and self.it: + self.it[-1] -= n + last = self.it[-2] + return last if self.it else -1 + \ No newline at end of file diff --git a/solutions/python3/bak/901.py.bak b/solutions/python3/bak/901.py.bak new file mode 100644 index 0000000..62177de --- /dev/null +++ b/solutions/python3/bak/901.py.bak @@ -0,0 +1,27 @@ +class StockSpanner: + + def __init__(self): + self.arr = [] + self.res = [] + + def next(self, price): + """ + :type price: int + :rtype: int + """ + if self.arr and self.arr[-1] > price: self.res.append(1) + else: + i = len(self.arr) - 1 + while i >= 0: + if self.arr[i] <= price and self.res[i]: + i -= self.res[i] + else: break + self.res.append(len(self.arr) - i) + self.arr.append(price) + return self.res[-1] + + + +# Your StockSpanner object will be instantiated and called as such: +# obj = StockSpanner() +# param_1 = obj.next(price) \ No newline at end of file diff --git a/solutions/python3/bak/902.py.bak b/solutions/python3/bak/902.py.bak new file mode 100644 index 0000000..51ba757 --- /dev/null +++ b/solutions/python3/bak/902.py.bak @@ -0,0 +1,16 @@ +class Solution: + def atMostNGivenDigitSet(self, D, N): + def less(c): + return len([char for char in D if char < c]) + d, cnt, l = len(D), 0, len(str(N)) + # For numbers which have less digits than N, simply len(D) ** digits_length different numbers can be created + for i in range(1, l): + cnt += d ** i + """ + We should also consider edge cases where previous digits match with related digits in N. In this case, we can make a number with previous digits + (digits less than N[i]) + D ** remaining length + """ + for i, c in enumerate(str(N)): + cnt += less(c) * (d ** (l - i - 1)) + if c not in D: break + if i == l - 1: cnt += 1 + return cnt \ No newline at end of file diff --git a/solutions/python3/bak/903.py.bak b/solutions/python3/bak/903.py.bak new file mode 100644 index 0000000..ecd76c1 --- /dev/null +++ b/solutions/python3/bak/903.py.bak @@ -0,0 +1,13 @@ +class Solution: + def numPermsDISequence(self, S: str) -> int: + dp = [1] * (len(S) + 1) + for c in S: + if c == "I": + dp = dp[:-1] + for i in range(1, len(dp)): + dp[i] += dp[i - 1] + else: + dp = dp[1:] + for i in range(len(dp) - 1)[::-1]: + dp[i] += dp[i + 1] + return dp[0] % (10**9 + 7) \ No newline at end of file diff --git a/solutions/python3/bak/904.py.bak b/solutions/python3/bak/904.py.bak new file mode 100644 index 0000000..8fa3c76 --- /dev/null +++ b/solutions/python3/bak/904.py.bak @@ -0,0 +1,12 @@ +class Solution: + def totalFruit(self, tree: List[int]) -> int: + res = i = 0 + last = collections.defaultdict(int) + for j, val in enumerate(tree): + if len(last) == 2 and val not in last: + pre = min(last.values()) + i = pre + 1 + last.pop(tree[pre]) + last[val] = j + res = max(res, j - i + 1) + return res \ No newline at end of file diff --git a/solutions/python3/bak/905.py.bak b/solutions/python3/bak/905.py.bak new file mode 100644 index 0000000..65b83ff --- /dev/null +++ b/solutions/python3/bak/905.py.bak @@ -0,0 +1,3 @@ +class Solution: + def sortArrayByParity(self, A): + return [a for a in A if not a % 2] + [a for a in A if a % 2] \ No newline at end of file diff --git a/solutions/python3/bak/906.py.bak b/solutions/python3/bak/906.py.bak new file mode 100644 index 0000000..9475c5a --- /dev/null +++ b/solutions/python3/bak/906.py.bak @@ -0,0 +1,20 @@ +class Solution: + def superpalindromesInRange(self, L, R): + L, R = int(L), int(R) + left = int(math.floor(math.sqrt(L))) + right = int(math.ceil(math.sqrt(R))) + n1, n2 = len(str(left)), len(str(right)) + n1 = n1//2 if n1%2==0 else n1//2+1 + n2 = n2//2 if n2%2==0 else n2//2+1 + start = int('1' + '0'*(n1 - 1)) + end = int('9' * n2) + 1 + ans = 0 + for i in range(start, end): + x = str(i) + num1 = int(x + x[::-1]) + num2 = int(x + x[:-1][::-1]) + for num in [num1, num2]: + cand = num * num + if L <= cand <= R and str(cand) == str(cand)[::-1]: + ans += 1 + return ans \ No newline at end of file diff --git a/solutions/python3/bak/907.py.bak b/solutions/python3/bak/907.py.bak new file mode 100644 index 0000000..c4f38fe --- /dev/null +++ b/solutions/python3/bak/907.py.bak @@ -0,0 +1,10 @@ +class Solution: + def sumSubarrayMins(self, A): + res, stack = 0, [] + A = [float('-inf')] + A + [float('-inf')] + for i, n in enumerate(A): + while stack and A[stack[-1]] > n: + cur = stack.pop() + res += A[cur] * (i - cur) * (cur - stack[-1]) + stack.append(i) + return res % (10 ** 9 + 7) \ No newline at end of file diff --git a/solutions/python3/bak/908.py.bak b/solutions/python3/bak/908.py.bak new file mode 100644 index 0000000..1515b5c --- /dev/null +++ b/solutions/python3/bak/908.py.bak @@ -0,0 +1,4 @@ +class Solution: + def smallestRangeI(self, A, K): + l, r = min(A) + K, max(A) - K + return 0 if l >= r else r - l \ No newline at end of file diff --git a/solutions/python3/bak/909.py.bak b/solutions/python3/bak/909.py.bak new file mode 100644 index 0000000..bc49cb7 --- /dev/null +++ b/solutions/python3/bak/909.py.bak @@ -0,0 +1,14 @@ +class Solution: + def snakesAndLadders(self, board): + arr, nn, q, seen, moves = [0], len(board) ** 2, [1], set(), 0 + for i, row in enumerate(board[::-1]): arr += row[::-1] if i % 2 else row + while q: + new = [] + for sq in q: + if sq == nn: return moves + for i in range(1, 7): + if sq + i <= nn and sq + i not in seen: + seen.add(sq + i) + new.append(sq + i if arr[sq + i] == -1 else arr[sq + i]) + q, moves = new, moves + 1 + return -1 \ No newline at end of file diff --git a/solutions/python3/bak/91.py.bak b/solutions/python3/bak/91.py.bak new file mode 100644 index 0000000..63a0459 --- /dev/null +++ b/solutions/python3/bak/91.py.bak @@ -0,0 +1,8 @@ +class Solution: + def numDecodings(self, s): + if s[0] == "0": return 0 + dp1 = dp2 = 1 + for i in range(1, len(s)): + if s[i] == "0" and (s[i - 1] == "0" or s[i - 1] >= "3"): return 0 + dp1, dp2 = [dp2, dp1] if s[i] == "0" else [dp2, dp2 + dp1] if "10" <= s[i -1: i + 1] <= "26" else [dp2, dp2] + return dp2 \ No newline at end of file diff --git a/solutions/python3/bak/910.py.bak b/solutions/python3/bak/910.py.bak new file mode 100644 index 0000000..bcb18d3 --- /dev/null +++ b/solutions/python3/bak/910.py.bak @@ -0,0 +1,4 @@ +class Solution: + def smallestRangeII(self, A, K): + A.sort() + return min([max(A[-1] - K, A[i] + K) - min(A[0] + K, A[i + 1] - K) for i in range(len(A) - 1)] + [A[-1] - A[0]]) \ No newline at end of file diff --git a/solutions/python3/bak/911.py.bak b/solutions/python3/bak/911.py.bak new file mode 100644 index 0000000..5e4ed37 --- /dev/null +++ b/solutions/python3/bak/911.py.bak @@ -0,0 +1,15 @@ +class TopVotedCandidate: + + def __init__(self, persons, times): + votes = collections.defaultdict(int) + winner = 0 + self.winners = [None] * len(times) + self.times = times + for i, person in enumerate(persons): + votes[person] += 1 + if votes[person] >= votes[winner]: + winner = person + self.winners[i] = winner + + def q(self, t): + return self.winners[bisect.bisect(self.times, t) - 1] \ No newline at end of file diff --git a/solutions/python3/bak/912.py.bak b/solutions/python3/bak/912.py.bak new file mode 100644 index 0000000..1534a1d --- /dev/null +++ b/solutions/python3/bak/912.py.bak @@ -0,0 +1,12 @@ +class Solution: + def sortArray(self, nums: List[int]) -> List[int]: + if len(nums) <= 1: + return nums + + pivot = random.choice(nums) + lt = [v for v in nums if v < pivot] + eq = [v for v in nums if v == pivot] + gt = [v for v in nums if v > pivot] + + return self.sortArray(lt) + eq + self.sortArray(gt) + \ No newline at end of file diff --git a/solutions/python3/bak/913.py.bak b/solutions/python3/bak/913.py.bak new file mode 100644 index 0000000..a2d7988 --- /dev/null +++ b/solutions/python3/bak/913.py.bak @@ -0,0 +1,56 @@ +class Solution: + def catMouseGame(self, graph: 'List[List[int]]') -> 'int': + mouse_visited = [False] * len(graph) + mouse_win_map = [[None for column in range(len(graph))] for row in range(len(graph))] + cat_visited = [False] * len(graph) + cat_win_map = [[None for column in range(len(graph))] for row in range(len(graph))] + if self.isMouseWin(graph, 1, 2, mouse_visited, mouse_win_map): + return 1 + elif self.isCatWin(graph, 1, 2, cat_visited, cat_win_map): + return 2 + else: + return 0 + + def isMouseWin(self, graph, mouse, cat, mouse_visited, mouse_win_map): + if mouse == 0: + return True + if mouse_win_map[mouse][cat] is not None: + return mouse_win_map[mouse][cat] + mouse_visited[mouse] = True + for mouseMove in graph[mouse]: + if mouseMove == 0 or (mouseMove not in graph[cat] and mouseMove != cat): + if not mouse_visited[mouseMove]: + mouseWinFlag = True + for catMove in graph[cat]: + if catMove != 0 and not self.isMouseWin(graph, mouseMove, catMove, mouse_visited, mouse_win_map): + mouseWinFlag = False + break + if mouseWinFlag: + mouse_visited[mouse] = False + mouse_win_map[mouse][cat] = True + return True + mouse_visited[mouse] = False + mouse_win_map[mouse][cat] = False + return False + + def isCatWin(self, graph, mouse, cat, cat_visited, cat_win_map): + if mouse == 0: + return False + if cat_win_map[mouse][cat] is not None: + return cat_win_map[mouse][cat] + cat_visited[cat] = True + for mouseMove in graph[mouse]: + if mouseMove == 0 or (mouseMove not in graph[cat] and mouseMove != cat): + catWinFlag = True + for catMove in graph[cat]: + if catMove != 0 and not cat_visited[catMove] and not self.isCatWin(graph, mouseMove, catMove, + cat_visited, cat_win_map): + catWinFlag = False + break + if not catWinFlag: + cat_visited[cat] = False + cat_win_map[mouse][cat] = False + return False + cat_visited[cat] = False + cat_win_map[mouse][cat] = True + return True \ No newline at end of file diff --git a/solutions/python3/bak/914.py.bak b/solutions/python3/bak/914.py.bak new file mode 100644 index 0000000..0555b09 --- /dev/null +++ b/solutions/python3/bak/914.py.bak @@ -0,0 +1,7 @@ +class Solution: + def hasGroupsSizeX(self, deck): + import functools + def gcd(a, b): + if not b: return a + return gcd(b, a % b) + return functools.reduce(gcd, collections.Counter(deck).values()) != 1 \ No newline at end of file diff --git a/solutions/python3/bak/915.py.bak b/solutions/python3/bak/915.py.bak new file mode 100644 index 0000000..c1697dc --- /dev/null +++ b/solutions/python3/bak/915.py.bak @@ -0,0 +1,12 @@ +class Solution: + def partitionDisjoint(self, A): + rMin, lMax, mx, mn = [0] * len(A), [0] * len(A), -float("inf"), float("inf") + for i, num in enumerate(A): + mx = max(mx, num) + lMax[i] = mx + for i in range(len(A) - 1, -1, -1): + mn = min(mn, A[i]) + rMin[i] = mn + for i in range(len(A) - 1): + if lMax[i] <= rMin[i + 1]: + return i + 1 \ No newline at end of file diff --git a/solutions/python3/bak/916.py.bak b/solutions/python3/bak/916.py.bak new file mode 100644 index 0000000..eb3552c --- /dev/null +++ b/solutions/python3/bak/916.py.bak @@ -0,0 +1,12 @@ +class Solution: + def wordSubsets(self, A: List[str], B: List[str]) -> List[str]: + cnt = collections.Counter() + for b in B: + for k, v in collections.Counter(b).items(): + if cnt[k] < v: + cnt[k] = v + res = [] + for a in A: + if not cnt - collections.Counter(a): + res.append(a) + return res \ No newline at end of file diff --git a/solutions/python3/bak/917.py.bak b/solutions/python3/bak/917.py.bak new file mode 100644 index 0000000..10c7b94 --- /dev/null +++ b/solutions/python3/bak/917.py.bak @@ -0,0 +1,4 @@ +class Solution: + def reverseOnlyLetters(self, S): + r = [s for s in S if s.isalpha()] + return "".join(S[i] if not S[i].isalpha() else r.pop() for i in range(len(S))) \ No newline at end of file diff --git a/solutions/python3/bak/918.py.bak b/solutions/python3/bak/918.py.bak new file mode 100644 index 0000000..ba9cd12 --- /dev/null +++ b/solutions/python3/bak/918.py.bak @@ -0,0 +1,12 @@ +class Solution: + def maxSubarraySumCircular(self, A): + lMn, rMx, res, lSm, rSm, preSm = float("inf"), [-float("inf")] * (len(A) + 1), -float("inf"), 0, 0, 0 + for i in range(len(A) - 1, -1, -1): + rSm += A[i] + rMx[i] = max(rMx[i + 1], rSm) + for i in range(len(A)): + preSm += A[i] + lMn = min(lMn, lSm) + res = max(res, preSm, preSm - lMn, preSm + rMx[i + 1]) + lSm += A[i] + return res \ No newline at end of file diff --git a/solutions/python3/bak/919.py.bak b/solutions/python3/bak/919.py.bak new file mode 100644 index 0000000..ab4bcbd --- /dev/null +++ b/solutions/python3/bak/919.py.bak @@ -0,0 +1,19 @@ +class CBTInserter: + + def __init__(self, root): + self.arr, q = [], [root] + while q: + self.arr += [node for node in q] + q = [child for node in q for child in (node.left, node.right) if child] + + def insert(self, v): + parent = self.arr[(len(self.arr) - 1) // 2] + if not len(self.arr) % 2: + child = parent.right = TreeNode(v) + else: + child = parent.left = TreeNode(v) + self.arr += [child] + return parent.val + + def get_root(self): + return self.arr[0] \ No newline at end of file diff --git a/solutions/python3/bak/92.py.bak b/solutions/python3/bak/92.py.bak new file mode 100644 index 0000000..fe373e7 --- /dev/null +++ b/solutions/python3/bak/92.py.bak @@ -0,0 +1,18 @@ +class Solution: + def reverseBetween(self, head, m, n): + dummy_left, dummy_left.next, i = ListNode(0), head, 1 + prev = dummy_left + while head: + latter = head.next + if m == n: + break + if i == m: + head_left, right = prev, head + if i == n: + head_right, left = head.next, head + if m < i <= n: + head.next = prev + prev, head, i = head, latter, i+1 + if m != n: + head_left.next, right.next = left, head_right + return dummy_left.next \ No newline at end of file diff --git a/solutions/python3/bak/920.py.bak b/solutions/python3/bak/920.py.bak new file mode 100644 index 0000000..c451993 --- /dev/null +++ b/solutions/python3/bak/920.py.bak @@ -0,0 +1,7 @@ +from functools import lru_cache + +class Solution: + def numMusicPlaylists(self, N, L, K): + @lru_cache(None) + def dp(i, j): return +(j == 0) if not i else (dp(i-1, j-1) * (N-j+1) + dp(i-1, j) * max(j-K, 0)) % (10**9+7) + return dp(L, N) \ No newline at end of file diff --git a/solutions/python3/bak/921.py.bak b/solutions/python3/bak/921.py.bak new file mode 100644 index 0000000..4af6b6a --- /dev/null +++ b/solutions/python3/bak/921.py.bak @@ -0,0 +1,11 @@ +class Solution: + def minAddToMakeValid(self, S): + r, l = 0, [] + for s in S: + if s == "(": + l.append(s) + elif l: + l.pop() + else: + r += 1 + return r + len(l) \ No newline at end of file diff --git a/solutions/python3/bak/922.py.bak b/solutions/python3/bak/922.py.bak new file mode 100644 index 0000000..c9055e4 --- /dev/null +++ b/solutions/python3/bak/922.py.bak @@ -0,0 +1,4 @@ +class Solution: + def sortArrayByParityII(self, A): + even, odd = [a for a in A if not a % 2], [a for a in A if a % 2] + return [even.pop() if not i % 2 else odd.pop() for i in range(len(A))] \ No newline at end of file diff --git a/solutions/python3/bak/923.py.bak b/solutions/python3/bak/923.py.bak new file mode 100644 index 0000000..94479ea --- /dev/null +++ b/solutions/python3/bak/923.py.bak @@ -0,0 +1,10 @@ +class Solution: + def threeSumMulti(self, A, target): + c = collections.Counter(A) + res = 0 + for i, j in itertools.combinations_with_replacement(c, 2): + k = target - i - j + if i == j == k: res += c[i] * (c[i] - 1) * (c[i] - 2) // 6 + elif i == j != k: res += c[i] * (c[i] - 1) // 2 * c[k] + elif k > i and k > j: res += c[i] * c[j] * c[k] + return res % (10**9 + 7) \ No newline at end of file diff --git a/solutions/python3/bak/924.py.bak b/solutions/python3/bak/924.py.bak new file mode 100644 index 0000000..ffd677b --- /dev/null +++ b/solutions/python3/bak/924.py.bak @@ -0,0 +1,14 @@ +class Solution: + def minMalwareSpread(self, graph, initial): + def dfs(i): + nodes.add(i) + for j in range(len(graph[i])): + if graph[i][j] and j not in nodes: + dfs(j) + rank, initial = collections.defaultdict(list), set(initial) + for node in sorted(initial): + nodes = set() + dfs(node) + if nodes & initial == {node}: + rank[len(nodes)].append(node) + return rank[max(rank)][0] if rank else min(initial) \ No newline at end of file diff --git a/solutions/python3/bak/925.py.bak b/solutions/python3/bak/925.py.bak new file mode 100644 index 0000000..2ae4c13 --- /dev/null +++ b/solutions/python3/bak/925.py.bak @@ -0,0 +1,9 @@ +class Solution: + def isLongPressedName(self, name, typed): + pre, i = None, 0 + for c in typed: + if i < len(name) and c == name[i]: + pre, i = name[i], i + 1 + elif c != pre: + return False + return i == len(name) \ No newline at end of file diff --git a/solutions/python3/bak/926.py.bak b/solutions/python3/bak/926.py.bak new file mode 100644 index 0000000..d79e1e4 --- /dev/null +++ b/solutions/python3/bak/926.py.bak @@ -0,0 +1,5 @@ +class Solution: + def minFlipsMonoIncr(self, s): + res = cur = s.count("0") + for c in s: res, cur = c == "1" and (res, cur + 1) or (min(res, cur - 1), cur - 1) + return res \ No newline at end of file diff --git a/solutions/python3/bak/927.py.bak b/solutions/python3/bak/927.py.bak new file mode 100644 index 0000000..62a9fb4 --- /dev/null +++ b/solutions/python3/bak/927.py.bak @@ -0,0 +1,11 @@ +class Solution(object): + def threeEqualParts(self, A): + sm = sum(A) + if sm % 3: return [-1, -1] + t = sm // 3 + if not t: return [0, len(A) - 1] + breaks = [0] + [i for i, x in enumerate(A) if x] + i1, j1, i2, j2, i3, j3 = breaks[1], breaks[t], breaks[t + 1], breaks[2 * t], breaks[2 * t + 1], breaks[3 * t] + if not (A[i1: j1 + 1] == A[i2: j2 + 1] == A[i3: j3 + 1]): return [-1, -1] + if i2 - j1 < len(A) - j3 or i3 - j2 < len(A) - j3: return [-1, -1] + return [j1 + len(A) - j3 - 1, j2+ len(A) - j3] \ No newline at end of file diff --git a/solutions/python3/bak/928.py.bak b/solutions/python3/bak/928.py.bak new file mode 100644 index 0000000..76a91bd --- /dev/null +++ b/solutions/python3/bak/928.py.bak @@ -0,0 +1,13 @@ +class Solution: + def minMalwareSpread(self, graph, initial): + def dfs(i): + seen.add(i) + return not any(graph[i][j] and j not in seen and (j in initials or not dfs(j)) for j in range(len(graph[i]))) + res, mx, initials = min(initial), 1, set(initial) + for node in sorted(initial): + impact = set() + for j in range(len(graph[node])): + seen = {node} + if graph[node][j] and j not in initials and dfs(j): impact |= seen + if len(impact) > mx: res, mx = node, len(impact) + return res \ No newline at end of file diff --git a/solutions/python3/bak/929.py.bak b/solutions/python3/bak/929.py.bak new file mode 100644 index 0000000..6f15666 --- /dev/null +++ b/solutions/python3/bak/929.py.bak @@ -0,0 +1,8 @@ +class Solution: + def numUniqueEmails(self, emails: List[str]) -> int: + rec = set() + for email in emails: + local, domain = email.split('@') + local = local.split('+')[0].replace('.', '') + rec.add(local + '@' + domain) + return len(rec) \ No newline at end of file diff --git a/solutions/python3/bak/93.py.bak b/solutions/python3/bak/93.py.bak new file mode 100644 index 0000000..5e4cc93 --- /dev/null +++ b/solutions/python3/bak/93.py.bak @@ -0,0 +1,14 @@ +class Solution: + def restoreIpAddresses(self, s: str) -> List[str]: + if len(s) > 12: return [] + bfs = [(0, '')] + for c in s: + new = [] + c = int(c) + for cur, st in bfs: + if cur * 10 + c <= 255 and (st[-1:] != '0' or cur): + new.append((cur * 10 + c, st + str(c))) + if st: + new.append((c, st + '.' + str(c))) + bfs = new + return [st for cur, st in bfs if st.count('.') == 3] \ No newline at end of file diff --git a/solutions/python3/bak/930.py.bak b/solutions/python3/bak/930.py.bak new file mode 100644 index 0000000..3db6ca2 --- /dev/null +++ b/solutions/python3/bak/930.py.bak @@ -0,0 +1,8 @@ +class Solution: + def numSubarraysWithSum(self, A, S): + res, sm, sums = 0, 0, collections.defaultdict(int) + for a in A: + sm += a + res += sums[sm - S] + (sm == S) + sums[sm] += 1 + return res \ No newline at end of file diff --git a/solutions/python3/bak/931.py.bak b/solutions/python3/bak/931.py.bak new file mode 100644 index 0000000..bd07b13 --- /dev/null +++ b/solutions/python3/bak/931.py.bak @@ -0,0 +1,6 @@ +class Solution: + def minFallingPathSum(self, A): + for i in range(1, len(A)): + for j in range(len(A)): + A[i][j] += min(A[i - 1][j and j - 1:j + 2]) + return min(A[-1]) \ No newline at end of file diff --git a/solutions/python3/bak/932.py.bak b/solutions/python3/bak/932.py.bak new file mode 100644 index 0000000..d1a2b18 --- /dev/null +++ b/solutions/python3/bak/932.py.bak @@ -0,0 +1,5 @@ +class Solution: + def beautifulArray(self, N): + if N == 1: return [1] + half = self.beautifulArray(N - N // 2) + return [i * 2 - 1 for i in half] + [i * 2 for i in half if i * 2 <= N] \ No newline at end of file diff --git a/solutions/python3/bak/933.py.bak b/solutions/python3/bak/933.py.bak new file mode 100644 index 0000000..9c3243d --- /dev/null +++ b/solutions/python3/bak/933.py.bak @@ -0,0 +1,10 @@ +class RecentCounter: + + def __init__(self): + self.p = collections.deque() + + def ping(self, t): + self.p.append(t) + while self.p[0] < t - 3000: + self.p.popleft() + return len(self.p) \ No newline at end of file diff --git a/solutions/python3/bak/934.py.bak b/solutions/python3/bak/934.py.bak new file mode 100644 index 0000000..5694139 --- /dev/null +++ b/solutions/python3/bak/934.py.bak @@ -0,0 +1,27 @@ +class Solution: + def shortestBridge(self, A): + def dfs(i, j): + A[i][j] = -1 + q.append((i, j)) + for x, y in ((i - 1, j), (i + 1, j), (i, j - 1), (i, j + 1)): + if 0 <= x < n and 0 <= y < n and A[x][y] == 1: + dfs(x, y) + def first(): + for i in range(n): + for j in range(n): + if A[i][j]: + return i, j + n, step, q = len(A), 0, [] + dfs(*first()) + while True: + new = [] + for i, j in q: + for x, y in ((i - 1, j), (i + 1, j), (i, j - 1), (i, j + 1)): + if 0 <= x < n and 0 <= y < n: + if A[x][y] == 1: + return step + elif not A[x][y]: + A[x][y] = -1 + new.append((x, y)) + step += 1 + q = new \ No newline at end of file diff --git a/solutions/python3/bak/935.py.bak b/solutions/python3/bak/935.py.bak new file mode 100644 index 0000000..d79ae06 --- /dev/null +++ b/solutions/python3/bak/935.py.bak @@ -0,0 +1,10 @@ +class Solution: + def knightDialer(self, N): + x1 = x2 = x3 = x4 = x5 = x6 = x7 = x8 = x9 = x0 = 1 + for _ in range(N - 1): + x1, x2, x3, x4, x5, x6, x7, x8, x9, x0 = \u005C + x6 + x8, x7 + x9, x4 + x8, \u005C + x7 + x9 + x0, 0, x1 + x7 + x0, \u005C + x2 + x6, x1 + x7, x2 + x4, \u005C + x4 + x6 + return (x1 + x2 + x3 + x4 + x5 + x6 + x7 + x8 + x9 + x0) % (10 ** 9 + 7) \ No newline at end of file diff --git a/solutions/python3/bak/936.py.bak b/solutions/python3/bak/936.py.bak new file mode 100644 index 0000000..d741276 --- /dev/null +++ b/solutions/python3/bak/936.py.bak @@ -0,0 +1,20 @@ +class Solution: + def movesToStamp(self, stamp, target): + def okay(s): + ret = False + for c1, c2 in zip(s, stamp): + if c1 == "*": continue + elif c1 != c2: return False + else: ret = True + return ret + t, move, mx, arr = "*" * len(target), 0, 10 * len(target), [] + while move < mx: + pre = move + for i in range(len(target) - len(stamp) + 1): + if okay(target[i:i + len(stamp)]): + move += 1 + arr = [i] + arr + target = target[:i] + "*" * len(stamp) + target[i + len(stamp):] + if target == t: return arr + if move == pre: break + return [] \ No newline at end of file diff --git a/solutions/python3/bak/937.py.bak b/solutions/python3/bak/937.py.bak new file mode 100644 index 0000000..eab2539 --- /dev/null +++ b/solutions/python3/bak/937.py.bak @@ -0,0 +1,3 @@ +class Solution: + def reorderLogFiles(self, logs): + return sorted(filter(lambda l: l[l.find(" ") + 1].isalpha(), logs), key = lambda x: (x[x.find(" "):], x[:x.find(" ")])) + list(filter(lambda l: l[l.find(" ") + 1].isdigit(), logs)) \ No newline at end of file diff --git a/solutions/python3/bak/938.py.bak b/solutions/python3/bak/938.py.bak new file mode 100644 index 0000000..139dc35 --- /dev/null +++ b/solutions/python3/bak/938.py.bak @@ -0,0 +1,6 @@ +class Solution: + def rangeSumBST(self, root, L, R): + if not root: return 0 + l = self.rangeSumBST(root.left, L, R) + r = self.rangeSumBST(root.right, L, R) + return l + r + (L <= root.val <= R) * root.val \ No newline at end of file diff --git a/solutions/python3/bak/939.py.bak b/solutions/python3/bak/939.py.bak new file mode 100644 index 0000000..c47ee74 --- /dev/null +++ b/solutions/python3/bak/939.py.bak @@ -0,0 +1,12 @@ +class Solution: + def minAreaRect(self, points): + seen, bases, baseX, res = collections.defaultdict(dict), [], -1, float("inf") + for x, y in sorted(points): + if x != baseX: + baseX, bases = x, [] + for base in bases: + if y in seen[base]: + res = min(res, (x - seen[base][y]) * (y - base)) + seen[base][y] = x + bases.append(y) + return res if res < float("inf") else 0 \ No newline at end of file diff --git a/solutions/python3/bak/94.py.bak b/solutions/python3/bak/94.py.bak new file mode 100644 index 0000000..9220d53 --- /dev/null +++ b/solutions/python3/bak/94.py.bak @@ -0,0 +1,17 @@ +# Definition for a binary tree node. +# class TreeNode: +# def __init__(self, x): +# self.val = x +# self.left = None +# self.right = None + +class Solution: + def inorderTraversal(self, root: TreeNode) -> List[int]: + self.res = [] + def dfs(node): + if not node: return + dfs(node.left) + self.res.append(node.val) + dfs(node.right) + dfs(root) + return self.res \ No newline at end of file diff --git a/solutions/python3/bak/940.py.bak b/solutions/python3/bak/940.py.bak new file mode 100644 index 0000000..7bf2119 --- /dev/null +++ b/solutions/python3/bak/940.py.bak @@ -0,0 +1,6 @@ +class Solution: + def distinctSubseqII(self, S): + res, end = 0, collections.Counter() + for c in S: + res, end[c] = res * 2 + 1 - end[c], res + 1 + return res % (10**9 + 7) \ No newline at end of file diff --git a/solutions/python3/bak/941.py.bak b/solutions/python3/bak/941.py.bak new file mode 100644 index 0000000..4ea2cc9 --- /dev/null +++ b/solutions/python3/bak/941.py.bak @@ -0,0 +1,4 @@ +class Solution: + def validMountainArray(self, A): + i = A and A.index(max(A)) + return A and 0a3 for a2,a3 in zip(A[i:],A[i+1:])) or False \ No newline at end of file diff --git a/solutions/python3/bak/942.py.bak b/solutions/python3/bak/942.py.bak new file mode 100644 index 0000000..7448d87 --- /dev/null +++ b/solutions/python3/bak/942.py.bak @@ -0,0 +1,7 @@ +class Solution: + def diStringMatch(self, S): + l, r, arr = 0, len(S), [] + for s in S: + arr.append(l if s == "I" else r) + l, r = l + (s == "I"), r - (s == "D") + return arr + [l] \ No newline at end of file diff --git a/solutions/python3/bak/943.py.bak b/solutions/python3/bak/943.py.bak new file mode 100644 index 0000000..a552d1a --- /dev/null +++ b/solutions/python3/bak/943.py.bak @@ -0,0 +1,31 @@ +class Solution: + def shortestSuperstring(self, A): + def merge(a, b): + for i in range(len(b), 0, -1): + if a.endswith(b[:i]): + return i + return 0 + def dfs(sup, s, st): + if len(sup + "".join(st)) < len(res[0]): + res[0] = sup + "".join(st) + if st and any(new in st for new in merged[s][1:]): + for new in merged[s][1:]: + if new in st: + dfs(sup + new[merged[s][0]:], new, st - {new}) + else: + for nex in st: + for new in merged[nex][1:]: + if new in st: + dfs(sup + nex + new[merged[nex][0]:], new, st - {nex, new}) + merged = {} + for a, b in itertools.combinations(A, 2): + for a, b in ((a, b), (b, a)): + s = merge(a, b) + if a not in merged or s > merged[a][0]: + merged[a] = [s, b] + elif s == merged[a][0]: + merged[a].append(b) + res, st = ["".join(A)], set(A) + for a in A: + dfs(a, a, st - {a}) + return res[0] \ No newline at end of file diff --git a/solutions/python3/bak/944.py.bak b/solutions/python3/bak/944.py.bak new file mode 100644 index 0000000..bd687a8 --- /dev/null +++ b/solutions/python3/bak/944.py.bak @@ -0,0 +1,3 @@ +class Solution: + def minDeletionSize(self, A): + return sum(any(a[j] > b[j] for a, b in zip(A, A[1:])) for j in range(len(A[0]))) \ No newline at end of file diff --git a/solutions/python3/bak/945.py.bak b/solutions/python3/bak/945.py.bak new file mode 100644 index 0000000..637e3f3 --- /dev/null +++ b/solutions/python3/bak/945.py.bak @@ -0,0 +1,15 @@ +class Solution: + def minIncrementForUnique(self, A): + st, used, move = set(A), set(), 0 + heapq.heapify(A) + empty = [i for i in range(80000) if i not in st][::-1] if A else [] + while A: + num = heapq.heappop(A) + if num not in used: + used.add(num) + else: + while empty[-1] < num: + empty.pop() + move += empty[-1] - num + heapq.heappush(A, empty.pop()) + return move \ No newline at end of file diff --git a/solutions/python3/bak/946.py.bak b/solutions/python3/bak/946.py.bak new file mode 100644 index 0000000..08e5a7f --- /dev/null +++ b/solutions/python3/bak/946.py.bak @@ -0,0 +1,14 @@ +class Solution: + def validateStackSequences(self, pushed, popped): + """ + :type pushed: List[int] + :type popped: List[int] + :rtype: bool + """ + arr, i = [], 0 + for num in pushed: + arr.append(num) + while arr and arr[-1] == popped[i]: + i += 1 + arr.pop() + return arr == popped[i:][::-1] \ No newline at end of file diff --git a/solutions/python3/bak/947.py.bak b/solutions/python3/bak/947.py.bak new file mode 100644 index 0000000..258a934 --- /dev/null +++ b/solutions/python3/bak/947.py.bak @@ -0,0 +1,19 @@ +class Solution: + def removeStones(self, stones): + def dfs(i, j): + points.discard((i, j)) + for y in rows[i]: + if (i, y) in points: + dfs(i, y) + for x in cols[j]: + if (x, j) in points: + dfs(x, j) + points, island, rows, cols = {(i, j) for i, j in stones}, 0, collections.defaultdict(list), collections.defaultdict(list) + for i, j in stones: + rows[i].append(j) + cols[j].append(i) + for i, j in stones: + if (i, j) in points: + dfs(i, j) + island += 1 + return len(stones) - island \ No newline at end of file diff --git a/solutions/python3/bak/948.py.bak b/solutions/python3/bak/948.py.bak new file mode 100644 index 0000000..0de5a9b --- /dev/null +++ b/solutions/python3/bak/948.py.bak @@ -0,0 +1,21 @@ +class Solution: + def bagOfTokensScore(self, tokens, P): + """ + :type tokens: List[int] + :type P: int + :rtype: int + """ + tokens.sort() + l, r, score = 0, len(tokens) - 1, 0 + while l <= r: + if P >= tokens[l]: + P -= tokens[l] + score += 1 + l += 1 + elif score and l != r: + P += tokens[r] + score -= 1 + r -= 1 + else: + break + return score \ No newline at end of file diff --git a/solutions/python3/bak/949.py.bak b/solutions/python3/bak/949.py.bak new file mode 100644 index 0000000..833007d --- /dev/null +++ b/solutions/python3/bak/949.py.bak @@ -0,0 +1,10 @@ +class Solution: + def largestTimeFromDigits(self, A): + h = m = -float("inf") + for n1, n2, n3, n4 in itertools.permutations(A): + hh, mm = n1 * 10 + n2, n3 * 10 + n4 + if 0 <= hh <= 23 and 0 <= mm <= 59 and (hh > h or hh == h and mm > m): + h, m = hh, mm + sh = str(h) if h > 9 else "0" + str(h) + sm = str(m) if m > 9 else "0" + str(m) + return 0 <= h <= 23 and 0 <= m <= 59 and sh + ":" + sm or "" \ No newline at end of file diff --git a/solutions/python3/bak/95.py.bak b/solutions/python3/bak/95.py.bak new file mode 100644 index 0000000..f8f11bd --- /dev/null +++ b/solutions/python3/bak/95.py.bak @@ -0,0 +1,24 @@ +# Definition for a binary tree node. +# class TreeNode: +# def __init__(self, x): +# self.val = x +# self.left = None +# self.right = None + +class Solution: + def generateTrees(self, n: int) -> List[TreeNode]: + def dfs(l, r): + if r < l: return [None] + arr = [] + for m in range(l, r + 1): + left = dfs(l, m - 1) + right = dfs(m + 1, r) + for lNode in left: + for rNode in right: + new = TreeNode(m) + new.left = lNode + new.right = rNode + arr.append(new) + return arr + res = dfs(1, n) + return [] if res == [None] else res \ No newline at end of file diff --git a/solutions/python3/bak/950.py.bak b/solutions/python3/bak/950.py.bak new file mode 100644 index 0000000..7d8db74 --- /dev/null +++ b/solutions/python3/bak/950.py.bak @@ -0,0 +1,7 @@ +class Solution: + def deckRevealedIncreasing(self, deck): + ind = list(range(len(deck))) + for num in sorted(deck): + deck[ind[0]] = num + ind = ind[2:] + [ind[1]] if len(ind) > 1 else [] + return deck \ No newline at end of file diff --git a/solutions/python3/bak/951.py.bak b/solutions/python3/bak/951.py.bak new file mode 100644 index 0000000..dec478f --- /dev/null +++ b/solutions/python3/bak/951.py.bak @@ -0,0 +1,6 @@ +class Solution: + def flipEquiv(self, root1, root2): + if not root1 or not root2: return root1 == root2 + if root1.left and root2.left and root1.left.val != root2.left.val or (not root1.left and root2.left) or (root1.left and not root2.left): + root1.left, root1.right = root1.right, root1.left + return root1.val == root2.val and self.flipEquiv(root1.left, root2.left) and self.flipEquiv(root1.right, root2.right) \ No newline at end of file diff --git a/solutions/python3/bak/952.py.bak b/solutions/python3/bak/952.py.bak new file mode 100644 index 0000000..3324614 --- /dev/null +++ b/solutions/python3/bak/952.py.bak @@ -0,0 +1,26 @@ +class Solution: + def largestComponentSize(self, A): + def find(i): + return i if i == parent[i] else find(parent[i]) + + def prime_factors(n): + res = set() + while n % 2 == 0: + res.add(2) + n //= 2 + for i in range(3, int(n**0.5) + 1, 2): + while n % i== 0: + res.add(i) + n //= i + if n > 2: + res.add(n) + return res + parent, dic = list(range(len(A))), {} + for i, n in enumerate(A): + for p in prime_factors(n): + if p in dic: + parent[find(i)] = find(dic[p]) + dic[p] = i + for i, x in enumerate(parent): + parent[i] = find(x) + return max(collections.Counter(parent).values()) \ No newline at end of file diff --git a/solutions/python3/bak/953.py.bak b/solutions/python3/bak/953.py.bak new file mode 100644 index 0000000..09698cc --- /dev/null +++ b/solutions/python3/bak/953.py.bak @@ -0,0 +1,19 @@ +class Solution: + def isAlienSorted(self, words, order): + """ + :type words: List[str] + :type order: str + :rtype: bool + """ + ind = {c: i for i, c in enumerate(order)} + for a, b in zip(words, words[1:]): + if len(a) > len(b) and a[:len(b)] == b: + return False + for s1, s2 in zip(a, b): + if ind[s1] < ind[s2]: + break + elif ind[s1] == ind[s2]: + continue + else: + return False + return True \ No newline at end of file diff --git a/solutions/python3/bak/954.py.bak b/solutions/python3/bak/954.py.bak new file mode 100644 index 0000000..46d3741 --- /dev/null +++ b/solutions/python3/bak/954.py.bak @@ -0,0 +1,11 @@ +class Solution: + def canReorderDoubled(self, A): + cnt = collections.Counter(A) + for a in sorted(A, key = abs): + if cnt[a] and cnt[a * 2]: + cnt[a] -= 1 + cnt[a * 2] -= 1 + elif cnt[a] and a % 2 == 0 and cnt[a // 2]: + cnt[a] -= 1 + cnt[a // 2] -= 1 + return all(cnt[a] == 0 for a in A) \ No newline at end of file diff --git a/solutions/python3/bak/955.py.bak b/solutions/python3/bak/955.py.bak new file mode 100644 index 0000000..53e2e93 --- /dev/null +++ b/solutions/python3/bak/955.py.bak @@ -0,0 +1,11 @@ +class Solution: + def minDeletionSize(self, A): + res = 0 + cur = [""] * len(A) + for col in zip(*A): + cur2 = list(zip(cur, col)) + if cur2 == sorted(cur2): + cur = cur2 + else: + res += 1 + return res \ No newline at end of file diff --git a/solutions/python3/bak/956.py.bak b/solutions/python3/bak/956.py.bak new file mode 100644 index 0000000..57fc69d --- /dev/null +++ b/solutions/python3/bak/956.py.bak @@ -0,0 +1,8 @@ +class Solution: + def tallestBillboard(self, rods): + dp = {0: 0} + for x in rods: + for d, h in list(dp.items()): + dp[d + x] = max(dp.get(x + d, 0), h) + dp[abs(d - x)] = max(dp.get(abs(d - x), 0), h + min(d, x)) + return dp[0] \ No newline at end of file diff --git a/solutions/python3/bak/957.py.bak b/solutions/python3/bak/957.py.bak new file mode 100644 index 0000000..e3cb285 --- /dev/null +++ b/solutions/python3/bak/957.py.bak @@ -0,0 +1,11 @@ +class Solution: + def prisonAfterNDays(self, cells, N): + day, state, cur = 0, {}, "".join(map(str, cells)) + while cur not in state: + state[cur] = day + state[day] = cur + if day == N: + return list(map(int, cur)) + day += 1 + cur = "0" + "".join(cur[i - 1] == cur[i + 1] and "1" or "0" for i in range(1, len(cur) - 1)) + "0" + return list(map(int, state[state[cur] + (N - state[cur]) % (day - state[cur])])) \ No newline at end of file diff --git a/solutions/python3/bak/958.py.bak b/solutions/python3/bak/958.py.bak new file mode 100644 index 0000000..6adbf93 --- /dev/null +++ b/solutions/python3/bak/958.py.bak @@ -0,0 +1,10 @@ +class Solution: + def isCompleteTree(self, root): + q, pre = [root, None], 1 + while any(q): + i = q.index(None) + if any(q[i:]) or pre > 1: + return False + pre = len(q[i:]) + q = [child for node in q[:i] for child in (node.left, node.right)] + [None] + return True \ No newline at end of file diff --git a/solutions/python3/bak/959.py.bak b/solutions/python3/bak/959.py.bak new file mode 100644 index 0000000..d3917cd --- /dev/null +++ b/solutions/python3/bak/959.py.bak @@ -0,0 +1,37 @@ +class Solution: + def regionsBySlashes(self, grid): + def dfs(i, j, k): + if 0 <= i < n > j >= 0 and not matrix[i][j][k]: + if grid[i][j] == "*": + if k <= 1: + matrix[i][j][0] = matrix[i][j][1] = cnt + dfs(i - 1, j, 2) + dfs(i, j + 1, 3) + else: + matrix[i][j][2] = matrix[i][j][3] = cnt + dfs(i + 1, j, 0) + dfs(i, j - 1, 1) + elif grid[i][j] == "/": + if 1 <= k <= 2: + matrix[i][j][1] = matrix[i][j][2] = cnt + dfs(i, j + 1, 3) + dfs(i + 1, j, 0) + else: + matrix[i][j][0] = matrix[i][j][3] = cnt + dfs(i - 1, j, 2) + dfs(i, j - 1, 1) + else: + matrix[i][j][0] = matrix[i][j][1] = matrix[i][j][2] = matrix[i][j][3] = cnt + dfs(i - 1, j, 2) + dfs(i, j + 1, 3) + dfs(i + 1, j, 0) + dfs(i, j - 1, 1) + grid, n = [row.replace("\u005C\u005C", "*") for row in grid], len(grid) + matrix, cnt = [[[0, 0, 0, 0] for j in range(n)] for i in range(n)], 0 + for i in range(n): + for j in range(n): + for k in range(4): + if not matrix[i][j][k]: + cnt += 1 + dfs(i, j, k) + return cnt \ No newline at end of file diff --git a/solutions/python3/bak/96.py.bak b/solutions/python3/bak/96.py.bak new file mode 100644 index 0000000..7ee3bb8 --- /dev/null +++ b/solutions/python3/bak/96.py.bak @@ -0,0 +1,10 @@ +class Solution: + def numTrees(self, n): + if n <= 1: + return 1 + catalan = [0] * (n + 1) + catalan[0] = catalan[1] = 1 + for i in range(2, n + 1): + for j in range(i): + catalan[i] += catalan[j] * catalan[i - j - 1] + return catalan[n] \ No newline at end of file diff --git a/solutions/python3/bak/960.py.bak b/solutions/python3/bak/960.py.bak new file mode 100644 index 0000000..32821b6 --- /dev/null +++ b/solutions/python3/bak/960.py.bak @@ -0,0 +1,9 @@ +class Solution: + def minDeletionSize(self, A): + m, n = len(A), len(A[0]) + dp = [1] * n + for j in range(1, n): + for i in range(j): + if all(A[k][i] <= A[k][j] for k in range(m)): + dp[j] = max(dp[j], dp[i] + 1) + return n - max(dp) \ No newline at end of file diff --git a/solutions/python3/bak/961.py.bak b/solutions/python3/bak/961.py.bak new file mode 100644 index 0000000..9f57660 --- /dev/null +++ b/solutions/python3/bak/961.py.bak @@ -0,0 +1,7 @@ +class Solution: + def repeatedNTimes(self, A): + """ + :type A: List[int] + :rtype: int + """ + return collections.Counter(A).most_common(1)[0][0] \ No newline at end of file diff --git a/solutions/python3/bak/962.py.bak b/solutions/python3/bak/962.py.bak new file mode 100644 index 0000000..da37e95 --- /dev/null +++ b/solutions/python3/bak/962.py.bak @@ -0,0 +1,14 @@ +class Solution: + def maxWidthRamp(self, A): + """ + :type A: List[int] + :rtype: int + """ + ind, mx, index = float("inf"), 0, collections.defaultdict(list) + for i, num in enumerate(A): + index[num].append(i) + A.sort() + for i in range(len(A)): + mx = max(mx, index[A[i]][-1] - ind) + ind = min(ind, index[A[i]][0]) + return mx \ No newline at end of file diff --git a/solutions/python3/bak/963.py.bak b/solutions/python3/bak/963.py.bak new file mode 100644 index 0000000..0fd5744 --- /dev/null +++ b/solutions/python3/bak/963.py.bak @@ -0,0 +1,13 @@ + +class Solution: + def minAreaFreeRect(self, points): + mn, st, n = float('inf'), {(x, y) for x, y in points}, len(points) + for i in range(n): + x1, y1 = points[i] + for j in range(i + 1, n): + x2, y2 = points[j] + for k in range(j + 1, n): + x3, y3 = points[k] + if not (x3 - x1) * (x2 - x1) + (y3 - y1) * (y2 - y1) and (x3 + (x2 - x1), y3 + (y2 - y1)) in st: + mn = min(mn, ((x2 - x1) ** 2 + (y2 - y1) ** 2) ** 0.5 * ((x3 - x1) ** 2 + (y3 - y1) ** 2) ** 0.5) + return mn if mn < float("inf") else 0 \ No newline at end of file diff --git a/solutions/python3/bak/964.py.bak b/solutions/python3/bak/964.py.bak new file mode 100644 index 0000000..2ded97a --- /dev/null +++ b/solutions/python3/bak/964.py.bak @@ -0,0 +1,11 @@ +class Solution: + def leastOpsExpressTarget(self, x: int, y: int) -> int: + pos = neg = k = 0 + while y: + y, cur = divmod(y, x) + if k: + pos, neg = min(cur * k + pos, (cur + 1) * k + neg), min((x - cur) * k + pos, (x - cur - 1) * k + neg) + else: + pos, neg = cur * 2, (x - cur) * 2 + k += 1 + return min(pos, k + neg) - 1 \ No newline at end of file diff --git a/solutions/python3/bak/965.py.bak b/solutions/python3/bak/965.py.bak new file mode 100644 index 0000000..8b3ef9e --- /dev/null +++ b/solutions/python3/bak/965.py.bak @@ -0,0 +1,17 @@ +# Definition for a binary tree node. +# class TreeNode: +# def __init__(self, x): +# self.val = x +# self.left = None +# self.right = None + +class Solution: + def isUnivalTree(self, root): + """ + :type root: TreeNode + :rtype: bool + """ + if not root: return True + if root.left and root.left.val != root.val: return False + if root.right and root.right.val != root.val: return False + return self.isUnivalTree(root.left) and self.isUnivalTree(root.right) \ No newline at end of file diff --git a/solutions/python3/bak/966.py.bak b/solutions/python3/bak/966.py.bak new file mode 100644 index 0000000..5a41a8b --- /dev/null +++ b/solutions/python3/bak/966.py.bak @@ -0,0 +1,27 @@ +class Solution: + def spellchecker(self, wordlist, queries): + """ + :type wordlist: List[str] + :type queries: List[str] + :rtype: List[str] + """ + st, cap, vow = set(wordlist), {}, {} + for w in wordlist: + newC = w.lower() + newW = "".join(c if c not in "aeiou" else "*" for c in newC) + if newC not in cap: + cap[newC] = w + if newW not in vow: + vow[newW] = w + for i, w in enumerate(queries): + if w in st: + pass + elif w.lower() in cap: + queries[i] = cap[w.lower()] + else: + new = "".join(c if c not in "aeiou" else "*" for c in w.lower()) + if new in vow: + queries[i] = vow[new] + else: + queries[i] = "" + return queries \ No newline at end of file diff --git a/solutions/python3/bak/967.py.bak b/solutions/python3/bak/967.py.bak new file mode 100644 index 0000000..779f079 --- /dev/null +++ b/solutions/python3/bak/967.py.bak @@ -0,0 +1,18 @@ +class Solution: + def numsSameConsecDiff(self, N, K): + """ + :type N: int + :type K: int + :rtype: List[int] + """ + q = {i for i in range(10)} + for _ in range(N - 1): + new = set() + for num in q: + last = num % 10 + if num and 0 <= last + K <= 9: + new.add(num * 10 + last + K) + if num and 0 <= last - K <= 9: + new.add(num * 10 + last - K) + q = new + return list(q) \ No newline at end of file diff --git a/solutions/python3/bak/968.py.bak b/solutions/python3/bak/968.py.bak new file mode 100644 index 0000000..496b507 --- /dev/null +++ b/solutions/python3/bak/968.py.bak @@ -0,0 +1,14 @@ +class Solution: + res = 0 + def minCameraCover(self, root): + def dfs(root): + if not root: return 2 + if not root.left and not root.right: return 0 + l, r = dfs(root.left), dfs(root.right) + if l == 0 or r == 0: + self.res += 1 + return 1 + if l == 1 or r == 1: + return 2 + return 0 + return (dfs(root) == 0) + self.res \ No newline at end of file diff --git a/solutions/python3/bak/969.py.bak b/solutions/python3/bak/969.py.bak new file mode 100644 index 0000000..1333e6f --- /dev/null +++ b/solutions/python3/bak/969.py.bak @@ -0,0 +1,8 @@ +class Solution: + def pancakeSort(self, A): + res = [] + for x in range(len(A), 1, -1): + i = A.index(x) + res.extend([i + 1, x]) + A = A[:i:-1] + A[:i] + return res \ No newline at end of file diff --git a/solutions/python3/bak/97.py.bak b/solutions/python3/bak/97.py.bak new file mode 100644 index 0000000..767bb90 --- /dev/null +++ b/solutions/python3/bak/97.py.bak @@ -0,0 +1,9 @@ +class Solution: + def isInterleave(self, s1, s2, s3): + def dfs(i, j, k): + if (i, j, k) not in memo: + memo[(i, j, k)] = k>=l3 or (i= 0: + s = s[:i] + s[i + 1:-1] * 20 + return float(s[:20]) + return f(S) == f(T) \ No newline at end of file diff --git a/solutions/python3/bak/973.py.bak b/solutions/python3/bak/973.py.bak new file mode 100644 index 0000000..bee0cd6 --- /dev/null +++ b/solutions/python3/bak/973.py.bak @@ -0,0 +1,3 @@ +class Solution: + def kClosest(self, points, K): + return sorted(points, key = lambda p: p[0] ** 2 + p[1] ** 2)[:K] \ No newline at end of file diff --git a/solutions/python3/bak/974.py.bak b/solutions/python3/bak/974.py.bak new file mode 100644 index 0000000..9f37bae --- /dev/null +++ b/solutions/python3/bak/974.py.bak @@ -0,0 +1,10 @@ +class Solution: + def subarraysDivByK(self, A: List[int], K: int) -> int: + res = sm = 0 + sums = collections.defaultdict(int) + sums[0] = 1 + for a in A: + sm = (sm + a) % K + sums[sm] += 1 + res += sums[sm] - 1 + return res \ No newline at end of file diff --git a/solutions/python3/bak/975.py.bak b/solutions/python3/bak/975.py.bak new file mode 100644 index 0000000..20bf620 --- /dev/null +++ b/solutions/python3/bak/975.py.bak @@ -0,0 +1,24 @@ +class Solution: + def oddEvenJumps(self, A: List[int]) -> int: + n = len(A) + next_higher, next_lower = [0] * n, [0] * n + + stack = [] + for a, i in sorted([a, i] for i, a in enumerate(A)): + while stack and stack[-1] < i: + next_higher[stack.pop()] = i + stack.append(i) + + stack = [] + for a, i in sorted([-a, i] for i, a in enumerate(A)): + while stack and stack[-1] < i: + next_lower[stack.pop()] = i + stack.append(i) + + higher, lower = [0] * n, [0] * n + higher[-1] = lower[-1] = 1 + for i in range(n - 1)[::-1]: + higher[i] = lower[next_higher[i]] + lower[i] = higher[next_lower[i]] + return sum(higher) + \ No newline at end of file diff --git a/solutions/python3/bak/976.py.bak b/solutions/python3/bak/976.py.bak new file mode 100644 index 0000000..dfc2017 --- /dev/null +++ b/solutions/python3/bak/976.py.bak @@ -0,0 +1,8 @@ +class Solution: + def largestPerimeter(self, A): + """ + :type A: List[int] + :rtype: int + """ + A.sort() + return ([0] + [a + b + c for a, b, c in zip(A, A[1:], A[2:]) if c < a + b])[-1] \ No newline at end of file diff --git a/solutions/python3/bak/977.py.bak b/solutions/python3/bak/977.py.bak new file mode 100644 index 0000000..205cec2 --- /dev/null +++ b/solutions/python3/bak/977.py.bak @@ -0,0 +1,7 @@ +class Solution: + def sortedSquares(self, A): + """ + :type A: List[int] + :rtype: List[int] + """ + return sorted([x ** 2 for x in A]) \ No newline at end of file diff --git a/solutions/python3/bak/978.py.bak b/solutions/python3/bak/978.py.bak new file mode 100644 index 0000000..6ecf775 --- /dev/null +++ b/solutions/python3/bak/978.py.bak @@ -0,0 +1,11 @@ +class Solution: + def maxTurbulenceSize(self, A): + arr = [A[i - 1] < A[i] for i in range(1, len(A))] + cur = mx = 1 + (len(A) > 1) + for i in range(1, len(arr)): + if A[i] != A[i + 1] and arr[i] != arr[i - 1]: + cur += 1 + mx = max(cur, mx) + else: + cur = 2 + return mx \ No newline at end of file diff --git a/solutions/python3/bak/979.py.bak b/solutions/python3/bak/979.py.bak new file mode 100644 index 0000000..fe0ccad --- /dev/null +++ b/solutions/python3/bak/979.py.bak @@ -0,0 +1,12 @@ +class Solution: + def distributeCoins(self, root): + self.ans = 0 + + def dfs(node): + if not node: return 0 + L, R = dfs(node.left), dfs(node.right) + self.ans += abs(L) + abs(R) + return node.val + L + R - 1 + + dfs(root) + return self.ans \ No newline at end of file diff --git a/solutions/python3/bak/98.py.bak b/solutions/python3/bak/98.py.bak new file mode 100644 index 0000000..2e60f07 --- /dev/null +++ b/solutions/python3/bak/98.py.bak @@ -0,0 +1,18 @@ +# Definition for a binary tree node. +# class TreeNode: +# def __init__(self, x): +# self.val = x +# self.left = None +# self.right = None + +class Solution: + def isValidBST(self, root): + """ + :type root: TreeNode + :rtype: bool + """ + def validate(node, mn, mx): + if not node: return True + if node.valmx: return False + return validate(node.left,mn,node.val-1) and validate(node.right,node.val+1,mx) + return validate(root, -float("inf"),float("inf")) \ No newline at end of file diff --git a/solutions/python3/bak/980.py.bak b/solutions/python3/bak/980.py.bak new file mode 100644 index 0000000..033013f --- /dev/null +++ b/solutions/python3/bak/980.py.bak @@ -0,0 +1,20 @@ +class Solution: + def uniquePathsIII(self, grid: List[List[int]]) -> int: + def dfs(i, j, visited): + if grid[i][j] == 2: + self.walks += visited == self.visit + return + for x, y in ((i - 1, j), (i + 1, j), (i, j - 1), (i, j + 1)): + if 0 <= x < m and 0 <= y < n and grid[x][y] != -1: + grid[i][j] -= 1 + dfs(x, y, visited + 1) + grid[i][j] += 1 + m, n = len(grid), len(grid[0]) + self.visit = m * n - sum(c == -1 for row in grid for c in row) + self.walks = 0 + for i in range(m): + for j in range(n): + if grid[i][j] == 1: + grid[i][j] -= 1 + dfs(i, j, 1) + return self.walks \ No newline at end of file diff --git a/solutions/python3/bak/981.py.bak b/solutions/python3/bak/981.py.bak new file mode 100644 index 0000000..f13729c --- /dev/null +++ b/solutions/python3/bak/981.py.bak @@ -0,0 +1,13 @@ +class TimeMap: + + def __init__(self): + self.times = collections.defaultdict(list) + self.values = collections.defaultdict(list) + + def set(self, key: str, value: str, timestamp: int) -> None: + self.times[key].append(timestamp) + self.values[key].append(value) + + def get(self, key: str, timestamp: int) -> str: + i = bisect.bisect(self.times[key], timestamp) + return self.values[key][i - 1] if i else '' diff --git a/solutions/python3/bak/982.py.bak b/solutions/python3/bak/982.py.bak new file mode 100644 index 0000000..852cc88 --- /dev/null +++ b/solutions/python3/bak/982.py.bak @@ -0,0 +1,4 @@ +class Solution: + def countTriplets(self, A: List[int]) -> int: + cnt = collections.Counter([a & b for a in A for b in A]) + return sum(cnt[k] for a in A for k in cnt if not a & k) \ No newline at end of file diff --git a/solutions/python3/bak/983.py.bak b/solutions/python3/bak/983.py.bak new file mode 100644 index 0000000..88cb2c0 --- /dev/null +++ b/solutions/python3/bak/983.py.bak @@ -0,0 +1,9 @@ +class Solution: + def mincostTickets(self, days: List[int], costs: List[int]) -> int: + day, days, last = [0] * 366, set(days), days[-1] + for i in range(1, last + 1): + if i not in days: + day[i] = day[i - 1] + else: + day[i] = min(day[i - 1] + costs[0], day[i - 7 if i>= 7 else 0] + costs[1], day[i - 30 if i >= 30 else 0] + costs[2]) + return day[last] \ No newline at end of file diff --git a/solutions/python3/bak/984.py.bak b/solutions/python3/bak/984.py.bak new file mode 100644 index 0000000..090d185 --- /dev/null +++ b/solutions/python3/bak/984.py.bak @@ -0,0 +1,12 @@ +class Solution: + def strWithout3a3b(self, A: int, B: int) -> str: + if not A and not B: return '' + if A >= B: + a = 2 if A >= 2 else 1 + b = 2 if A - a - B < 1 and B >= 2 else 1 if B else 0 + return a * 'a' + b * 'b' + self.strWithout3a3b(A - a, B - b) + else: + b = 2 if B >= 2 else 1 + a = 2 if B - b - A < 1 and A >= 2 else 1 if A else 0 + return b * 'b' + a * 'a' + self.strWithout3a3b(A - a, B - b) + \ No newline at end of file diff --git a/solutions/python3/bak/985.py.bak b/solutions/python3/bak/985.py.bak new file mode 100644 index 0000000..dbd8999 --- /dev/null +++ b/solutions/python3/bak/985.py.bak @@ -0,0 +1,10 @@ +class Solution: + def sumEvenAfterQueries(self, A: List[int], queries: List[List[int]]) -> List[int]: + sm = sum(a for a in A if a % 2 == 0) + for i in range(len(queries)): + val, ind = queries[i] + sm -= A[ind] % 2 == 0 and A[ind] + A[ind] += val + sm += A[ind] % 2 == 0 and A[ind] + queries[i] = sm + return queries \ No newline at end of file diff --git a/solutions/python3/bak/986.py.bak b/solutions/python3/bak/986.py.bak new file mode 100644 index 0000000..72202a5 --- /dev/null +++ b/solutions/python3/bak/986.py.bak @@ -0,0 +1,17 @@ +class Solution: + def intervalIntersection(self, A: List[Interval], B: List[Interval]) -> List[Interval]: + i = j = 0 + res = [] + while i < len(A) and j < len(B): + s = max(A[i].start, B[j].start) + e = min(A[i].end, B[j].end) + if s <= e: + res.append(Interval(s, e)) + if A[i].end < B[j].end: + i += 1 + elif A[i].end == B[j].end: + i += 1 + j += 1 + else: + j += 1 + return res \ No newline at end of file diff --git a/solutions/python3/bak/987.py.bak b/solutions/python3/bak/987.py.bak new file mode 100644 index 0000000..99fa263 --- /dev/null +++ b/solutions/python3/bak/987.py.bak @@ -0,0 +1,10 @@ +class Solution: + def verticalTraversal(self, root: TreeNode) -> List[List[int]]: + self.arr = [] + def dfs(node, x, y): + if node: + self.arr.append((x, y, node.val)) + dfs(node.left, x - 1, y + 1) + dfs(node.right, x + 1, y + 1) + dfs(root, 0, 0) + return [list(map(lambda x: x[-1], g)) for k, g in itertools.groupby(sorted(self.arr), key = lambda x: x[0])] \ No newline at end of file diff --git a/solutions/python3/bak/988.py.bak b/solutions/python3/bak/988.py.bak new file mode 100644 index 0000000..352137d --- /dev/null +++ b/solutions/python3/bak/988.py.bak @@ -0,0 +1,9 @@ +class Solution: + def smallestFromLeaf(self, root: TreeNode, s = '') -> str: + if not root.right and not root.left: + return chr(97 + root.val) + s + if not root.right: + return self.smallestFromLeaf(root.left, chr(97 + root.val) + s) + if not root.left: + return self.smallestFromLeaf(root.right, chr(97 + root.val) + s) + return min(self.smallestFromLeaf(root.left, chr(97 + root.val) + s), self.smallestFromLeaf(root.right, chr(97 + root.val) + s)) \ No newline at end of file diff --git a/solutions/python3/bak/989.py.bak b/solutions/python3/bak/989.py.bak new file mode 100644 index 0000000..e09c23f --- /dev/null +++ b/solutions/python3/bak/989.py.bak @@ -0,0 +1,5 @@ +class Solution: + def addToArrayForm(self, A, K): + for i in range(len(A))[::-1]: + A[i], K = (A[i] + K) % 10, (A[i] + K) // 10 + return [int(i) for i in str(K)] + A if K else A \ No newline at end of file diff --git a/solutions/python3/bak/99.py.bak b/solutions/python3/bak/99.py.bak new file mode 100644 index 0000000..a21243d --- /dev/null +++ b/solutions/python3/bak/99.py.bak @@ -0,0 +1,17 @@ +class Solution: + def recoverTree(self, root): + def inorder(node): + if node.left: + yield from inorder(node.left) + yield node + if node.right: + yield from inorder(node.right) + swap1 = swap2 = smaller = None + for node in inorder(root): + if smaller and smaller.val > node.val: + if not swap1: + swap1 = smaller + swap2 = node + smaller = node + if swap1: + swap1.val, swap2.val = swap2.val, swap1.val \ No newline at end of file diff --git a/solutions/python3/bak/990.py.bak b/solutions/python3/bak/990.py.bak new file mode 100644 index 0000000..c5cd1e9 --- /dev/null +++ b/solutions/python3/bak/990.py.bak @@ -0,0 +1,12 @@ +class Solution: + def equationsPossible(self, equations: List[str]) -> bool: + def uf(c): + return uf(parent[ord(c) - ord('a')]) if parent[ord(c) - ord('a')] != c else ord(c) - ord('a') + parent = [c for c in string.ascii_lowercase] + for eq in equations: + if eq[1] == '=': + parent[uf(eq[0])] = parent[uf(eq[-1])] + for eq in equations: + if eq[1] == '!' and parent[uf(eq[0])] == parent[uf(eq[-1])]: + return False + return True \ No newline at end of file diff --git a/solutions/python3/bak/991.py.bak b/solutions/python3/bak/991.py.bak new file mode 100644 index 0000000..04761db --- /dev/null +++ b/solutions/python3/bak/991.py.bak @@ -0,0 +1,7 @@ +class Solution: + def brokenCalc(self, X, Y): + res = 0 + while X < Y: + res += Y % 2 + 1 + Y = (Y + 1) // 2 + return res + X - Y \ No newline at end of file diff --git a/solutions/python3/bak/993.py.bak b/solutions/python3/bak/993.py.bak new file mode 100644 index 0000000..d918d76 --- /dev/null +++ b/solutions/python3/bak/993.py.bak @@ -0,0 +1,9 @@ +class Solution: + def isCousins(self, root: TreeNode, x: int, y: int) -> bool: + def dfs(node, parent, depth, mod): + if node: + if node.val == mod: + return depth, parent + return dfs(node.left, node, depth + 1, mod) or dfs(node.right, node, depth + 1, mod) + dx, px, dy, py = dfs(root, None, 0, x) + dfs(root, None, 0, y) + return dx == dy and px != py \ No newline at end of file diff --git a/solutions/python3/bak/994.py.bak b/solutions/python3/bak/994.py.bak new file mode 100644 index 0000000..0ef9bb1 --- /dev/null +++ b/solutions/python3/bak/994.py.bak @@ -0,0 +1,13 @@ +class Solution: + def orangesRotting(self, grid: List[List[int]]) -> int: + bfs, t, m, n = [(i, j) for i, row in enumerate(grid) for j, val in enumerate(row) if val == 2], 0, len(grid), len(grid[0]) + while bfs: + new = [] + for i, j in bfs: + for x, y in ((i - 1, j), (i + 1, j), (i, j - 1), (i, j + 1)): + if 0 <= x < m and 0 <= y < n and grid[x][y] == 1: + grid[x][y] = 2 + new.append((x, y)) + bfs = new + t += bool(bfs) + return t if all(val != 1 for row in grid for val in row) else -1 \ No newline at end of file diff --git a/solutions/python3/bak/995.py.bak b/solutions/python3/bak/995.py.bak new file mode 100644 index 0000000..7f8871c --- /dev/null +++ b/solutions/python3/bak/995.py.bak @@ -0,0 +1,11 @@ +class Solution: + def minKBitFlips(self, a: List[int], k: int) -> int: + q = collections.deque() + res = 0 + for i in range(len(a)): + if len(q) % 2 != 0 and a[i] == 1 or len(q) % 2 == a[i] == 0: + res += 1 + q.append(i+k-1) + if q and q[0] == i: q.popleft() + if q and q[-1] >= len(a): return -1 + return res \ No newline at end of file diff --git a/solutions/python3/bak/996.py.bak b/solutions/python3/bak/996.py.bak new file mode 100644 index 0000000..54adee2 --- /dev/null +++ b/solutions/python3/bak/996.py.bak @@ -0,0 +1,27 @@ +class Solution: + def numSquarefulPerms(self, A: List[int]) -> int: + self.res = 0 + def dfs(cnt, num): + if not cnt: + self.res += 1 + for new in nex[num]: + if cnt[new]: + cnt[new] -= 1 + if not cnt[new]: + cnt.pop(new) + dfs(cnt, new) + cnt[new] += 1 + + nex = collections.defaultdict(set) + cnt = collections.Counter(A) + for a, b in itertools.permutations(A, 2): + if not (a + b) ** 0.5 % 1: + nex[a].add(b) + nex[b].add(a) + for a in set(A): + cnt[a] -= 1 + if not cnt[a]: + cnt.pop(a) + dfs(cnt, a) + cnt[a] += 1 + return self.res \ No newline at end of file diff --git a/solutions/python3/bak/997.py.bak b/solutions/python3/bak/997.py.bak new file mode 100644 index 0000000..c184f65 --- /dev/null +++ b/solutions/python3/bak/997.py.bak @@ -0,0 +1,4 @@ +class Solution: + def findJudge(self, N: int, trust: List[List[int]]) -> int: + j, cnt = collections.Counter(b for a, b in trust).most_common(1)[0] if trust else (N, 0) + return j if j not in {a for a, b in trust} and cnt == N - 1 else -1 \ No newline at end of file diff --git a/solutions/python3/bak/998.py.bak b/solutions/python3/bak/998.py.bak new file mode 100644 index 0000000..f9c4c1f --- /dev/null +++ b/solutions/python3/bak/998.py.bak @@ -0,0 +1,14 @@ +class Solution: + def insertIntoMaxTree(self, root: TreeNode, val: int, parent = None) -> TreeNode: + if not root or val > root.val: + new = TreeNode(val) + new.left = root + if parent: + if parent.right == root: + parent.right = new + else: + parent.left = new + root = new + else: + root.right = self.insertIntoMaxTree(root.right, val, root) + return root \ No newline at end of file diff --git a/solutions/python3/bak/999.py.bak b/solutions/python3/bak/999.py.bak new file mode 100644 index 0000000..83021a1 --- /dev/null +++ b/solutions/python3/bak/999.py.bak @@ -0,0 +1,22 @@ +class Solution: + def numRookCaptures(self, board: List[List[str]], res = 0) -> int: + for i in range(8): + for j in range(8): + if board[i][j] == 'R': + for x in range(i - 1, -1, -1): + if board[x][j] in 'Bp': + res += board[x][j] == 'p' + break + for x in range(i + 1, 8): + if board[x][j] in 'Bp': + res += board[x][j] == 'p' + break + for y in range(j - 1, -1, -1): + if board[i][y] in 'Bp': + res += board[i][y] == 'p' + break + for y in range(j + 1, 8): + if board[i][y] in 'Bp': + res += board[i][y] == 'p' + break + return res \ No newline at end of file diff --git a/solutions/python3/generate.py b/solutions/python3/generate.py new file mode 100644 index 0000000..34883af --- /dev/null +++ b/solutions/python3/generate.py @@ -0,0 +1,88 @@ +import os +import glob +from pathlib import Path +import requests +import time + +def process_code_with_ollama(code: str) -> str: + """ + 使用Ollama处理代码 + Using Ollama to process code + """ + prompt = """请对以下Python代码进行优化和双语注释改进: + 1. 添加清晰的中英文注释,一定要中英文双语注释 + 2. 适度优化代码结构和性能 + 3. 保持代码简洁易读 + 4. 不要改变主要逻辑 + 5. 要求只保留生成的代码部分,其他内容都作为文档注释保留 + 6. 也就是代码开头和结尾的三个之间的内容不要删除,其他的都不要保留 + 请输出代码和注释,不要输出其他内容!不要评价,不要总结,什么多余的都不要放。 + + 代码如下: + {}""".format(code) + + try: + response = requests.post('http://localhost:11434/api/generate', + json={ + "model": "qwen2.5:7b", + "prompt": prompt, + "stream": False + }) + return response.json()['response'] + except Exception as e: + print(f"处理出错 Error occurred: {e}") + return code + + + +def process_python_files(): + """ + 处理当前目录下所有Python文件 + Process all Python files in current directory + """ + python_files = glob.glob("*.py") + + for file_path in python_files: + if file_path == os.path.basename(__file__): + continue + + # 检查是否存在备份文件 + # Check if backup file exists + backup_path = f"{file_path}.bak" + if os.path.exists(backup_path): + print(f"跳过已处理文件 Skipping already processed file: {file_path}") + continue + + print(f"处理文件 Processing: {file_path}") + + try: + # 读取原始代码 + # Read original code + with open(file_path, 'r', encoding='utf-8') as f: + original_code = f.read() + + # 处理代码 + # Process code + improved_code = process_code_with_ollama(original_code) + + # 备份原文件 + # Backup original file + Path(file_path).rename(backup_path) + + # 写入优化后的代码 + # Write improved code + with open(file_path, 'w', encoding='utf-8') as f: + f.write(improved_code) + + print(f"完成处理 Completed: {file_path}") + + # 添加短暂延迟避免请求过快 + # Add short delay to avoid too frequent requests + time.sleep(1) + + except Exception as e: + print(f"处理文件 {file_path} 时出错 Error while processing: {e}") + +# ...existing code for if __name__ == "__main__"... +if __name__ == "__main__": + process_python_files() \ No newline at end of file