diff --git a/solution/1700-1799/1760.Minimum Limit of Balls in a Bag/README.md b/solution/1700-1799/1760.Minimum Limit of Balls in a Bag/README.md index 62765638217de..919bf3c866941 100644 --- a/solution/1700-1799/1760.Minimum Limit of Balls in a Bag/README.md +++ b/solution/1700-1799/1760.Minimum Limit of Balls in a Bag/README.md @@ -87,9 +87,15 @@ tags: ### 方法一:二分查找 -我们可以将题目可以转换为:对某个开销值,看它能不能在 maxOperations 次操作内得到。因此,二分枚举开销值,找到最小的且满足条件的开销值即可。 +本题需要我们最小化开销,即最小化单个袋子里球数目的最大值。随着最大值的增大,操作次数会减少,越容易满足条件。 -时间复杂度 $O(n \times \log M)$。其中 $n$ 和 $M$ 分别为数组 `nums` 的长度和最大值。 +因此,我们可以二分枚举单个袋子里球数目的最大值,判断是否能在 $\textit{maxOperations}$ 次操作内得到。 + +具体地,我们定义二分查找的左边界 $l = 1$,右边界 $r = \max(\textit{nums})$。然后我们不断二分枚举中间值 $\textit{mid} = \frac{l + r}{2}$,对于每个 $\textit{mid}$,我们计算在这个 $\textit{mid}$ 下,需要的操作次数。如果操作次数小于等于 $\textit{maxOperations}$,说明 $\textit{mid}$ 满足条件,我们将右边界 $r$ 更新为 $\textit{mid}$,否则将左边界 $l$ 更新为 $\textit{mid} + 1$。 + +最后,我们返回左边界 $l$ 即可。 + +时间复杂度 $O(n \times \log M)$,其中 $n$ 和 $M$ 分别是数组 $\textit{nums}$ 的长度和最大值。空间复杂度 $O(1)$。 @@ -101,7 +107,7 @@ class Solution: def check(mx: int) -> bool: return sum((x - 1) // mx for x in nums) <= maxOperations - return bisect_left(range(1, max(nums)), True, key=check) + 1 + return bisect_left(range(1, max(nums) + 1), True, key=check) + 1 ``` #### Java @@ -109,23 +115,20 @@ class Solution: ```java class Solution { public int minimumSize(int[] nums, int maxOperations) { - int left = 1, right = 0; - for (int x : nums) { - right = Math.max(right, x); - } - while (left < right) { - int mid = (left + right) >> 1; - long cnt = 0; + int l = 1, r = Arrays.stream(nums).max().getAsInt(); + while (l < r) { + int mid = (l + r) >> 1; + long s = 0; for (int x : nums) { - cnt += (x - 1) / mid; + s += (x - 1) / mid; } - if (cnt <= maxOperations) { - right = mid; + if (s <= maxOperations) { + r = mid; } else { - left = mid + 1; + l = mid + 1; } } - return left; + return l; } } ``` @@ -136,20 +139,20 @@ class Solution { class Solution { public: int minimumSize(vector& nums, int maxOperations) { - int left = 1, right = *max_element(nums.begin(), nums.end()); - while (left < right) { - int mid = (left + right) >> 1; - long long cnt = 0; + int l = 1, r = ranges::max(nums); + while (l < r) { + int mid = (l + r) >> 1; + long long s = 0; for (int x : nums) { - cnt += (x - 1) / mid; + s += (x - 1) / mid; } - if (cnt <= maxOperations) { - right = mid; + if (s <= maxOperations) { + r = mid; } else { - left = mid + 1; + l = mid + 1; } } - return left; + return l; } }; ``` @@ -161,11 +164,11 @@ func minimumSize(nums []int, maxOperations int) int { r := slices.Max(nums) return 1 + sort.Search(r, func(mx int) bool { mx++ - cnt := 0 + s := 0 for _, x := range nums { - cnt += (x - 1) / mx + s += (x - 1) / mx } - return cnt <= maxOperations + return s <= maxOperations }) } ``` @@ -174,21 +177,45 @@ func minimumSize(nums []int, maxOperations int) int { ```ts function minimumSize(nums: number[], maxOperations: number): number { - let left = 1; - let right = Math.max(...nums); - while (left < right) { - const mid = (left + right) >> 1; - let cnt = 0; - for (const x of nums) { - cnt += ~~((x - 1) / mid); - } - if (cnt <= maxOperations) { - right = mid; + let [l, r] = [1, Math.max(...nums)]; + while (l < r) { + const mid = (l + r) >> 1; + const s = nums.map(x => ((x - 1) / mid) | 0).reduce((a, b) => a + b); + if (s <= maxOperations) { + r = mid; } else { - left = mid + 1; + l = mid + 1; } } - return left; + return l; +} +``` + +#### Rust + +```rust +impl Solution { + pub fn minimum_size(nums: Vec, max_operations: i32) -> i32 { + let mut l = 1; + let mut r = *nums.iter().max().unwrap(); + + while l < r { + let mid = (l + r) / 2; + let mut s: i64 = 0; + + for &x in &nums { + s += ((x - 1) / mid) as i64; + } + + if s <= max_operations as i64 { + r = mid; + } else { + l = mid + 1; + } + } + + l + } } ``` @@ -201,24 +228,43 @@ function minimumSize(nums: number[], maxOperations: number): number { * @return {number} */ var minimumSize = function (nums, maxOperations) { - let left = 1; - let right = Math.max(...nums); - while (left < right) { - const mid = (left + right) >> 1; - let cnt = 0; - for (const x of nums) { - cnt += ~~((x - 1) / mid); - } - if (cnt <= maxOperations) { - right = mid; + let [l, r] = [1, Math.max(...nums)]; + while (l < r) { + const mid = (l + r) >> 1; + const s = nums.map(x => ((x - 1) / mid) | 0).reduce((a, b) => a + b); + if (s <= maxOperations) { + r = mid; } else { - left = mid + 1; + l = mid + 1; } } - return left; + return l; }; ``` +#### C# + +```cs +public class Solution { + public int MinimumSize(int[] nums, int maxOperations) { + int l = 1, r = nums.Max(); + while (l < r) { + int mid = (l + r) >> 1; + long s = 0; + foreach (int x in nums) { + s += (x - 1) / mid; + } + if (s <= maxOperations) { + r = mid; + } else { + l = mid + 1; + } + } + return l; + } +} +``` + diff --git a/solution/1700-1799/1760.Minimum Limit of Balls in a Bag/README_EN.md b/solution/1700-1799/1760.Minimum Limit of Balls in a Bag/README_EN.md index 476f69ff11d86..45a3a7056bebe 100644 --- a/solution/1700-1799/1760.Minimum Limit of Balls in a Bag/README_EN.md +++ b/solution/1700-1799/1760.Minimum Limit of Balls in a Bag/README_EN.md @@ -76,7 +76,17 @@ The bag with the most number of balls has 2 balls, so your penalty is 2, and you -### Solution 1 +### Solution 1: Binary Search + +This problem requires us to minimize the cost, which is the maximum number of balls in a single bag. As the maximum value increases, the number of operations decreases, making it easier to meet the condition. + +Therefore, we can use binary search to enumerate the maximum number of balls in a single bag and determine if it can be achieved within $\textit{maxOperations}$ operations. + +Specifically, we define the left boundary of the binary search as $l = 1$ and the right boundary as $r = \max(\textit{nums})$. Then we continuously perform binary search on the middle value $\textit{mid} = \frac{l + r}{2}$. For each $\textit{mid}$, we calculate the number of operations needed. If the number of operations is less than or equal to $\textit{maxOperations}$, it means $\textit{mid}$ meets the condition, and we update the right boundary $r$ to $\textit{mid}$. Otherwise, we update the left boundary $l$ to $\textit{mid} + 1$. + +Finally, we return the left boundary $l$. + +The time complexity is $O(n \times \log M)$, where $n$ and $M$ are the length and the maximum value of the array $\textit{nums}$, respectively. The space complexity is $O(1)$. @@ -88,7 +98,7 @@ class Solution: def check(mx: int) -> bool: return sum((x - 1) // mx for x in nums) <= maxOperations - return bisect_left(range(1, max(nums)), True, key=check) + 1 + return bisect_left(range(1, max(nums) + 1), True, key=check) + 1 ``` #### Java @@ -96,23 +106,20 @@ class Solution: ```java class Solution { public int minimumSize(int[] nums, int maxOperations) { - int left = 1, right = 0; - for (int x : nums) { - right = Math.max(right, x); - } - while (left < right) { - int mid = (left + right) >> 1; - long cnt = 0; + int l = 1, r = Arrays.stream(nums).max().getAsInt(); + while (l < r) { + int mid = (l + r) >> 1; + long s = 0; for (int x : nums) { - cnt += (x - 1) / mid; + s += (x - 1) / mid; } - if (cnt <= maxOperations) { - right = mid; + if (s <= maxOperations) { + r = mid; } else { - left = mid + 1; + l = mid + 1; } } - return left; + return l; } } ``` @@ -123,20 +130,20 @@ class Solution { class Solution { public: int minimumSize(vector& nums, int maxOperations) { - int left = 1, right = *max_element(nums.begin(), nums.end()); - while (left < right) { - int mid = (left + right) >> 1; - long long cnt = 0; + int l = 1, r = ranges::max(nums); + while (l < r) { + int mid = (l + r) >> 1; + long long s = 0; for (int x : nums) { - cnt += (x - 1) / mid; + s += (x - 1) / mid; } - if (cnt <= maxOperations) { - right = mid; + if (s <= maxOperations) { + r = mid; } else { - left = mid + 1; + l = mid + 1; } } - return left; + return l; } }; ``` @@ -148,11 +155,11 @@ func minimumSize(nums []int, maxOperations int) int { r := slices.Max(nums) return 1 + sort.Search(r, func(mx int) bool { mx++ - cnt := 0 + s := 0 for _, x := range nums { - cnt += (x - 1) / mx + s += (x - 1) / mx } - return cnt <= maxOperations + return s <= maxOperations }) } ``` @@ -161,21 +168,45 @@ func minimumSize(nums []int, maxOperations int) int { ```ts function minimumSize(nums: number[], maxOperations: number): number { - let left = 1; - let right = Math.max(...nums); - while (left < right) { - const mid = (left + right) >> 1; - let cnt = 0; - for (const x of nums) { - cnt += ~~((x - 1) / mid); - } - if (cnt <= maxOperations) { - right = mid; + let [l, r] = [1, Math.max(...nums)]; + while (l < r) { + const mid = (l + r) >> 1; + const s = nums.map(x => ((x - 1) / mid) | 0).reduce((a, b) => a + b); + if (s <= maxOperations) { + r = mid; } else { - left = mid + 1; + l = mid + 1; } } - return left; + return l; +} +``` + +#### Rust + +```rust +impl Solution { + pub fn minimum_size(nums: Vec, max_operations: i32) -> i32 { + let mut l = 1; + let mut r = *nums.iter().max().unwrap(); + + while l < r { + let mid = (l + r) / 2; + let mut s: i64 = 0; + + for &x in &nums { + s += ((x - 1) / mid) as i64; + } + + if s <= max_operations as i64 { + r = mid; + } else { + l = mid + 1; + } + } + + l + } } ``` @@ -188,24 +219,43 @@ function minimumSize(nums: number[], maxOperations: number): number { * @return {number} */ var minimumSize = function (nums, maxOperations) { - let left = 1; - let right = Math.max(...nums); - while (left < right) { - const mid = (left + right) >> 1; - let cnt = 0; - for (const x of nums) { - cnt += ~~((x - 1) / mid); - } - if (cnt <= maxOperations) { - right = mid; + let [l, r] = [1, Math.max(...nums)]; + while (l < r) { + const mid = (l + r) >> 1; + const s = nums.map(x => ((x - 1) / mid) | 0).reduce((a, b) => a + b); + if (s <= maxOperations) { + r = mid; } else { - left = mid + 1; + l = mid + 1; } } - return left; + return l; }; ``` +#### C# + +```cs +public class Solution { + public int MinimumSize(int[] nums, int maxOperations) { + int l = 1, r = nums.Max(); + while (l < r) { + int mid = (l + r) >> 1; + long s = 0; + foreach (int x in nums) { + s += (x - 1) / mid; + } + if (s <= maxOperations) { + r = mid; + } else { + l = mid + 1; + } + } + return l; + } +} +``` + diff --git a/solution/1700-1799/1760.Minimum Limit of Balls in a Bag/Solution.cpp b/solution/1700-1799/1760.Minimum Limit of Balls in a Bag/Solution.cpp index 6423c68ddfa77..6d5ad2248c7ba 100644 --- a/solution/1700-1799/1760.Minimum Limit of Balls in a Bag/Solution.cpp +++ b/solution/1700-1799/1760.Minimum Limit of Balls in a Bag/Solution.cpp @@ -1,19 +1,19 @@ class Solution { public: int minimumSize(vector& nums, int maxOperations) { - int left = 1, right = *max_element(nums.begin(), nums.end()); - while (left < right) { - int mid = (left + right) >> 1; - long long cnt = 0; + int l = 1, r = ranges::max(nums); + while (l < r) { + int mid = (l + r) >> 1; + long long s = 0; for (int x : nums) { - cnt += (x - 1) / mid; + s += (x - 1) / mid; } - if (cnt <= maxOperations) { - right = mid; + if (s <= maxOperations) { + r = mid; } else { - left = mid + 1; + l = mid + 1; } } - return left; + return l; } -}; \ No newline at end of file +}; diff --git a/solution/1700-1799/1760.Minimum Limit of Balls in a Bag/Solution.cs b/solution/1700-1799/1760.Minimum Limit of Balls in a Bag/Solution.cs new file mode 100644 index 0000000000000..c3f9e3917a1ac --- /dev/null +++ b/solution/1700-1799/1760.Minimum Limit of Balls in a Bag/Solution.cs @@ -0,0 +1,18 @@ +public class Solution { + public int MinimumSize(int[] nums, int maxOperations) { + int l = 1, r = nums.Max(); + while (l < r) { + int mid = (l + r) >> 1; + long s = 0; + foreach (int x in nums) { + s += (x - 1) / mid; + } + if (s <= maxOperations) { + r = mid; + } else { + l = mid + 1; + } + } + return l; + } +} diff --git a/solution/1700-1799/1760.Minimum Limit of Balls in a Bag/Solution.go b/solution/1700-1799/1760.Minimum Limit of Balls in a Bag/Solution.go index f3c1b612aa9d3..61dbad5054590 100644 --- a/solution/1700-1799/1760.Minimum Limit of Balls in a Bag/Solution.go +++ b/solution/1700-1799/1760.Minimum Limit of Balls in a Bag/Solution.go @@ -2,10 +2,10 @@ func minimumSize(nums []int, maxOperations int) int { r := slices.Max(nums) return 1 + sort.Search(r, func(mx int) bool { mx++ - cnt := 0 + s := 0 for _, x := range nums { - cnt += (x - 1) / mx + s += (x - 1) / mx } - return cnt <= maxOperations + return s <= maxOperations }) -} \ No newline at end of file +} diff --git a/solution/1700-1799/1760.Minimum Limit of Balls in a Bag/Solution.java b/solution/1700-1799/1760.Minimum Limit of Balls in a Bag/Solution.java index 48aca93edbf71..c742182e520bc 100644 --- a/solution/1700-1799/1760.Minimum Limit of Balls in a Bag/Solution.java +++ b/solution/1700-1799/1760.Minimum Limit of Balls in a Bag/Solution.java @@ -1,21 +1,18 @@ class Solution { public int minimumSize(int[] nums, int maxOperations) { - int left = 1, right = 0; - for (int x : nums) { - right = Math.max(right, x); - } - while (left < right) { - int mid = (left + right) >> 1; - long cnt = 0; + int l = 1, r = Arrays.stream(nums).max().getAsInt(); + while (l < r) { + int mid = (l + r) >> 1; + long s = 0; for (int x : nums) { - cnt += (x - 1) / mid; + s += (x - 1) / mid; } - if (cnt <= maxOperations) { - right = mid; + if (s <= maxOperations) { + r = mid; } else { - left = mid + 1; + l = mid + 1; } } - return left; + return l; } -} \ No newline at end of file +} diff --git a/solution/1700-1799/1760.Minimum Limit of Balls in a Bag/Solution.js b/solution/1700-1799/1760.Minimum Limit of Balls in a Bag/Solution.js index ece365f4a43d1..54e2c957ac478 100644 --- a/solution/1700-1799/1760.Minimum Limit of Balls in a Bag/Solution.js +++ b/solution/1700-1799/1760.Minimum Limit of Balls in a Bag/Solution.js @@ -4,19 +4,15 @@ * @return {number} */ var minimumSize = function (nums, maxOperations) { - let left = 1; - let right = Math.max(...nums); - while (left < right) { - const mid = (left + right) >> 1; - let cnt = 0; - for (const x of nums) { - cnt += ~~((x - 1) / mid); - } - if (cnt <= maxOperations) { - right = mid; + let [l, r] = [1, Math.max(...nums)]; + while (l < r) { + const mid = (l + r) >> 1; + const s = nums.map(x => ((x - 1) / mid) | 0).reduce((a, b) => a + b); + if (s <= maxOperations) { + r = mid; } else { - left = mid + 1; + l = mid + 1; } } - return left; + return l; }; diff --git a/solution/1700-1799/1760.Minimum Limit of Balls in a Bag/Solution.py b/solution/1700-1799/1760.Minimum Limit of Balls in a Bag/Solution.py index 41c1224361eea..844b7c89e7d96 100644 --- a/solution/1700-1799/1760.Minimum Limit of Balls in a Bag/Solution.py +++ b/solution/1700-1799/1760.Minimum Limit of Balls in a Bag/Solution.py @@ -3,4 +3,4 @@ def minimumSize(self, nums: List[int], maxOperations: int) -> int: def check(mx: int) -> bool: return sum((x - 1) // mx for x in nums) <= maxOperations - return bisect_left(range(1, max(nums)), True, key=check) + 1 + return bisect_left(range(1, max(nums) + 1), True, key=check) + 1 diff --git a/solution/1700-1799/1760.Minimum Limit of Balls in a Bag/Solution.rs b/solution/1700-1799/1760.Minimum Limit of Balls in a Bag/Solution.rs new file mode 100644 index 0000000000000..3bdbf1c191eec --- /dev/null +++ b/solution/1700-1799/1760.Minimum Limit of Balls in a Bag/Solution.rs @@ -0,0 +1,23 @@ +impl Solution { + pub fn minimum_size(nums: Vec, max_operations: i32) -> i32 { + let mut l = 1; + let mut r = *nums.iter().max().unwrap(); + + while l < r { + let mid = (l + r) / 2; + let mut s: i64 = 0; + + for &x in &nums { + s += ((x - 1) / mid) as i64; + } + + if s <= max_operations as i64 { + r = mid; + } else { + l = mid + 1; + } + } + + l + } +} diff --git a/solution/1700-1799/1760.Minimum Limit of Balls in a Bag/Solution.ts b/solution/1700-1799/1760.Minimum Limit of Balls in a Bag/Solution.ts index 63185f0b74848..3313bb7bc541b 100644 --- a/solution/1700-1799/1760.Minimum Limit of Balls in a Bag/Solution.ts +++ b/solution/1700-1799/1760.Minimum Limit of Balls in a Bag/Solution.ts @@ -1,17 +1,13 @@ function minimumSize(nums: number[], maxOperations: number): number { - let left = 1; - let right = Math.max(...nums); - while (left < right) { - const mid = (left + right) >> 1; - let cnt = 0; - for (const x of nums) { - cnt += ~~((x - 1) / mid); - } - if (cnt <= maxOperations) { - right = mid; + let [l, r] = [1, Math.max(...nums)]; + while (l < r) { + const mid = (l + r) >> 1; + const s = nums.map(x => ((x - 1) / mid) | 0).reduce((a, b) => a + b); + if (s <= maxOperations) { + r = mid; } else { - left = mid + 1; + l = mid + 1; } } - return left; + return l; } diff --git a/solution/1800-1899/1887.Reduction Operations to Make the Array Elements Equal/README.md b/solution/1800-1899/1887.Reduction Operations to Make the Array Elements Equal/README.md index 9e93c2f20ead7..5d5fe49767ebd 100644 --- a/solution/1800-1899/1887.Reduction Operations to Make the Array Elements Equal/README.md +++ b/solution/1800-1899/1887.Reduction Operations to Make the Array Elements Equal/README.md @@ -57,8 +57,8 @@ tags: 输出:4 解释:需要 4 次操作使 nums 中的所有元素相等: 1. largest = 3 下标为 4 。nextLargest = 2 。将 nums[4] 减少到 2 。nums = [1,1,2,2,2] 。 -2. largest = 2 下标为 2 。nextLargest = 1 。将 nums[2] 减少到 1 。nums = [1,1,1,2,2] 。 -3. largest = 2 下标为 3 。nextLargest = 1 。将 nums[3] 减少到 1 。nums = [1,1,1,1,2] 。 +2. largest = 2 下标为 2 。nextLargest = 1 。将 nums[2] 减少到 1 。nums = [1,1,1,2,2] 。 +3. largest = 2 下标为 3 。nextLargest = 1 。将 nums[3] 减少到 1 。nums = [1,1,1,1,2] 。 4. largest = 2 下标为 4 。nextLargest = 1 。将 nums[4] 减少到 1 。nums = [1,1,1,1,1] 。 diff --git a/solution/3400-3499/3450.Maximum Students on a Single Bench/README.md b/solution/3400-3499/3450.Maximum Students on a Single Bench/README.md new file mode 100644 index 0000000000000..f77c8fcf2ce5d --- /dev/null +++ b/solution/3400-3499/3450.Maximum Students on a Single Bench/README.md @@ -0,0 +1,232 @@ +--- +comments: true +difficulty: 简单 +edit_url: https://github.com/doocs/leetcode/edit/main/solution/3400-3499/3450.Maximum%20Students%20on%20a%20Single%20Bench/README.md +--- + + + +# [3450. 一张长椅的上最多学生 🔒](https://leetcode.cn/problems/maximum-students-on-a-single-bench) + +[English Version](/solution/3400-3499/3450.Maximum%20Students%20on%20a%20Single%20Bench/README_EN.md) + +## 题目描述 + + + +

