diff --git a/solution/0100-0199/0112.Path Sum/README_EN.md b/solution/0100-0199/0112.Path Sum/README_EN.md index b3df7020a512a..46aa820d83f3e 100644 --- a/solution/0100-0199/0112.Path Sum/README_EN.md +++ b/solution/0100-0199/0112.Path Sum/README_EN.md @@ -37,7 +37,7 @@ tags:
 Input: root = [1,2,3], targetSum = 5
 Output: false
-Explanation: There two root-to-leaf paths in the tree:
+Explanation: There are two root-to-leaf paths in the tree:
 (1 --> 2): The sum is 3.
 (1 --> 3): The sum is 4.
 There is no root-to-leaf path with sum = 5.
diff --git a/solution/0400-0499/0442.Find All Duplicates in an Array/README_EN.md b/solution/0400-0499/0442.Find All Duplicates in an Array/README_EN.md
index 3ece71c0a4ce0..013557eeb986e 100644
--- a/solution/0400-0499/0442.Find All Duplicates in an Array/README_EN.md	
+++ b/solution/0400-0499/0442.Find All Duplicates in an Array/README_EN.md	
@@ -17,7 +17,7 @@ tags:
 
 
 
-

Given an integer array nums of length n where all the integers of nums are in the range [1, n] and each integer appears once or twice, return an array of all the integers that appears twice.

+

Given an integer array nums of length n where all the integers of nums are in the range [1, n] and each integer appears at most twice, return an array of all the integers that appears twice.

You must write an algorithm that runs in O(n) time and uses only constant auxiliary space, excluding the space needed to store the output

