diff --git a/.gitignore b/.gitignore index 9f11b755..9893a05d 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,3 @@ +# vscode +.vscode/ .idea/ diff --git a/Week_02/id_36/LeetCode_101_36.py b/Week_02/id_36/LeetCode_101_36.py new file mode 100644 index 00000000..dd2b4cf4 --- /dev/null +++ b/Week_02/id_36/LeetCode_101_36.py @@ -0,0 +1,86 @@ +# +# @lc app=leetcode.cn id=101 lang=python3 +# +# [101] 对称二叉树 +# +# https://leetcode-cn.com/problems/symmetric-tree/description/ +# +# algorithms +# Easy (46.79%) +# Likes: 357 +# Dislikes: 0 +# Total Accepted: 36K +# Total Submissions: 77K +# Testcase Example: '[1,2,2,3,4,4,3]' +# +# 给定一个二叉树,检查它是否是镜像对称的。 +# +# 例如,二叉树 [1,2,2,3,4,4,3] 是对称的。 +# +# ⁠ 1 +# ⁠ / \ +# ⁠ 2 2 +# ⁠/ \ / \ +# 3 4 4 3 +# +# +# 但是下面这个 [1,2,2,null,3,null,3] 则不是镜像对称的: +# +# ⁠ 1 +# ⁠ / \ +# ⁠ 2 2 +# ⁠ \ \ +# ⁠ 3 3 +# +# +# 说明: +# +# 如果你可以运用递归和迭代两种方法解决这个问题,会很加分。 +# +# +# 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: TreeNode) -> bool: +# return self.isMirror(root, root) + +# def isMirror(self, root1: TreeNode, root2: TreeNode) -> bool: +# if root1 is None and root2 is None: +# return True +# if root1 is None or root2 is None: +# return False + +# return root1.val == root2.val and self.isMirror(root1.right, root2.left) and self.isMirror(root1.left, root2.right) + +# 迭代 +class Solution: + def isSymmetric(self, root: TreeNode) -> bool: + queue = [] + queue.append(root) + queue.append(root) + + while len(queue) > 0: + t1 = queue.pop() + t2 = queue.pop() + if t1 is None and t2 is None: + continue + if t1 is None or t2 is None: + return False + if t1.val != t2.val: + return False + + queue.append(t1.left) + queue.append(t2.right) + queue.append(t1.right) + queue.append(t2.left) + + return True + diff --git a/Week_02/id_36/LeetCode_111_36.py b/Week_02/id_36/LeetCode_111_36.py new file mode 100644 index 00000000..d822615b --- /dev/null +++ b/Week_02/id_36/LeetCode_111_36.py @@ -0,0 +1,73 @@ +# +# @lc app=leetcode.cn id=111 lang=python3 +# +# [111] 二叉树的最小深度 +# +# 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: TreeNode) -> int: +# if root is None: +# return 0 + +# if root.left is None and root.right is not None: +# return self.minDepth(root.right) + 1 +# elif root.left is not None and root.right is None: +# return self.minDepth(root.left) + 1 + +# return min(self.minDepth(root.left), self.minDepth(root.right)) + 1 + +# #深度优先搜索迭代 +# class Solution: +# def minDepth(self, root: TreeNode) -> int: +# if root is None: +# return 0 + +# stack = [] +# import sys +# stack.append((root, 1)) +# min_depth = sys.maxsize +# while len(stack) > 0: +# current = stack.pop() +# root = current[0] +# current_depth = current[1] +# if root.left is None and root.right is None: +# min_depth = min(min_depth, current_depth) +# if root.left is not None: +# stack.append((root.left, current_depth + 1)) +# if root.right is not None: +# stack.append((root.right, current_depth + 1)) + +# return min_depth + +#宽度优先搜索迭代 +class Solution: + def minDepth(self, root: TreeNode) -> int: + if root is None: + return 0 + + stack = [] + stack.append((root, 1)) + current_depth = 0 + while len(stack) > 0: + current = stack.pop() + root = current[0] + current_depth = current[1] + if root.left is None and root.right is None: + break + if root.left is not None: + stack.insert(0, (root.left, current_depth + 1)) + if root.right is not None: + stack.insert(0, (root.right, current_depth + 1)) + + return current_depth + diff --git a/Week_02/id_36/LeetCode_1_36.py b/Week_02/id_36/LeetCode_1_36.py new file mode 100644 index 00000000..787695c3 --- /dev/null +++ b/Week_02/id_36/LeetCode_1_36.py @@ -0,0 +1,62 @@ +# +# @lc app=leetcode.cn id=1 lang=python3 +# +# [1] 两数之和 +# +# https://leetcode-cn.com/problems/two-sum/description/ +# +# algorithms +# Easy (46.08%) +# Likes: 5365 +# Dislikes: 0 +# Total Accepted: 397.2K +# Total Submissions: 861.4K +# Testcase Example: '[2,7,11,15]\n9' +# +# 给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那 两个 整数,并返回他们的数组下标。 +# +# 你可以假设每种输入只会对应一个答案。但是,你不能重复利用这个数组中同样的元素。 +# +# 示例: +# +# 给定 nums = [2, 7, 11, 15], target = 9 +# +# 因为 nums[0] + nums[1] = 2 + 7 = 9 +# 所以返回 [0, 1] +# +# +# 暴力解法: +# class Solution: +# def twoSum(self, nums: List[int], target: int) -> List[int]: +# l = len(nums) +# for i in range(l): +# for j in range(i + 1, l): +# if nums[j] == target - nums[i]: +# return [i, j] +# return [] +# +# 两遍哈希表 +# class Solution: +# def twoSum(self, nums: List[int], target: int) -> List[int]: +# map = dict() +# l = len(nums) +# for i in range(l): +# map[nums[i]] = i +# for i in range(l): +# r = target - nums[i] +# if map.get(r, i) != i: +# return [i, map.get(r)] +# return [] +# +# 一遍哈希表 +class Solution: + def twoSum(self, nums: List[int], target: int) -> List[int]: + map = dict() + l = len(nums) + for i in range(l): + r = target - nums[i] + if map.get(r, i) != i: + return [map.get(r), i] + map[nums[i]] = i + return [] + diff --git a/Week_02/id_36/LeetCode_236_36.py b/Week_02/id_36/LeetCode_236_36.py new file mode 100644 index 00000000..6c8225ac --- /dev/null +++ b/Week_02/id_36/LeetCode_236_36.py @@ -0,0 +1,77 @@ +# +# @lc app=leetcode.cn id=236 lang=python3 +# +# [236] 二叉树的最近公共祖先 +# +# https://leetcode-cn.com/problems/lowest-common-ancestor-of-a-binary-tree/description/ +# +# algorithms +# Medium (55.09%) +# Likes: 183 +# Dislikes: 0 +# Total Accepted: 15K +# Total Submissions: 27.3K +# Testcase Example: '[3,5,1,6,2,0,8,null,null,7,4]\n5\n1' +# +# 给定一个二叉树, 找到该树中两个指定节点的最近公共祖先。 +# +# 百度百科中最近公共祖先的定义为:“对于有根树 T 的两个结点 p、q,最近公共祖先表示为一个结点 x,满足 x 是 p、q 的祖先且 x +# 的深度尽可能大(一个节点也可以是它自己的祖先)。” +# +# 例如,给定如下二叉树:  root = [3,5,1,6,2,0,8,null,null,7,4] +# +# +# +# +# +# 示例 1: +# +# 输入: root = [3,5,1,6,2,0,8,null,null,7,4], p = 5, q = 1 +# 输出: 3 +# 解释: 节点 5 和节点 1 的最近公共祖先是节点 3。 +# +# +# 示例 2: +# +# 输入: root = [3,5,1,6,2,0,8,null,null,7,4], p = 5, q = 4 +# 输出: 5 +# 解释: 节点 5 和节点 4 的最近公共祖先是节点 5。因为根据定义最近公共祖先节点可以为节点本身。 +# +# +# +# +# 说明: +# +# +# 所有节点的值都是唯一的。 +# p、q 为不同节点且均存在于给定的二叉树中。 +# +# +# +# Definition for a binary tree node. + + +class TreeNode: + def __init__(self, x): + self.val = x + self.left = None + self.right = None + + +class Solution: + def lowestCommonAncestor(self, root: 'TreeNode', p: 'TreeNode', q: 'TreeNode') -> 'TreeNode': + if root == p or root == q or root is None: + return root + + left = self.lowestCommonAncestor(root.left, p, q) + right = self.lowestCommonAncestor(root.right, p, q) + + if left is None and right is None: + return None + elif left is not None and right is None: + return left + elif left is None and right is not None: + return right + + return root + diff --git a/Week_02/id_36/LeetCode_3_36.py b/Week_02/id_36/LeetCode_3_36.py new file mode 100644 index 00000000..670c7668 --- /dev/null +++ b/Week_02/id_36/LeetCode_3_36.py @@ -0,0 +1,77 @@ +# +# @lc app=leetcode.cn id=3 lang=python3 +# +# [3] 无重复字符的最长子串 +# +# https://leetcode-cn.com/problems/longest-substring-without-repeating-characters/description/ +# +# algorithms +# Medium (29.74%) +# Likes: 1907 +# Dislikes: 0 +# Total Accepted: 136.6K +# Total Submissions: 457.9K +# Testcase Example: '"abcabcbb"' +# +# 给定一个字符串,请你找出其中不含有重复字符的 最长子串 的长度。 +# +# 示例 1: +# +# 输入: "abcabcbb" +# 输出: 3 +# 解释: 因为无重复字符的最长子串是 "abc",所以其长度为 3。 +# +# +# 示例 2: +# +# 输入: "bbbbb" +# 输出: 1 +# 解释: 因为无重复字符的最长子串是 "b",所以其长度为 1。 +# +# +# 示例 3: +# +# 输入: "pwwkew" +# 输出: 3 +# 解释: 因为无重复字符的最长子串是 "wke",所以其长度为 3。 +# 请注意,你的答案必须是 子串 的长度,"pwke" 是一个子序列,不是子串。 +# +# +# +# class Solution: +# def lengthOfLongestSubstring(self, s: str) -> int: +# n = len(s) +# ans = 0 + +# for i in range(n): +# for j in range(i + 1, n + 1): +# if self.allUnique(s, i, j): +# ans = max(ans, j - i) + +# return ans + +# def allUnique(self, s, start, end): +# set_v = set() +# for i in range(start, end): +# ch = s[i] +# if ch in set_v: +# return False +# set_v.add(ch) + +# return True + + +class Solution: + def lengthOfLongestSubstring(self, s: str) -> int: + n = len(s) + ans = 0 + start = 0 + dict_v = dict() + for end in range(n): + ch = s[end] + if dict_v.get(ch, None): + start = max(dict_v.get(ch), start) + ans = max(ans, end - start + 1) + dict_v[ch] = end + 1 + + return ans diff --git a/Week_03/id_36/LeetCode_102_36.py b/Week_03/id_36/LeetCode_102_36.py new file mode 100644 index 00000000..8e1da996 --- /dev/null +++ b/Week_03/id_36/LeetCode_102_36.py @@ -0,0 +1,94 @@ +# +# @lc app=leetcode.cn id=102 lang=python3 +# +# [102] 二叉树的层次遍历 +# +# https://leetcode-cn.com/problems/binary-tree-level-order-traversal/description/ +# +# algorithms +# Medium (56.68%) +# Likes: 215 +# Dislikes: 0 +# Total Accepted: 29.3K +# Total Submissions: 51.7K +# Testcase Example: '[3,9,20,null,null,15,7]' +# +# 给定一个二叉树,返回其按层次遍历的节点值。 (即逐层地,从左到右访问所有节点)。 +# +# 例如: +# 给定二叉树: [3,9,20,null,null,15,7], +# +# ⁠ 3 +# ⁠ / \ +# ⁠ 9 20 +# ⁠ / \ +# ⁠ 15 7 +# +# +# 返回其层次遍历结果: +# +# [ +# ⁠ [3], +# ⁠ [9,20], +# ⁠ [15,7] +# ] +# +# +# +# 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: TreeNode) -> List[List[int]]: +# levels = [] +# if not root: +# return levels + +# def helper(node, level): +# if len(levels) == level: +# levels.append([]) + +# levels[level].append(node.val) + +# if node.left: +# helper(node.left, level + 1) +# if node.right: +# helper(node.right, level + 1) + +# helper(root, 0) +# return levels + +# BFS +class Solution: + def levelOrder(self, root: TreeNode) -> List[List[int]]: + levels = [] + if not root: + return levels + + level = 0 + from collections import deque + queue = deque([root,]) + + while queue: + levels.append([]) + level_length = len(queue) + + for i in range(level_length): + node = queue.popleft() + + levels[level].append(node.val) + + if node.left: + queue.append(node.left) + if node.right: + queue.append(node.right) + + level += 1 + + return levels + diff --git a/Week_03/id_36/LeetCode_104_36.py b/Week_03/id_36/LeetCode_104_36.py new file mode 100644 index 00000000..8e5dd1ac --- /dev/null +++ b/Week_03/id_36/LeetCode_104_36.py @@ -0,0 +1,70 @@ +# +# @lc app=leetcode.cn id=104 lang=python3 +# +# [104] 二叉树的最大深度 +# +# https://leetcode-cn.com/problems/maximum-depth-of-binary-tree/description/ +# +# algorithms +# Easy (69.37%) +# Likes: 298 +# Dislikes: 0 +# Total Accepted: 52.1K +# Total Submissions: 75.1K +# Testcase Example: '[3,9,20,null,null,15,7]' +# +# 给定一个二叉树,找出其最大深度。 +# +# 二叉树的深度为根节点到最远叶子节点的最长路径上的节点数。 +# +# 说明: 叶子节点是指没有子节点的节点。 +# +# 示例: +# 给定二叉树 [3,9,20,null,null,15,7], +# +# ⁠ 3 +# ⁠ / \ +# ⁠ 9 20 +# ⁠ / \ +# ⁠ 15 7 +# +# 返回它的最大深度 3 。 +# +# +# 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) -> int: +# if not root: +# return 0 +# return max(self.maxDepth(root.left), self.maxDepth(root.right)) + 1 + +# DFS +class Solution: + def maxDepth(self, root: TreeNode) -> int: + if root is None: + return 0 + + stack = [] + stack.append((root, 1)) + max_depth = 0 + while len(stack) > 0: + current = stack.pop() + root = current[0] + current_depth = current[1] + if root.left is None and root.right is None: + max_depth = max(max_depth, current_depth) + if root.left is not None: + stack.append((root.left, current_depth + 1)) + if root.right is not None: + stack.append((root.right, current_depth + 1)) + + return max_depth diff --git a/Week_03/id_36/LeetCode_107_36.py b/Week_03/id_36/LeetCode_107_36.py new file mode 100644 index 00000000..4315a325 --- /dev/null +++ b/Week_03/id_36/LeetCode_107_36.py @@ -0,0 +1,73 @@ +# +# @lc app=leetcode.cn id=107 lang=python3 +# +# [107] 二叉树的层次遍历 II +# +# https://leetcode-cn.com/problems/binary-tree-level-order-traversal-ii/description/ +# +# algorithms +# Easy (60.90%) +# Likes: 108 +# Dislikes: 0 +# Total Accepted: 17.6K +# Total Submissions: 28.9K +# Testcase Example: '[3,9,20,null,null,15,7]' +# +# 给定一个二叉树,返回其节点值自底向上的层次遍历。 (即按从叶子节点所在层到根节点所在的层,逐层从左向右遍历) +# +# 例如: +# 给定二叉树 [3,9,20,null,null,15,7], +# +# ⁠ 3 +# ⁠ / \ +# ⁠ 9 20 +# ⁠ / \ +# ⁠ 15 7 +# +# +# 返回其自底向上的层次遍历为: +# +# [ +# ⁠ [15,7], +# ⁠ [9,20], +# ⁠ [3] +# ] +# +# +# +# Definition for a binary tree node. +class TreeNode: + def __init__(self, x): + self.val = x + self.left = None + self.right = None + +# BFS +class Solution: + def levelOrderBottom(self, root: TreeNode) -> List[List[int]]: + levels = [] + if not root: + return levels + + from collections import deque + queue = deque([root,]) + children_list = [] + + while queue: + level_length = len(queue) + + for i in range(level_length): + node = queue.popleft() + + if node.left: + queue.append(node.left) + if node.right: + queue.append(node.right) + + children_list.append(node.val) + + levels.insert(0, children_list) + children_list = [] + + return levels + diff --git a/Week_03/id_36/LeetCode_111_36.py b/Week_03/id_36/LeetCode_111_36.py new file mode 100644 index 00000000..5ade1f1d --- /dev/null +++ b/Week_03/id_36/LeetCode_111_36.py @@ -0,0 +1,36 @@ +# +# @lc app=leetcode.cn id=111 lang=python3 +# +# [111] 二叉树的最小深度 +# +# Definition for a binary tree node. + + +class TreeNode: + def __init__(self, x): + self.val = x + self.left = None + self.right = None + +DFS +class Solution: + def minDepth(self, root: TreeNode) -> int: + if root is None: + return 0 + + stack = [] + import sys + stack.append((root, 1)) + min_depth = sys.maxsize + while len(stack) > 0: + current = stack.pop() + root = current[0] + current_depth = current[1] + if root.left is None and root.right is None: + min_depth = min(min_depth, current_depth) + if root.left is not None: + stack.append((root.left, current_depth + 1)) + if root.right is not None: + stack.append((root.right, current_depth + 1)) + + return min_depth diff --git a/Week_03/id_36/LeetCode_200_36.py b/Week_03/id_36/LeetCode_200_36.py new file mode 100644 index 00000000..91552989 --- /dev/null +++ b/Week_03/id_36/LeetCode_200_36.py @@ -0,0 +1,50 @@ +# +# @lc app=leetcode.cn id=200 lang=python3 +# +# [200] 岛屿数量 +# +# https://leetcode-cn.com/problems/number-of-islands/description/ +# +# algorithms +# Medium (44.05%) +# Likes: 171 +# Dislikes: 0 +# Total Accepted: 16.5K +# Total Submissions: 37.4K +# Testcase Example: '[["1","1","1","1","0"],["1","1","0","1","0"],["1","1","0","0","0"],["0","0","0","0","0"]]' +# +# 给定一个由 '1'(陆地)和 +# '0'(水)组成的的二维网格,计算岛屿的数量。一个岛被水包围,并且它是通过水平方向或垂直方向上相邻的陆地连接而成的。你可以假设网格的四个边均被水包围。 +# +# 示例 1: +# +# 输入: +# 11110 +# 11010 +# 11000 +# 00000 +# +# 输出: 1 +# +# +# 示例 2: +# +# 输入: +# 11000 +# 11000 +# 00100 +# 00011 +# +# 输出: 3 +# +# +# + + +class Solution: + def numIslands(self, grid: List[List[str]]) -> int: + def sink(i, j): + if 0 <= i < len(grid) and 0 <= j < len(grid[0]) and grid[i][j] == '1': + grid[i][j] = '0' + list(map(sink, (i-1, i, i+1, i), (j, j-1, j, j+1))) + return sum(grid[i][j] == '1' and not sink(i, j) for i in range(len(grid)) for j in range(len(grid[0]))) diff --git a/Week_03/id_36/LeetCode_429_36.py b/Week_03/id_36/LeetCode_429_36.py new file mode 100644 index 00000000..32e2036e --- /dev/null +++ b/Week_03/id_36/LeetCode_429_36.py @@ -0,0 +1,76 @@ +# +# @lc app=leetcode.cn id=429 lang=python3 +# +# [429] N叉树的层序遍历 +# +# https://leetcode-cn.com/problems/n-ary-tree-level-order-traversal/description/ +# +# algorithms +# Easy (61.82%) +# Likes: 36 +# Dislikes: 0 +# Total Accepted: 6.6K +# Total Submissions: 10.6K +# Testcase Example: '{"$id":"1","children":[{"$id":"2","children":[{"$id":"5","children":[],"val":5},{"$id":"6","children":[],"val":6}],"val":3},{"$id":"3","children":[],"val":2},{"$id":"4","children":[],"val":4}],"val":1}' +# +# 给定一个 N 叉树,返回其节点值的层序遍历。 (即从左到右,逐层遍历)。 +# +# 例如,给定一个 3叉树 : +# +# +# +# +# +# +# +# 返回其层序遍历: +# +# [ +# ⁠ [1], +# ⁠ [3,2,4], +# ⁠ [5,6] +# ] +# +# +# +# +# 说明: +# +# +# 树的深度不会超过 1000。 +# 树的节点总数不会超过 5000。 +# +# + +# Definition for a Node. +class Node: + def __init__(self, val, children): + self.val = val + self.children = children + +class Solution: + def levelOrder(self, root: 'Node') -> List[List[int]]: + levels = [] + if not root: + return levels + + level = 0 + from collections import deque + queue = deque([root,]) + + while queue: + levels.append([]) + level_length = len(queue) + + for i in range(level_length): + node = queue.popleft() + + levels[level].append(node.val) + + if node.children: + queue.extend(node.children) + + level += 1 + + return levels + diff --git "a/Week_03/id_36/\345\260\217\347\273\204\350\256\250\350\256\272\347\232\204\346\225\260\346\215\256\347\273\223\346\236\204\344\270\216\347\256\227\346\263\225\347\232\204\346\200\235\347\273\264\345\257\274\345\233\276.PNG" "b/Week_03/id_36/\345\260\217\347\273\204\350\256\250\350\256\272\347\232\204\346\225\260\346\215\256\347\273\223\346\236\204\344\270\216\347\256\227\346\263\225\347\232\204\346\200\235\347\273\264\345\257\274\345\233\276.PNG" new file mode 100644 index 00000000..4f5286d7 Binary files /dev/null and "b/Week_03/id_36/\345\260\217\347\273\204\350\256\250\350\256\272\347\232\204\346\225\260\346\215\256\347\273\223\346\236\204\344\270\216\347\256\227\346\263\225\347\232\204\346\200\235\347\273\264\345\257\274\345\233\276.PNG" differ