给定一个包含学生数据的 2 维数组 students,其中 students[i] = [student_id, bench_id] 表示学生 student_id 正坐在长椅 bench_id 上。

+ +

返回单个长凳上坐着的不同学生的 最大 数量。如果没有学生,返回 0。

+ +

注意:一个学生在输入中可以出现在同一张长椅上多次,但每个长椅上只能计算一次。

+ +

 

+ +

示例 1:

+ +
+

输入:students = [[1,2],[2,2],[3,3],[1,3],[2,3]]

+ +

输出:3

+ +

解释:

+ +
    +
  • 长椅 2 上有 2 个不同学生:[1, 2]
  • +
  • 长椅 3 上有 3 个不同学生:[1, 2, 3]
  • +
  • 一张长椅上不同学生的最大数量是 3。
  • +
+
+ +

示例 2:

+ +
+

输入:students = [[1,1],[2,1],[3,1],[4,2],[5,2]]

+ +

输出:3

+ +

示例:

+ +
    +
  • 长椅 1 上有 3 个不同学生:[1, 2, 3]
  • +
  • 长椅 2 上有 2 个不同学生:[4, 5]
  • +
  • 一张长椅上不同学生的最大数量是 3。
  • +
+
+ +

示例 3:

+ +
+

输入:students = [[1,1],[1,1]]