diff --git a/solution/0800-0899/0887.Super Egg Drop/README.md b/solution/0800-0899/0887.Super Egg Drop/README.md index 3768e9efb584c..39d3803790ed8 100644 --- a/solution/0800-0899/0887.Super Egg Drop/README.md +++ b/solution/0800-0899/0887.Super Egg Drop/README.md @@ -158,7 +158,7 @@ public: int superEggDrop(int k, int n) { int f[n + 1][k + 1]; memset(f, 0, sizeof(f)); - function dfs = [&](int i, int j) -> int { + auto dfs = [&](auto&& dfs, int i, int j) -> int { if (i < 1) { return 0; } @@ -171,17 +171,17 @@ public: int l = 1, r = i; while (l < r) { int mid = (l + r + 1) >> 1; - int a = dfs(mid - 1, j - 1); - int b = dfs(i - mid, j); + int a = dfs(dfs, mid - 1, j - 1); + int b = dfs(dfs, i - mid, j); if (a <= b) { l = mid; } else { r = mid - 1; } } - return f[i][j] = max(dfs(l - 1, j - 1), dfs(i - l, j)) + 1; + return f[i][j] = max(dfs(dfs, l - 1, j - 1), dfs(dfs, i - l, j)) + 1; }; - return dfs(n, k); + return dfs(dfs, n, k); } }; ``` diff --git a/solution/0800-0899/0887.Super Egg Drop/README_EN.md b/solution/0800-0899/0887.Super Egg Drop/README_EN.md index 42b7cac4045d2..3b1c934196d79 100644 --- a/solution/0800-0899/0887.Super Egg Drop/README_EN.md +++ b/solution/0800-0899/0887.Super Egg Drop/README_EN.md @@ -141,7 +141,7 @@ public: int superEggDrop(int k, int n) { int f[n + 1][k + 1]; memset(f, 0, sizeof(f)); - function dfs = [&](int i, int j) -> int { + auto dfs = [&](auto&& dfs, int i, int j) -> int { if (i < 1) { return 0; } @@ -154,17 +154,17 @@ public: int l = 1, r = i; while (l < r) { int mid = (l + r + 1) >> 1; - int a = dfs(mid - 1, j - 1); - int b = dfs(i - mid, j); + int a = dfs(dfs, mid - 1, j - 1); + int b = dfs(dfs, i - mid, j); if (a <= b) { l = mid; } else { r = mid - 1; } } - return f[i][j] = max(dfs(l - 1, j - 1), dfs(i - l, j)) + 1; + return f[i][j] = max(dfs(dfs, l - 1, j - 1), dfs(dfs, i - l, j)) + 1; }; - return dfs(n, k); + return dfs(dfs, n, k); } }; ``` diff --git a/solution/0800-0899/0887.Super Egg Drop/Solution.cpp b/solution/0800-0899/0887.Super Egg Drop/Solution.cpp index 0be08e60e0e5e..4fc7571df685d 100644 --- a/solution/0800-0899/0887.Super Egg Drop/Solution.cpp +++ b/solution/0800-0899/0887.Super Egg Drop/Solution.cpp @@ -3,7 +3,7 @@ class Solution { int superEggDrop(int k, int n) { int f[n + 1][k + 1]; memset(f, 0, sizeof(f)); - function dfs = [&](int i, int j) -> int { + auto dfs = [&](auto&& dfs, int i, int j) -> int { if (i < 1) { return 0; } @@ -16,16 +16,16 @@ class Solution { int l = 1, r = i; while (l < r) { int mid = (l + r + 1) >> 1; - int a = dfs(mid - 1, j - 1); - int b = dfs(i - mid, j); + int a = dfs(dfs, mid - 1, j - 1); + int b = dfs(dfs, i - mid, j); if (a <= b) { l = mid; } else { r = mid - 1; } } - return f[i][j] = max(dfs(l - 1, j - 1), dfs(i - l, j)) + 1; + return f[i][j] = max(dfs(dfs, l - 1, j - 1), dfs(dfs, i - l, j)) + 1; }; - return dfs(n, k); + return dfs(dfs, n, k); } -}; \ No newline at end of file +}; diff --git a/solution/3000-3099/3016.Minimum Number of Pushes to Type Word II/README_EN.md b/solution/3000-3099/3016.Minimum Number of Pushes to Type Word II/README_EN.md index 1d470861064a2..00e2e5513bf7f 100644 --- a/solution/3000-3099/3016.Minimum Number of Pushes to Type Word II/README_EN.md +++ b/solution/3000-3099/3016.Minimum Number of Pushes to Type Word II/README_EN.md @@ -49,7 +49,7 @@ It can be shown that no other mapping can provide a lower cost.

Example 2:

- +
 Input: word = "xyzxyzxyzxyz"
 Output: 12
diff --git a/solution/3000-3099/3095.Shortest Subarray With OR at Least K I/README_EN.md b/solution/3000-3099/3095.Shortest Subarray With OR at Least K I/README_EN.md
index b61019222153c..8c710f1b490d9 100644
--- a/solution/3000-3099/3095.Shortest Subarray With OR at Least K I/README_EN.md	
+++ b/solution/3000-3099/3095.Shortest Subarray With OR at Least K I/README_EN.md	
@@ -37,6 +37,8 @@ tags:
 

Explanation:

The subarray [3] has OR value of 3. Hence, we return 1.

+ +

Note that [2] is also a special subarray.

Example 2:

diff --git a/solution/3300-3399/3314.Construct the Minimum Bitwise Array I/README_EN.md b/solution/3300-3399/3314.Construct the Minimum Bitwise Array I/README_EN.md index 676c8322e2a83..aeb5b42af38ba 100644 --- a/solution/3300-3399/3314.Construct the Minimum Bitwise Array I/README_EN.md +++ b/solution/3300-3399/3314.Construct the Minimum Bitwise Array I/README_EN.md @@ -22,8 +22,6 @@ edit_url: https://github.com/doocs/leetcode/edit/main/solution/3300-3399/3314.Co

If it is not possible to find such a value for ans[i] that satisfies the condition, then set ans[i] = -1.

-

A prime number is a natural number greater than 1 with only two factors, 1 and itself.

-

 

Example 1:

diff --git a/solution/3300-3399/3315.Construct the Minimum Bitwise Array II/README_EN.md b/solution/3300-3399/3315.Construct the Minimum Bitwise Array II/README_EN.md index 22efae3d6330f..f9ae16599b691 100644 --- a/solution/3300-3399/3315.Construct the Minimum Bitwise Array II/README_EN.md +++ b/solution/3300-3399/3315.Construct the Minimum Bitwise Array II/README_EN.md @@ -22,8 +22,6 @@ edit_url: https://github.com/doocs/leetcode/edit/main/solution/3300-3399/3315.Co

If it is not possible to find such a value for ans[i] that satisfies the condition, then set ans[i] = -1.

-

A prime number is a natural number greater than 1 with only two factors, 1 and itself.

-

 

Example 1:

diff --git a/solution/3300-3399/3316.Find Maximum Removals From Source String/README_EN.md b/solution/3300-3399/3316.Find Maximum Removals From Source String/README_EN.md index 59dba18f88d70..766fa13dabc9f 100644 --- a/solution/3300-3399/3316.Find Maximum Removals From Source String/README_EN.md +++ b/solution/3300-3399/3316.Find Maximum Removals From Source String/README_EN.md @@ -27,8 +27,6 @@ edit_url: https://github.com/doocs/leetcode/edit/main/solution/3300-3399/3316.Fi

Return the maximum number of operations that can be performed.

-

A subsequence is a string that can be derived from another string by deleting some or no characters without changing the order of the remaining characters.

-

 

Example 1:

diff --git a/solution/3300-3399/3319.K-th Largest Perfect Subtree Size in Binary Tree/README.md b/solution/3300-3399/3319.K-th Largest Perfect Subtree Size in Binary Tree/README.md index 296b8402b5da3..9334a995525d3 100644 --- a/solution/3300-3399/3319.K-th Largest Perfect Subtree Size in Binary Tree/README.md +++ b/solution/3300-3399/3319.K-th Largest Perfect Subtree Size in Binary Tree/README.md @@ -83,32 +83,213 @@ edit_url: https://github.com/doocs/leetcode/edit/main/solution/3300-3399/3319.K- -### 方法一 +### 方法一:DFS + 排序 + +我们定义一个函数 $\textit{dfs}$,用于计算以当前节点为根节点的完美二叉子树的大小,用一个数组 $\textit{nums}$ 记录所有完美二叉子树的大小。如果以当前节点为根节点的子树不是完美二叉子树,则返回 $-1$。 + +函数 $\textit{dfs}$ 的执行过程如下: + +1. 如果当前节点为空,则返回 $0$; +2. 递归计算左子树和右子树的完美二叉子树的大小,分别记为 $l$ 和 $r$; +3. 如果左子树和右子树的大小不相等,或者左子树和右子树的大小小于 $0$,则返回 $-1$; +4. 计算当前节点的完美二叉子树的大小 $\textit{cnt} = l + r + 1$,并将 $\textit{cnt}$ 添加到数组 $\textit{nums}$ 中; +5. 返回 $\textit{cnt}$。 + +我们调用 $\textit{dfs}$ 函数计算出所有完美二叉子树的大小,如果数组 $\textit{nums}$ 的长度小于 $k$,则返回 $-1$,否则对数组 $\textit{nums}$ 进行降序排序,返回第 $k$ 大的完美二叉子树的大小。 + +时间复杂度 $O(n \times \log n)$,空间复杂度 $O(n)$。其中 $n$ 是二叉树的节点数。 #### Python3 ```python - +# Definition for a binary tree node. +# class TreeNode: +# def __init__(self, val=0, left=None, right=None): +# self.val = val +# self.left = left +# self.right = right +class Solution: + def kthLargestPerfectSubtree(self, root: Optional[TreeNode], k: int) -> int: + def dfs(root: Optional[TreeNode]) -> int: + if root is None: + return 0 + l, r = dfs(root.left), dfs(root.right) + if l < 0 or l != r: + return -1 + cnt = l + r + 1 + nums.append(cnt) + return cnt + + nums = [] + dfs(root) + if len(nums) < k: + return -1 + nums.sort(reverse=True) + return nums[k - 1] ``` #### Java ```java - +/** + * Definition for a binary tree node. + * public class TreeNode { + * int val; + * TreeNode left; + * TreeNode right; + * TreeNode() {} + * TreeNode(int val) { this.val = val; } + * TreeNode(int val, TreeNode left, TreeNode right) { + * this.val = val; + * this.left = left; + * this.right = right; + * } + * } + */ +class Solution { + private List nums = new ArrayList<>(); + + public int kthLargestPerfectSubtree(TreeNode root, int k) { + dfs(root); + if (nums.size() < k) { + return -1; + } + nums.sort(Comparator.reverseOrder()); + return nums.get(k - 1); + } + + private int dfs(TreeNode root) { + if (root == null) { + return 0; + } + int l = dfs(root.left); + int r = dfs(root.right); + if (l < 0 || l != r) { + return -1; + } + int cnt = l + r + 1; + nums.add(cnt); + return cnt; + } +} ``` #### C++ ```cpp - +/** + * Definition for a binary tree node. + * struct TreeNode { + * int val; + * TreeNode *left; + * TreeNode *right; + * TreeNode() : val(0), left(nullptr), right(nullptr) {} + * TreeNode(int x) : val(x), left(nullptr), right(nullptr) {} + * TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {} + * }; + */ +class Solution { +public: + int kthLargestPerfectSubtree(TreeNode* root, int k) { + vector nums; + auto dfs = [&](auto&& dfs, TreeNode* root) -> int { + if (!root) { + return 0; + } + int l = dfs(dfs, root->left); + int r = dfs(dfs, root->right); + if (l < 0 || l != r) { + return -1; + } + int cnt = l + r + 1; + nums.push_back(cnt); + return cnt; + }; + dfs(dfs, root); + if (nums.size() < k) { + return -1; + } + ranges::sort(nums, greater()); + return nums[k - 1]; + } +}; ``` #### Go ```go +/** + * Definition for a binary tree node. + * type TreeNode struct { + * Val int + * Left *TreeNode + * Right *TreeNode + * } + */ +func kthLargestPerfectSubtree(root *TreeNode, k int) int { + nums := []int{} + var dfs func(*TreeNode) int + dfs = func(root *TreeNode) int { + if root == nil { + return 0 + } + l, r := dfs(root.Left), dfs(root.Right) + if l < 0 || l != r { + return -1 + } + cnt := l + r + 1 + nums = append(nums, cnt) + return cnt + } + dfs(root) + if len(nums) < k { + return -1 + } + sort.Sort(sort.Reverse(sort.IntSlice(nums))) + return nums[k-1] +} +``` +#### TypeScript + +```ts +/** + * Definition for a binary tree node. + * class TreeNode { + * val: number + * left: TreeNode | null + * right: TreeNode | null + * constructor(val?: number, left?: TreeNode | null, right?: TreeNode | null) { + * this.val = (val===undefined ? 0 : val) + * this.left = (left===undefined ? null : left) + * this.right = (right===undefined ? null : right) + * } + * } + */ + +function kthLargestPerfectSubtree(root: TreeNode | null, k: number): number { + const nums: number[] = []; + const dfs = (root: TreeNode | null): number => { + if (!root) { + return 0; + } + const l = dfs(root.left); + const r = dfs(root.right); + if (l < 0 || l !== r) { + return -1; + } + const cnt = l + r + 1; + nums.push(cnt); + return cnt; + }; + dfs(root); + if (nums.length < k) { + return -1; + } + return nums.sort((a, b) => b - a)[k - 1]; +} ``` diff --git a/solution/3300-3399/3319.K-th Largest Perfect Subtree Size in Binary Tree/README_EN.md b/solution/3300-3399/3319.K-th Largest Perfect Subtree Size in Binary Tree/README_EN.md index e13cb8d95decf..b30257addfb7d 100644 --- a/solution/3300-3399/3319.K-th Largest Perfect Subtree Size in Binary Tree/README_EN.md +++ b/solution/3300-3399/3319.K-th Largest Perfect Subtree Size in Binary Tree/README_EN.md @@ -79,32 +79,213 @@ The 2nd largest size is 3.

-### Solution 1 +### Solution 1: DFS + Sorting + +We define a function $\textit{dfs}$ to calculate the size of the perfect binary subtree rooted at the current node, using an array $\textit{nums}$ to record the sizes of all perfect binary subtrees. If the subtree rooted at the current node is not a perfect binary subtree, it returns $-1$. + +The execution process of the function $\textit{dfs}$ is as follows: + +1. If the current node is null, return $0$; +2. Recursively calculate the sizes of the perfect binary subtrees of the left and right subtrees, denoted as $l$ and $r$ respectively; +3. If the sizes of the left and right subtrees are not equal, or if the sizes of the left and right subtrees are less than $0$, return $-1$; +4. Calculate the size of the perfect binary subtree rooted at the current node $\textit{cnt} = l + r + 1$, and add $\textit{cnt}$ to the array $\textit{nums}$; +5. Return $\textit{cnt}$. + +We call the $\textit{dfs}$ function to calculate the sizes of all perfect binary subtrees. If the length of the array $\textit{nums}$ is less than $k$, return $-1$. Otherwise, sort the array $\textit{nums}$ in descending order and return the $k$-th largest perfect binary subtree size. + +The time complexity is $O(n \times \log n)$, and the space complexity is $O(n)$. Here, $n$ is the number of nodes in the binary tree. #### Python3 ```python - +# Definition for a binary tree node. +# class TreeNode: +# def __init__(self, val=0, left=None, right=None): +# self.val = val +# self.left = left +# self.right = right +class Solution: + def kthLargestPerfectSubtree(self, root: Optional[TreeNode], k: int) -> int: + def dfs(root: Optional[TreeNode]) -> int: + if root is None: + return 0 + l, r = dfs(root.left), dfs(root.right) + if l < 0 or l != r: + return -1 + cnt = l + r + 1 + nums.append(cnt) + return cnt + + nums = [] + dfs(root) + if len(nums) < k: + return -1 + nums.sort(reverse=True) + return nums[k - 1] ``` #### Java ```java - +/** + * Definition for a binary tree node. + * public class TreeNode { + * int val; + * TreeNode left; + * TreeNode right; + * TreeNode() {} + * TreeNode(int val) { this.val = val; } + * TreeNode(int val, TreeNode left, TreeNode right) { + * this.val = val; + * this.left = left; + * this.right = right; + * } + * } + */ +class Solution { + private List nums = new ArrayList<>(); + + public int kthLargestPerfectSubtree(TreeNode root, int k) { + dfs(root); + if (nums.size() < k) { + return -1; + } + nums.sort(Comparator.reverseOrder()); + return nums.get(k - 1); + } + + private int dfs(TreeNode root) { + if (root == null) { + return 0; + } + int l = dfs(root.left); + int r = dfs(root.right); + if (l < 0 || l != r) { + return -1; + } + int cnt = l + r + 1; + nums.add(cnt); + return cnt; + } +} ``` #### C++ ```cpp - +/** + * Definition for a binary tree node. + * struct TreeNode { + * int val; + * TreeNode *left; + * TreeNode *right; + * TreeNode() : val(0), left(nullptr), right(nullptr) {} + * TreeNode(int x) : val(x), left(nullptr), right(nullptr) {} + * TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {} + * }; + */ +class Solution { +public: + int kthLargestPerfectSubtree(TreeNode* root, int k) { + vector nums; + auto dfs = [&](auto&& dfs, TreeNode* root) -> int { + if (!root) { + return 0; + } + int l = dfs(dfs, root->left); + int r = dfs(dfs, root->right); + if (l < 0 || l != r) { + return -1; + } + int cnt = l + r + 1; + nums.push_back(cnt); + return cnt; + }; + dfs(dfs, root); + if (nums.size() < k) { + return -1; + } + ranges::sort(nums, greater()); + return nums[k - 1]; + } +}; ``` #### Go ```go +/** + * Definition for a binary tree node. + * type TreeNode struct { + * Val int + * Left *TreeNode + * Right *TreeNode + * } + */ +func kthLargestPerfectSubtree(root *TreeNode, k int) int { + nums := []int{} + var dfs func(*TreeNode) int + dfs = func(root *TreeNode) int { + if root == nil { + return 0 + } + l, r := dfs(root.Left), dfs(root.Right) + if l < 0 || l != r { + return -1 + } + cnt := l + r + 1 + nums = append(nums, cnt) + return cnt + } + dfs(root) + if len(nums) < k { + return -1 + } + sort.Sort(sort.Reverse(sort.IntSlice(nums))) + return nums[k-1] +} +``` +#### TypeScript + +```ts +/** + * Definition for a binary tree node. + * class TreeNode { + * val: number + * left: TreeNode | null + * right: TreeNode | null + * constructor(val?: number, left?: TreeNode | null, right?: TreeNode | null) { + * this.val = (val===undefined ? 0 : val) + * this.left = (left===undefined ? null : left) + * this.right = (right===undefined ? null : right) + * } + * } + */ + +function kthLargestPerfectSubtree(root: TreeNode | null, k: number): number { + const nums: number[] = []; + const dfs = (root: TreeNode | null): number => { + if (!root) { + return 0; + } + const l = dfs(root.left); + const r = dfs(root.right); + if (l < 0 || l !== r) { + return -1; + } + const cnt = l + r + 1; + nums.push(cnt); + return cnt; + }; + dfs(root); + if (nums.length < k) { + return -1; + } + return nums.sort((a, b) => b - a)[k - 1]; +} ``` diff --git a/solution/3300-3399/3319.K-th Largest Perfect Subtree Size in Binary Tree/Solution.cpp b/solution/3300-3399/3319.K-th Largest Perfect Subtree Size in Binary Tree/Solution.cpp new file mode 100644 index 0000000000000..b39240437ccb8 --- /dev/null +++ b/solution/3300-3399/3319.K-th Largest Perfect Subtree Size in Binary Tree/Solution.cpp @@ -0,0 +1,36 @@ +/** + * Definition for a binary tree node. + * struct TreeNode { + * int val; + * TreeNode *left; + * TreeNode *right; + * TreeNode() : val(0), left(nullptr), right(nullptr) {} + * TreeNode(int x) : val(x), left(nullptr), right(nullptr) {} + * TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {} + * }; + */ +class Solution { +public: + int kthLargestPerfectSubtree(TreeNode* root, int k) { + vector nums; + auto dfs = [&](auto&& dfs, TreeNode* root) -> int { + if (!root) { + return 0; + } + int l = dfs(dfs, root->left); + int r = dfs(dfs, root->right); + if (l < 0 || l != r) { + return -1; + } + int cnt = l + r + 1; + nums.push_back(cnt); + return cnt; + }; + dfs(dfs, root); + if (nums.size() < k) { + return -1; + } + ranges::sort(nums, greater()); + return nums[k - 1]; + } +}; diff --git a/solution/3300-3399/3319.K-th Largest Perfect Subtree Size in Binary Tree/Solution.go b/solution/3300-3399/3319.K-th Largest Perfect Subtree Size in Binary Tree/Solution.go new file mode 100644 index 0000000000000..3fe69a5febb5b --- /dev/null +++ b/solution/3300-3399/3319.K-th Largest Perfect Subtree Size in Binary Tree/Solution.go @@ -0,0 +1,30 @@ +/** + * Definition for a binary tree node. + * type TreeNode struct { + * Val int + * Left *TreeNode + * Right *TreeNode + * } + */ +func kthLargestPerfectSubtree(root *TreeNode, k int) int { + nums := []int{} + var dfs func(*TreeNode) int + dfs = func(root *TreeNode) int { + if root == nil { + return 0 + } + l, r := dfs(root.Left), dfs(root.Right) + if l < 0 || l != r { + return -1 + } + cnt := l + r + 1 + nums = append(nums, cnt) + return cnt + } + dfs(root) + if len(nums) < k { + return -1 + } + sort.Sort(sort.Reverse(sort.IntSlice(nums))) + return nums[k-1] +} diff --git a/solution/3300-3399/3319.K-th Largest Perfect Subtree Size in Binary Tree/Solution.java b/solution/3300-3399/3319.K-th Largest Perfect Subtree Size in Binary Tree/Solution.java new file mode 100644 index 0000000000000..cb9558cd8b3bd --- /dev/null +++ b/solution/3300-3399/3319.K-th Largest Perfect Subtree Size in Binary Tree/Solution.java @@ -0,0 +1,41 @@ +/** + * Definition for a binary tree node. + * public class TreeNode { + * int val; + * TreeNode left; + * TreeNode right; + * TreeNode() {} + * TreeNode(int val) { this.val = val; } + * TreeNode(int val, TreeNode left, TreeNode right) { + * this.val = val; + * this.left = left; + * this.right = right; + * } + * } + */ +class Solution { + private List nums = new ArrayList<>(); + + public int kthLargestPerfectSubtree(TreeNode root, int k) { + dfs(root); + if (nums.size() < k) { + return -1; + } + nums.sort(Comparator.reverseOrder()); + return nums.get(k - 1); + } + + private int dfs(TreeNode root) { + if (root == null) { + return 0; + } + int l = dfs(root.left); + int r = dfs(root.right); + if (l < 0 || l != r) { + return -1; + } + int cnt = l + r + 1; + nums.add(cnt); + return cnt; + } +} diff --git a/solution/3300-3399/3319.K-th Largest Perfect Subtree Size in Binary Tree/Solution.py b/solution/3300-3399/3319.K-th Largest Perfect Subtree Size in Binary Tree/Solution.py new file mode 100644 index 0000000000000..1bee5e3f37e00 --- /dev/null +++ b/solution/3300-3399/3319.K-th Largest Perfect Subtree Size in Binary Tree/Solution.py @@ -0,0 +1,24 @@ +# Definition for a binary tree node. +# class TreeNode: +# def __init__(self, val=0, left=None, right=None): +# self.val = val +# self.left = left +# self.right = right +class Solution: + def kthLargestPerfectSubtree(self, root: Optional[TreeNode], k: int) -> int: + def dfs(root: Optional[TreeNode]) -> int: + if root is None: + return 0 + l, r = dfs(root.left), dfs(root.right) + if l < 0 or l != r: + return -1 + cnt = l + r + 1 + nums.append(cnt) + return cnt + + nums = [] + dfs(root) + if len(nums) < k: + return -1 + nums.sort(reverse=True) + return nums[k - 1] diff --git a/solution/3300-3399/3319.K-th Largest Perfect Subtree Size in Binary Tree/Solution.ts b/solution/3300-3399/3319.K-th Largest Perfect Subtree Size in Binary Tree/Solution.ts new file mode 100644 index 0000000000000..c04fc5c5e297d --- /dev/null +++ b/solution/3300-3399/3319.K-th Largest Perfect Subtree Size in Binary Tree/Solution.ts @@ -0,0 +1,35 @@ +/** + * Definition for a binary tree node. + * class TreeNode { + * val: number + * left: TreeNode | null + * right: TreeNode | null + * constructor(val?: number, left?: TreeNode | null, right?: TreeNode | null) { + * this.val = (val===undefined ? 0 : val) + * this.left = (left===undefined ? null : left) + * this.right = (right===undefined ? null : right) + * } + * } + */ + +function kthLargestPerfectSubtree(root: TreeNode | null, k: number): number { + const nums: number[] = []; + const dfs = (root: TreeNode | null): number => { + if (!root) { + return 0; + } + const l = dfs(root.left); + const r = dfs(root.right); + if (l < 0 || l !== r) { + return -1; + } + const cnt = l + r + 1; + nums.push(cnt); + return cnt; + }; + dfs(root); + if (nums.length < k) { + return -1; + } + return nums.sort((a, b) => b - a)[k - 1]; +} diff --git a/solution/3300-3399/3322.Premier League Table Ranking III/README.md b/solution/3300-3399/3322.Premier League Table Ranking III/README.md new file mode 100644 index 0000000000000..440984aeb2fa3 --- /dev/null +++ b/solution/3300-3399/3322.Premier League Table Ranking III/README.md @@ -0,0 +1,189 @@ +--- +comments: true +difficulty: 中等 +edit_url: https://github.com/doocs/leetcode/edit/main/solution/3300-3399/3322.Premier%20League%20Table%20Ranking%20III/README.md +tags: + - 数据库 +--- + + + +# [3322. 英超积分榜排名 III 🔒](https://leetcode.cn/problems/premier-league-table-ranking-iii) + +[English Version](/solution/3300-3399/3322.Premier%20League%20Table%20Ranking%20III/README_EN.md) + +## 题目描述 + + + +

表:SeasonStats

+ +
++------------------+---------+
+| Column Name      | Type    |
++------------------+---------+
+| season_id        | int     |
+| team_id          | int     |
+| team_name        | varchar |
+| matches_played   | int     |
+| wins             | int     |
+| draws            | int     |
+| losses           | int     |
+| goals_for        | int     |
+| goals_against    | int     |
++------------------+---------+
+(season_id, team_id) 是这张表的唯一主键。
+这张表包含每个赛季中每支球队的赛季 id,队伍 id,队伍名,比赛场次,赢场,平局,输场,进球数 (goals_for),以及失球数 (goals_against)。
+
+ +

编写一个解决方案来计算 每个赛季每支球队的积分,净胜球 和 排名。排名应确定如下:

+ +
    +
  • 球队首先按总分排名(从高到低)
  • +
  • 如果积分持平,球队就会根据净胜球(从最高到最低)进行排名
  • +
  • 如果净胜球也持平,则球队将按球队名称按字母顺序排名
  • +
+ +

积分如下计算:

+ +
    +
  • 赢局 有 3 点得分
  • +
  • 平局 有 1 点得分
  • +
  • 输局 有 0 点得分
  • +
+ +

净胜球计算如下:goals_for - goals_against

+ +

返回结果表以 season_id 升序 排序,然后以 rank 升序 排序,最后以 team_name 升序 排序。

+ +

结果格式如下所示。

+ +

 

+ +

示例:

+ +

输入:

+ +

SeasonStats 表:

+ +
++------------+---------+-------------------+----------------+------+-------+--------+-----------+---------------+
+| season_id  | team_id | team_name         | matches_played | wins | draws | losses | goals_for | goals_against |
++------------+---------+-------------------+----------------+------+-------+--------+-----------+---------------+
+| 2021       | 1       | Manchester City   | 38             | 29   | 6     | 3      | 99        | 26            |
+| 2021       | 2       | Liverpool         | 38             | 28   | 8     | 2      | 94        | 26            |
+| 2021       | 3       | Chelsea           | 38             | 21   | 11    | 6      | 76        | 33            |
+| 2021       | 4       | Tottenham         | 38             | 22   | 5     | 11     | 69        | 40            |
+| 2021       | 5       | Arsenal           | 38             | 22   | 3     | 13     | 61        | 48            |
+| 2022       | 1       | Manchester City   | 38             | 28   | 5     | 5      | 94        | 33            |
+| 2022       | 2       | Arsenal           | 38             | 26   | 6     | 6      | 88        | 43            |
+| 2022       | 3       | Manchester United | 38             | 23   | 6     | 9      | 58        | 43            |
+| 2022       | 4       | Newcastle         | 38             | 19   | 14    | 5      | 68        | 33            |
+| 2022       | 5       | Liverpool         | 38             | 19   | 10    | 9      | 75        | 47            |
++------------+---------+-------------------+----------------+------+-------+--------+-----------+---------------+
+
+ +

输出:

+ +
++------------+---------+-------------------+--------+-----------------+------+
+| season_id  | team_id | team_name         | points | goal_difference | rank |
++------------+---------+-------------------+--------+-----------------+------+
+| 2021       | 1       | Manchester City   | 93     | 73              | 1    |
+| 2021       | 2       | Liverpool         | 92     | 68              | 2    |
+| 2021       | 3       | Chelsea           | 74     | 43              | 3    |
+| 2021       | 4       | Tottenham         | 71     | 29              | 4    |
+| 2021       | 5       | Arsenal           | 69     | 13              | 5    |
+| 2022       | 1       | Manchester City   | 89     | 61              | 1    |
+| 2022       | 2       | Arsenal           | 84     | 45              | 2    |
+| 2022       | 3       | Manchester United | 75     | 15              | 3    |
+| 2022       | 4       | Newcastle         | 71     | 35              | 4    |
+| 2022       | 5       | Liverpool         | 67     | 28              | 5    |
++------------+---------+-------------------+--------+-----------------+------+
+
+ +

解释:

+ +
    +
  • 对于 2021 赛季: +
      +
    • 曼城有 93 积分 (29 * 3 + 6 * 1) 以及 73 (99 - 26) 个净胜球。
    • +
    • 利物浦有 92 积分 (28 * 3 + 8 * 1) 以及 68 (94 - 26) 个净胜球。
    • +
    • 切尔西有 74 积分 (21 * 3 + 11 * 1) 以及 43 (76 - 33) 个净胜球。
    • +
    • 托特纳姆有 71 积分 (22 * 3 + 5 * 1) 以及 29 (69 - 40) 个净胜球。
    • +
    • 阿森纳有 69 积分 (22 * 3 + 3 * 1) 以及 13 (61 - 48) 个净胜球。
    • +
    +
  • +
  • 对于 2022 赛季: +
      +
    • 曼城有 89 积分 (28 * 3 + 5 * 1) 以及 61 (94 - 33) 个净胜球。
    • +
    • 阿森纳有 84 积分 (26 * 3 + 6 * 1) 以及 45 (88 - 43) 个净胜球。
    • +
    • 曼联有 75 积分 (23 * 3 + 6 * 1) 以及 15 (58 - 43) 个净胜球。
    • +
    • 纽卡斯尔有 71 积分 (19 * 3 + 14 * 1) 以及 35 (68 - 33) 个净胜球。
    • +
    • 利物浦有 67 积分 (19 * 3 + 10 * 1) 以及 28 (75 - 47) 个净胜球。
    • +
    +
  • +
  • 球队首先以积分排名,然后是净胜球,最后是球队名称。
  • +
  • 输出以 season_id 升序排序,然后以排名升序排序,最后以 team_name 升序排序。
  • +
+ + + +## 解法 + + + +### 方法一:窗口函数 + +我们可以使用窗口函数 `RANK()`,将球队按照赛季分组,按照积分、净胜球和球队名称的顺序进行排名。 + +最后,我们只需要按照 `season_id`、`position` 和 `team_name` 进行排序即可。 + + + +#### MySQL + +```sql +SELECT + season_id, + team_id, + team_name, + wins * 3 + draws points, + goals_for - goals_against goal_difference, + RANK() OVER ( + PARTITION BY season_id + ORDER BY wins * 3 + draws DESC, goals_for - goals_against DESC, team_name + ) position +FROM SeasonStats +ORDER BY 1, 6, 3; +``` + +#### Pandas + +```python +import pandas as pd + + +def process_team_standings(season_stats: pd.DataFrame) -> pd.DataFrame: + season_stats["points"] = season_stats["wins"] * 3 + season_stats["draws"] + season_stats["goal_difference"] = ( + season_stats["goals_for"] - season_stats["goals_against"] + ) + + season_stats = season_stats.sort_values( + ["season_id", "points", "goal_difference", "team_name"], + ascending=[True, False, False, True], + ) + + season_stats["position"] = season_stats.groupby("season_id").cumcount() + 1 + + return season_stats[ + ["season_id", "team_id", "team_name", "points", "goal_difference", "position"] + ] +``` + + + + + + diff --git a/solution/3300-3399/3322.Premier League Table Ranking III/README_EN.md b/solution/3300-3399/3322.Premier League Table Ranking III/README_EN.md new file mode 100644 index 0000000000000..cfc805ef73eed --- /dev/null +++ b/solution/3300-3399/3322.Premier League Table Ranking III/README_EN.md @@ -0,0 +1,188 @@ +--- +comments: true +difficulty: Medium +edit_url: https://github.com/doocs/leetcode/edit/main/solution/3300-3399/3322.Premier%20League%20Table%20Ranking%20III/README_EN.md +tags: + - Database +--- + + + +# [3322. Premier League Table Ranking III 🔒](https://leetcode.com/problems/premier-league-table-ranking-iii) + +[中文文档](/solution/3300-3399/3322.Premier%20League%20Table%20Ranking%20III/README.md) + +## Description + + + +

Table: SeasonStats

+ +
++------------------+---------+
+| Column Name      | Type    |
++------------------+---------+
+| season_id        | int     |
+| team_id          | int     |
+| team_name        | varchar |
+| matches_played   | int     |
+| wins             | int     |
+| draws            | int     |
+| losses           | int     |
+| goals_for        | int     |
+| goals_against    | int     |
++------------------+---------+
+(season_id, team_id) is the unique key for this table.
+This table contains season id, team id, team name, matches played, wins, draws, losses, goals scored (goals_for), and goals conceded (goals_against) for each team in each season.
+
+ +

Write a solution to calculate the points, goal difference, and rank for each team in each season. The ranking should be determined as follows:

+ +
    +
  • Teams are first ranked by their total points (highest to lowest)
  • +
  • If points are tied, teams are then ranked by their goal difference (highest to lowest)
  • +
  • If goal difference is also tied, teams are then ranked alphabetically by team name
  • +
+ +

Points are calculated as follows:

+ +
    +
  • 3 points for a win
  • +
  • 1 point for a draw
  • +
  • 0 points for a loss
  • +
+ +

Goal difference is calculated as: goals_for - goals_against

+ +

Return the result table ordered by season_id in ascending order, then by rank in ascending order, and finally by team_name in ascending order.

+ +

The query result format is in the following example.

+ +

 

+

Example:

+ +

Input:

+ +

SeasonStats table:

+ +
++------------+---------+-------------------+----------------+------+-------+--------+-----------+---------------+
+| season_id  | team_id | team_name         | matches_played | wins | draws | losses | goals_for | goals_against |
++------------+---------+-------------------+----------------+------+-------+--------+-----------+---------------+
+| 2021       | 1       | Manchester City   | 38             | 29   | 6     | 3      | 99        | 26            |
+| 2021       | 2       | Liverpool         | 38             | 28   | 8     | 2      | 94        | 26            |
+| 2021       | 3       | Chelsea           | 38             | 21   | 11    | 6      | 76        | 33            |
+| 2021       | 4       | Tottenham         | 38             | 22   | 5     | 11     | 69        | 40            |
+| 2021       | 5       | Arsenal           | 38             | 22   | 3     | 13     | 61        | 48            |
+| 2022       | 1       | Manchester City   | 38             | 28   | 5     | 5      | 94        | 33            |
+| 2022       | 2       | Arsenal           | 38             | 26   | 6     | 6      | 88        | 43            |
+| 2022       | 3       | Manchester United | 38             | 23   | 6     | 9      | 58        | 43            |
+| 2022       | 4       | Newcastle         | 38             | 19   | 14    | 5      | 68        | 33            |
+| 2022       | 5       | Liverpool         | 38             | 19   | 10    | 9      | 75        | 47            |
++------------+---------+-------------------+----------------+------+-------+--------+-----------+---------------+
+
+ +

Output:

+ +
++------------+---------+-------------------+--------+-----------------+------+
+| season_id  | team_id | team_name         | points | goal_difference | rank |
++------------+---------+-------------------+--------+-----------------+------+
+| 2021       | 1       | Manchester City   | 93     | 73              | 1    |
+| 2021       | 2       | Liverpool         | 92     | 68              | 2    |
+| 2021       | 3       | Chelsea           | 74     | 43              | 3    |
+| 2021       | 4       | Tottenham         | 71     | 29              | 4    |
+| 2021       | 5       | Arsenal           | 69     | 13              | 5    |
+| 2022       | 1       | Manchester City   | 89     | 61              | 1    |
+| 2022       | 2       | Arsenal           | 84     | 45              | 2    |
+| 2022       | 3       | Manchester United | 75     | 15              | 3    |
+| 2022       | 4       | Newcastle         | 71     | 35              | 4    |
+| 2022       | 5       | Liverpool         | 67     | 28              | 5    |
++------------+---------+-------------------+--------+-----------------+------+
+
+ +

Explanation:

+ +
    +
  • For the 2021 season: +
      +
    • Manchester City has 93 points (29 * 3 + 6 * 1) and a goal difference of 73 (99 - 26).
    • +
    • Liverpool has 92 points (28 * 3 + 8 * 1) and a goal difference of 68 (94 - 26).
    • +
    • Chelsea has 74 points (21 * 3 + 11 * 1) and a goal difference of 43 (76 - 33).
    • +
    • Tottenham has 71 points (22 * 3 + 5 * 1) and a goal difference of 29 (69 - 40).
    • +
    • Arsenal has 69 points (22 * 3 + 3 * 1) and a goal difference of 13 (61 - 48).
    • +
    +
  • +
  • For the 2022 season: +
      +
    • Manchester City has 89 points (28 * 3 + 5 * 1) and a goal difference of 61 (94 - 33).
    • +
    • Arsenal has 84 points (26 * 3 + 6 * 1) and a goal difference of 45 (88 - 43).
    • +
    • Manchester United has 75 points (23 * 3 + 6 * 1) and a goal difference of 15 (58 - 43).
    • +
    • Newcastle has 71 points (19 * 3 + 14 * 1) and a goal difference of 35 (68 - 33).
    • +
    • Liverpool has 67 points (19 * 3 + 10 * 1) and a goal difference of 28 (75 - 47).
    • +
    +
  • +
  • The teams are ranked first by points, then by goal difference, and finally by team name.
  • +
  • The output is ordered by season_id ascending, then by rank ascending, and finally by team_name ascending.
  • +
+ + + +## Solutions + + + +### Solution 1: Window Function + +We can use the window function `RANK()` to rank the teams by grouping them by season and sorting based on points, goal difference, and team name. + +Finally, we just need to sort by `season_id`, `position`, and `team_name`. + + + +#### MySQL + +```sql +SELECT + season_id, + team_id, + team_name, + wins * 3 + draws points, + goals_for - goals_against goal_difference, + RANK() OVER ( + PARTITION BY season_id + ORDER BY wins * 3 + draws DESC, goals_for - goals_against DESC, team_name + ) position +FROM SeasonStats +ORDER BY 1, 6, 3; +``` + +#### Pandas + +```python +import pandas as pd + + +def process_team_standings(season_stats: pd.DataFrame) -> pd.DataFrame: + season_stats["points"] = season_stats["wins"] * 3 + season_stats["draws"] + season_stats["goal_difference"] = ( + season_stats["goals_for"] - season_stats["goals_against"] + ) + + season_stats = season_stats.sort_values( + ["season_id", "points", "goal_difference", "team_name"], + ascending=[True, False, False, True], + ) + + season_stats["position"] = season_stats.groupby("season_id").cumcount() + 1 + + return season_stats[ + ["season_id", "team_id", "team_name", "points", "goal_difference", "position"] + ] +``` + + + + + + diff --git a/solution/3300-3399/3322.Premier League Table Ranking III/Solution.py b/solution/3300-3399/3322.Premier League Table Ranking III/Solution.py new file mode 100644 index 0000000000000..afbefd8834414 --- /dev/null +++ b/solution/3300-3399/3322.Premier League Table Ranking III/Solution.py @@ -0,0 +1,19 @@ +import pandas as pd + + +def process_team_standings(season_stats: pd.DataFrame) -> pd.DataFrame: + season_stats["points"] = season_stats["wins"] * 3 + season_stats["draws"] + season_stats["goal_difference"] = ( + season_stats["goals_for"] - season_stats["goals_against"] + ) + + season_stats = season_stats.sort_values( + ["season_id", "points", "goal_difference", "team_name"], + ascending=[True, False, False, True], + ) + + season_stats["position"] = season_stats.groupby("season_id").cumcount() + 1 + + return season_stats[ + ["season_id", "team_id", "team_name", "points", "goal_difference", "position"] + ] diff --git a/solution/3300-3399/3322.Premier League Table Ranking III/Solution.sql b/solution/3300-3399/3322.Premier League Table Ranking III/Solution.sql new file mode 100644 index 0000000000000..0b9774594f7d4 --- /dev/null +++ b/solution/3300-3399/3322.Premier League Table Ranking III/Solution.sql @@ -0,0 +1,12 @@ +SELECT + season_id, + team_id, + team_name, + wins * 3 + draws points, + goals_for - goals_against goal_difference, + RANK() OVER ( + PARTITION BY season_id + ORDER BY wins * 3 + draws DESC, goals_for - goals_against DESC, team_name + ) position +FROM SeasonStats +ORDER BY 1, 6, 3; diff --git a/solution/DATABASE_README.md b/solution/DATABASE_README.md index 3a26b58e07d6d..a35d091b26ad7 100644 --- a/solution/DATABASE_README.md +++ b/solution/DATABASE_README.md @@ -297,6 +297,7 @@ | 3278 | [寻找数据科学家职位的候选人 II](/solution/3200-3299/3278.Find%20Candidates%20for%20Data%20Scientist%20Position%20II/README.md) | `数据库` | 中等 | 🔒 | | 3293 | [计算产品最终价格](/solution/3200-3299/3293.Calculate%20Product%20Final%20Price/README.md) | `数据库` | 中等 | 🔒 | | 3308 | [Find Top Performing Driver](/solution/3300-3399/3308.Find%20Top%20Performing%20Driver/README.md) | `数据库` | 中等 | 🔒 | +| 3322 | [英超积分榜排名 III](/solution/3300-3399/3322.Premier%20League%20Table%20Ranking%20III/README.md) | | 中等 | 🔒 | ## 版权 diff --git a/solution/DATABASE_README_EN.md b/solution/DATABASE_README_EN.md index d1bbd98d8a590..6c3a747cc5d04 100644 --- a/solution/DATABASE_README_EN.md +++ b/solution/DATABASE_README_EN.md @@ -295,6 +295,7 @@ Press Control + F(or Command + F on | 3278 | [Find Candidates for Data Scientist Position II](/solution/3200-3299/3278.Find%20Candidates%20for%20Data%20Scientist%20Position%20II/README_EN.md) | `Database` | Medium | 🔒 | | 3293 | [Calculate Product Final Price](/solution/3200-3299/3293.Calculate%20Product%20Final%20Price/README_EN.md) | `Database` | Medium | 🔒 | | 3308 | [Find Top Performing Driver](/solution/3300-3399/3308.Find%20Top%20Performing%20Driver/README_EN.md) | `Database` | Medium | 🔒 | +| 3322 | [Premier League Table Ranking III](/solution/3300-3399/3322.Premier%20League%20Table%20Ranking%20III/README_EN.md) | | Medium | 🔒 | ## Copyright diff --git a/solution/README.md b/solution/README.md index 2c7b8baa627b6..2850c846cca7d 100644 --- a/solution/README.md +++ b/solution/README.md @@ -3332,6 +3332,7 @@ | 3319 | [第 K 大的完美二叉子树的大小](/solution/3300-3399/3319.K-th%20Largest%20Perfect%20Subtree%20Size%20in%20Binary%20Tree/README.md) | | 中等 | 第 419 场周赛 | | 3320 | [统计能获胜的出招序列数](/solution/3300-3399/3320.Count%20The%20Number%20of%20Winning%20Sequences/README.md) | | 困难 | 第 419 场周赛 | | 3321 | [计算子数组的 x-sum II](/solution/3300-3399/3321.Find%20X-Sum%20of%20All%20K-Long%20Subarrays%20II/README.md) | | 困难 | 第 419 场周赛 | +| 3322 | [英超积分榜排名 III](/solution/3300-3399/3322.Premier%20League%20Table%20Ranking%20III/README.md) | | 中等 | 🔒 | ## 版权 diff --git a/solution/README_EN.md b/solution/README_EN.md index f3f8f6d3a7fca..b19bfd7fb70bf 100644 --- a/solution/README_EN.md +++ b/solution/README_EN.md @@ -3330,6 +3330,7 @@ Press Control + F(or Command + F on | 3319 | [K-th Largest Perfect Subtree Size in Binary Tree](/solution/3300-3399/3319.K-th%20Largest%20Perfect%20Subtree%20Size%20in%20Binary%20Tree/README_EN.md) | | Medium | Weekly Contest 419 | | 3320 | [Count The Number of Winning Sequences](/solution/3300-3399/3320.Count%20The%20Number%20of%20Winning%20Sequences/README_EN.md) | | Hard | Weekly Contest 419 | | 3321 | [Find X-Sum of All K-Long Subarrays II](/solution/3300-3399/3321.Find%20X-Sum%20of%20All%20K-Long%20Subarrays%20II/README_EN.md) | | Hard | Weekly Contest 419 | +| 3322 | [Premier League Table Ranking III](/solution/3300-3399/3322.Premier%20League%20Table%20Ranking%20III/README_EN.md) | | Medium | 🔒 | ## Copyright