+ +

输出:1

+ +

解释:

+ +
    +
  • 一张长椅上不同学生的最大数量是 1。
  • +
+
+ +

示例 4:

+ +
+

输入:students = []

+ +

输出:0

+ +

解释:

+ +
    +
  • 由于不存在学生,输出为 0。
  • +
+
+ +

 

+ +

提示:

+ +
    +
  • 0 <= students.length <= 100
  • +
  • students[i] = [student_id, bench_id]
  • +
  • 1 <= student_id <= 100
  • +
  • 1 <= bench_id <= 100
  • +
+ + + +## 解法 + + + +### 方法一:哈希表 + +我们用一个哈希表 $d$ 来存储每个长椅上的学生,键为长椅编号,值为一个集合,集合中存储着该长椅上的学生编号。 + +遍历学生数组 $\textit{students}$,将学生编号和长椅编号存入哈希表 $d$ 中。 + +最后,我们遍历哈希表 $d$ 的值,取出集合的大小的最大值即为一张长椅上坐着的不同学生的最大数量。 + +时间复杂度 $O(n)$,空间复杂度 $O(n)$。其中 $n$ 为学生数组 $\textit{students}$ 的长度。 + + + +#### Python3 + +```python +class Solution: + def maxStudentsOnBench(self, students: List[List[int]]) -> int: + if not students: + return 0 + d = defaultdict(set) + for student_id, bench_id in students: + d[bench_id].add(student_id) + return max(map(len, d.values())) +``` + +#### Java + +```java +class Solution { + public int maxStudentsOnBench(int[][] students) { + Map> d = new HashMap<>(); + for (var e : students) { + int studentId = e[0], benchId = e[1]; + d.computeIfAbsent(benchId, k -> new HashSet<>()).add(studentId); + } + int ans = 0; + for (var s : d.values()) { + ans = Math.max(ans, s.size()); + } + return ans; + } +} +``` + +#### C++ + +```cpp +class Solution { +public: + int maxStudentsOnBench(vector>& students) { + unordered_map> d; + for (const auto& e : students) { + int studentId = e[0], benchId = e[1]; + d[benchId].insert(studentId); + } + int ans = 0; + for (const auto& s : d) { + ans = max(ans, (int) s.second.size()); + } + return ans; + } +}; +``` + +#### Go + +```go +func maxStudentsOnBench(students [][]int) (ans int) { + d := make(map[int]map[int]struct{}) + for _, e := range students { + studentId, benchId := e[0], e[1] + if _, exists := d[benchId]; !exists { + d[benchId] = make(map[int]struct{}) + } + d[benchId][studentId] = struct{}{} + } + for _, s := range d { + ans = max(ans, len(s)) + } + return +} +``` + +#### TypeScript + +```ts +function maxStudentsOnBench(students: number[][]): number { + const d: Map> = new Map(); + for (const [studentId, benchId] of students) { + if (!d.has(benchId)) { + d.set(benchId, new Set()); + } + d.get(benchId)?.add(studentId); + } + let ans = 0; + for (const s of d.values()) { + ans = Math.max(ans, s.size); + } + return ans; +} +``` + +#### Rust + +```rust +use std::collections::{HashMap, HashSet}; + +impl Solution { + pub fn max_students_on_bench(students: Vec>) -> i32 { + let mut d: HashMap> = HashMap::new(); + for e in students { + let student_id = e[0]; + let bench_id = e[1]; + d.entry(bench_id) + .or_insert_with(HashSet::new) + .insert(student_id); + } + let mut ans = 0; + for s in d.values() { + ans = ans.max(s.len() as i32); + } + ans + } +} +``` + + + + + + diff --git a/solution/3400-3499/3450.Maximum Students on a Single Bench/README_EN.md b/solution/3400-3499/3450.Maximum Students on a Single Bench/README_EN.md new file mode 100644 index 0000000000000..d615781f413ee --- /dev/null +++ b/solution/3400-3499/3450.Maximum Students on a Single Bench/README_EN.md @@ -0,0 +1,230 @@ +--- +comments: true +difficulty: Easy +edit_url: https://github.com/doocs/leetcode/edit/main/solution/3400-3499/3450.Maximum%20Students%20on%20a%20Single%20Bench/README_EN.md +--- + + + +# [3450. Maximum Students on a Single Bench 🔒](https://leetcode.com/problems/maximum-students-on-a-single-bench) + +[中文文档](/solution/3400-3499/3450.Maximum%20Students%20on%20a%20Single%20Bench/README.md) + +## Description + + + +

You are given a 2D integer array of student data students, where students[i] = [student_id, bench_id] represents that student student_id is sitting on the bench bench_id.

+ +

Return the maximum number of unique students sitting on any single bench. If no students are present, return 0.

+ +

Note: A student can appear multiple times on the same bench in the input, but they should be counted only once per bench.

+ +

 

+

Example 1:

+ +
+

Input: students = [[1,2],[2,2],[3,3],[1,3],[2,3]]

+ +

Output: 3

+ +

Explanation:

+ +
    +
  • Bench 2 has two unique students: [1, 2].
  • +
  • Bench 3 has three unique students: [1, 2, 3].
  • +
  • The maximum number of unique students on a single bench is 3.
  • +
+
+ +

Example 2:

+ +
+

Input: students = [[1,1],[2,1],[3,1],[4,2],[5,2]]

+ +

Output: 3

+ +

Explanation:

+ +
    +
  • Bench 1 has three unique students: [1, 2, 3].
  • +
  • Bench 2 has two unique students: [4, 5].
  • +
  • The maximum number of unique students on a single bench is 3.
  • +
+
+ +

Example 3:

+ +
+

Input: students = [[1,1],[1,1]]

+ +

Output: 1

+ +

Explanation:

+ +
    +
  • The maximum number of unique students on a single bench is 1.
  • +
+
+ +

Example 4:

+ +
+

Input: students = []

+ +

Output: 0

+ +

Explanation:

+ +
    +
  • Since no students are present, the output is 0.
  • +
+
+ +

 

+

Constraints:

+ +
    +
  • 0 <= students.length <= 100
  • +
  • students[i] = [student_id, bench_id]
  • +
  • 1 <= student_id <= 100
  • +
  • 1 <= bench_id <= 100
  • +
+ + + +## Solutions + + + +### Solution 1: Hash Table + +We use a hash table $d$ to store the students on each bench, where the key is the bench number and the value is a set containing the student IDs on that bench. + +Traverse the student array $\textit{students}$ and store the student IDs and bench numbers in the hash table $d$. + +Finally, we traverse the values of the hash table $d$ and take the maximum size of the sets, which is the maximum number of different students on a single bench. + +The time complexity is $O(n)$, and the space complexity is $O(n)$. Here, $n$ is the length of the student array $\textit{students}$. + + + +#### Python3 + +```python +class Solution: + def maxStudentsOnBench(self, students: List[List[int]]) -> int: + if not students: + return 0 + d = defaultdict(set) + for student_id, bench_id in students: + d[bench_id].add(student_id) + return max(map(len, d.values())) +``` + +#### Java + +```java +class Solution { + public int maxStudentsOnBench(int[][] students) { + Map> d = new HashMap<>(); + for (var e : students) { + int studentId = e[0], benchId = e[1]; + d.computeIfAbsent(benchId, k -> new HashSet<>()).add(studentId); + } + int ans = 0; + for (var s : d.values()) { + ans = Math.max(ans, s.size()); + } + return ans; + } +} +``` + +#### C++ + +```cpp +class Solution { +public: + int maxStudentsOnBench(vector>& students) { + unordered_map> d; + for (const auto& e : students) { + int studentId = e[0], benchId = e[1]; + d[benchId].insert(studentId); + } + int ans = 0; + for (const auto& s : d) { + ans = max(ans, (int) s.second.size()); + } + return ans; + } +}; +``` + +#### Go + +```go +func maxStudentsOnBench(students [][]int) (ans int) { + d := make(map[int]map[int]struct{}) + for _, e := range students { + studentId, benchId := e[0], e[1] + if _, exists := d[benchId]; !exists { + d[benchId] = make(map[int]struct{}) + } + d[benchId][studentId] = struct{}{} + } + for _, s := range d { + ans = max(ans, len(s)) + } + return +} +``` + +#### TypeScript + +```ts +function maxStudentsOnBench(students: number[][]): number { + const d: Map> = new Map(); + for (const [studentId, benchId] of students) { + if (!d.has(benchId)) { + d.set(benchId, new Set()); + } + d.get(benchId)?.add(studentId); + } + let ans = 0; + for (const s of d.values()) { + ans = Math.max(ans, s.size); + } + return ans; +} +``` + +#### Rust + +```rust +use std::collections::{HashMap, HashSet}; + +impl Solution { + pub fn max_students_on_bench(students: Vec>) -> i32 { + let mut d: HashMap> = HashMap::new(); + for e in students { + let student_id = e[0]; + let bench_id = e[1]; + d.entry(bench_id) + .or_insert_with(HashSet::new) + .insert(student_id); + } + let mut ans = 0; + for s in d.values() { + ans = ans.max(s.len() as i32); + } + ans + } +} +``` + + + + + + diff --git a/solution/3400-3499/3450.Maximum Students on a Single Bench/Solution.cpp b/solution/3400-3499/3450.Maximum Students on a Single Bench/Solution.cpp new file mode 100644 index 0000000000000..d26e9eef798e9 --- /dev/null +++ b/solution/3400-3499/3450.Maximum Students on a Single Bench/Solution.cpp @@ -0,0 +1,15 @@ +class Solution { +public: + int maxStudentsOnBench(vector>& students) { + unordered_map> d; + for (const auto& e : students) { + int studentId = e[0], benchId = e[1]; + d[benchId].insert(studentId); + } + int ans = 0; + for (const auto& s : d) { + ans = max(ans, (int) s.second.size()); + } + return ans; + } +}; diff --git a/solution/3400-3499/3450.Maximum Students on a Single Bench/Solution.go b/solution/3400-3499/3450.Maximum Students on a Single Bench/Solution.go new file mode 100644 index 0000000000000..65c8c8c6e24d7 --- /dev/null +++ b/solution/3400-3499/3450.Maximum Students on a Single Bench/Solution.go @@ -0,0 +1,14 @@ +func maxStudentsOnBench(students [][]int) (ans int) { + d := make(map[int]map[int]struct{}) + for _, e := range students { + studentId, benchId := e[0], e[1] + if _, exists := d[benchId]; !exists { + d[benchId] = make(map[int]struct{}) + } + d[benchId][studentId] = struct{}{} + } + for _, s := range d { + ans = max(ans, len(s)) + } + return +} diff --git a/solution/3400-3499/3450.Maximum Students on a Single Bench/Solution.java b/solution/3400-3499/3450.Maximum Students on a Single Bench/Solution.java new file mode 100644 index 0000000000000..2f6f4f036df08 --- /dev/null +++ b/solution/3400-3499/3450.Maximum Students on a Single Bench/Solution.java @@ -0,0 +1,14 @@ +class Solution { + public int maxStudentsOnBench(int[][] students) { + Map> d = new HashMap<>(); + for (var e : students) { + int studentId = e[0], benchId = e[1]; + d.computeIfAbsent(benchId, k -> new HashSet<>()).add(studentId); + } + int ans = 0; + for (var s : d.values()) { + ans = Math.max(ans, s.size()); + } + return ans; + } +} diff --git a/solution/3400-3499/3450.Maximum Students on a Single Bench/Solution.py b/solution/3400-3499/3450.Maximum Students on a Single Bench/Solution.py new file mode 100644 index 0000000000000..2c577c2dd3cb7 --- /dev/null +++ b/solution/3400-3499/3450.Maximum Students on a Single Bench/Solution.py @@ -0,0 +1,8 @@ +class Solution: + def maxStudentsOnBench(self, students: List[List[int]]) -> int: + if not students: + return 0 + d = defaultdict(set) + for student_id, bench_id in students: + d[bench_id].add(student_id) + return max(map(len, d.values())) diff --git a/solution/3400-3499/3450.Maximum Students on a Single Bench/Solution.rs b/solution/3400-3499/3450.Maximum Students on a Single Bench/Solution.rs new file mode 100644 index 0000000000000..4cd8cbc9c3697 --- /dev/null +++ b/solution/3400-3499/3450.Maximum Students on a Single Bench/Solution.rs @@ -0,0 +1,19 @@ +use std::collections::{HashMap, HashSet}; + +impl Solution { + pub fn max_students_on_bench(students: Vec>) -> i32 { + let mut d: HashMap> = HashMap::new(); + for e in students { + let student_id = e[0]; + let bench_id = e[1]; + d.entry(bench_id) + .or_insert_with(HashSet::new) + .insert(student_id); + } + let mut ans = 0; + for s in d.values() { + ans = ans.max(s.len() as i32); + } + ans + } +} diff --git a/solution/3400-3499/3450.Maximum Students on a Single Bench/Solution.ts b/solution/3400-3499/3450.Maximum Students on a Single Bench/Solution.ts new file mode 100644 index 0000000000000..c6035afee0cd0 --- /dev/null +++ b/solution/3400-3499/3450.Maximum Students on a Single Bench/Solution.ts @@ -0,0 +1,14 @@ +function maxStudentsOnBench(students: number[][]): number { + const d: Map> = new Map(); + for (const [studentId, benchId] of students) { + if (!d.has(benchId)) { + d.set(benchId, new Set()); + } + d.get(benchId)?.add(studentId); + } + let ans = 0; + for (const s of d.values()) { + ans = Math.max(ans, s.size); + } + return ans; +} diff --git a/solution/README.md b/solution/README.md index a8e8e082efd51..e72fac6f5073b 100644 --- a/solution/README.md +++ b/solution/README.md @@ -3460,6 +3460,7 @@ | 3447 | [将元素分配给有约束条件的组](/solution/3400-3499/3447.Assign%20Elements%20to%20Groups%20with%20Constraints/README.md) | | 中等 | 第 436 场周赛 | | 3448 | [统计可以被最后一个数位整除的子字符串数目](/solution/3400-3499/3448.Count%20Substrings%20Divisible%20By%20Last%20Digit/README.md) | | 困难 | 第 436 场周赛 | | 3449 | [最大化游戏分数的最小值](/solution/3400-3499/3449.Maximize%20the%20Minimum%20Game%20Score/README.md) | | 困难 | 第 436 场周赛 | +| 3450 | [一张长椅的上最多学生](/solution/3400-3499/3450.Maximum%20Students%20on%20a%20Single%20Bench/README.md) | | 简单 | 🔒 | ## 版权 diff --git a/solution/README_EN.md b/solution/README_EN.md index c78935faefcd8..d9f44db234e4a 100644 --- a/solution/README_EN.md +++ b/solution/README_EN.md @@ -3458,6 +3458,7 @@ Press Control + F(or Command + F on | 3447 | [Assign Elements to Groups with Constraints](/solution/3400-3499/3447.Assign%20Elements%20to%20Groups%20with%20Constraints/README_EN.md) | | Medium | Weekly Contest 436 | | 3448 | [Count Substrings Divisible By Last Digit](/solution/3400-3499/3448.Count%20Substrings%20Divisible%20By%20Last%20Digit/README_EN.md) | | Hard | Weekly Contest 436 | | 3449 | [Maximize the Minimum Game Score](/solution/3400-3499/3449.Maximize%20the%20Minimum%20Game%20Score/README_EN.md) | | Hard | Weekly Contest 436 | +| 3450 | [Maximum Students on a Single Bench](/solution/3400-3499/3450.Maximum%20Students%20on%20a%20Single%20Bench/README_EN.md) | | Easy | 🔒 | ## Copyright