From dd699e9daa7a31135b4a365ea4d869b380729803 Mon Sep 17 00:00:00 2001 From: Libin YANG Date: Sun, 17 Dec 2023 08:53:31 +0800 Subject: [PATCH 1/8] feat: add solutions to lc problems: No.0746,0747 (#2109) * No.0746.Min Cost Climbing Stairs * No.0747.Largest Number At Least Twice of Others --- .../0746.Min Cost Climbing Stairs/README.md | 155 ++++++++++------- .../README_EN.md | 156 +++++++++++------- .../Solution.cpp | 22 +-- .../0746.Min Cost Climbing Stairs/Solution.go | 8 +- .../Solution.java | 20 +-- .../0746.Min Cost Climbing Stairs/Solution.py | 12 +- .../0746.Min Cost Climbing Stairs/Solution.rs | 11 ++ .../0746.Min Cost Climbing Stairs/Solution.ts | 9 +- .../README.md | 120 ++++++++------ .../README_EN.md | 120 ++++++++------ .../Solution.cpp | 32 ++-- .../Solution.go | 20 +-- .../Solution.java | 31 ++-- .../Solution.js | 19 +-- .../Solution.py | 15 +- .../Solution.ts | 14 ++ 16 files changed, 446 insertions(+), 318 deletions(-) create mode 100644 solution/0700-0799/0746.Min Cost Climbing Stairs/Solution.rs create mode 100644 solution/0700-0799/0747.Largest Number At Least Twice of Others/Solution.ts diff --git a/solution/0700-0799/0746.Min Cost Climbing Stairs/README.md b/solution/0700-0799/0746.Min Cost Climbing Stairs/README.md index a177bcb33bdb1..d200638b31aa2 100644 --- a/solution/0700-0799/0746.Min Cost Climbing Stairs/README.md +++ b/solution/0700-0799/0746.Min Cost Climbing Stairs/README.md @@ -54,19 +54,19 @@ **方法一:动态规划** -定义 `dp[i]` 表示到达第 `i` 个台阶的最小花费。可以得到状态转移方程: +我们定义 $f[i]$ 表示到达第 $i$ 个阶梯所需要的最小花费,初始时 $f[0] = f[1] = 0$,答案即为 $f[n]$。 + +当 $i \ge 2$ 时,我们可以从第 $i - 1$ 个阶梯使用 $1$ 步直接到达第 $i$ 个阶梯,或者从第 $i - 2$ 个阶梯使用 $2$ 步到达第 $i$ 个阶梯,因此我们有状态转移方程: $$ -dp[i] = \min(dp[i - 1] + cost[i - 1], dp[i - 2] + cost[i - 2]) +f[i] = \min(f[i - 1] + cost[i - 1], f[i - 2] + cost[i - 2]) $$ -最终结果为 `dp[n]`。其中 $n$ 表示 `cost` 数组的长度。 - -时间复杂度 $O(n)$,空间复杂度 $O(n)$。 +最终的答案即为 $f[n]$。 -由于 `dp[i]` 只跟 `dp[i-1]` 和 `dp[i-2]` 有关,因此我们还可以对空间进行优化,只用两个变量 `a`, `b` 来记录。 +时间复杂度 $O(n)$,空间复杂度 $O(n)$。其中 $n$ 是数组 `cost` 的长度。 -时间复杂度 $O(n)$,空间复杂度 $O(1)$。 +我们注意到,状态转移方程中的 $f[i]$ 只和 $f[i - 1]$ 与 $f[i - 2]$ 有关,因此我们可以使用两个变量 $f$ 和 $g$ 交替地记录 $f[i - 2]$ 和 $f[i - 1]$ 的值,这样空间复杂度可以优化到 $O(1)$。 @@ -78,19 +78,19 @@ $$ class Solution: def minCostClimbingStairs(self, cost: List[int]) -> int: n = len(cost) - dp = [0] * (n + 1) + f = [0] * (n + 1) for i in range(2, n + 1): - dp[i] = min(dp[i - 1] + cost[i - 1], dp[i - 2] + cost[i - 2]) - return dp[-1] + f[i] = min(f[i - 2] + cost[i - 2], f[i - 1] + cost[i - 1]) + return f[n] ``` ```python class Solution: def minCostClimbingStairs(self, cost: List[int]) -> int: - a = b = 0 - for i in range(1, len(cost)): - a, b = b, min(a + cost[i - 1], b + cost[i]) - return b + f = g = 0 + for i in range(2, len(cost) + 1): + f, g = g, min(f + cost[i - 2], g + cost[i - 1]) + return g ``` ### **Java** @@ -101,11 +101,11 @@ class Solution: class Solution { public int minCostClimbingStairs(int[] cost) { int n = cost.length; - int[] dp = new int[n + 1]; + int[] f = new int[n + 1]; for (int i = 2; i <= n; ++i) { - dp[i] = Math.min(dp[i - 1] + cost[i - 1], dp[i - 2] + cost[i - 2]); + f[i] = Math.min(f[i - 2] + cost[i - 2], f[i - 1] + cost[i - 1]); } - return dp[n]; + return f[n]; } } ``` @@ -113,38 +113,14 @@ class Solution { ```java class Solution { public int minCostClimbingStairs(int[] cost) { - int a = 0, b = 0; - for (int i = 1; i < cost.length; ++i) { - int c = Math.min(a + cost[i - 1], b + cost[i]); - a = b; - b = c; + int f = 0, g = 0; + for (int i = 2; i <= cost.length; ++i) { + int gg = Math.min(f + cost[i - 2], g + cost[i - 1]); + f = g; + g = gg; } - return b; - } -} -``` - -### **TypeScript** - -```ts -function minCostClimbingStairs(cost: number[]): number { - const n = cost.length; - const dp = new Array(n + 1).fill(0); - for (let i = 2; i <= n; ++i) { - dp[i] = Math.min(dp[i - 1] + cost[i - 1], dp[i - 2] + cost[i - 2]); - } - return dp[n]; -} -``` - -```ts -function minCostClimbingStairs(cost: number[]): number { - let a = 0, - b = 0; - for (let i = 1; i < cost.length; ++i) { - [a, b] = [b, Math.min(a + cost[i - 1], b + cost[i])]; + return g; } - return b; } ``` @@ -155,11 +131,11 @@ class Solution { public: int minCostClimbingStairs(vector& cost) { int n = cost.size(); - vector dp(n + 1); + vector f(n + 1); for (int i = 2; i <= n; ++i) { - dp[i] = min(dp[i - 1] + cost[i - 1], dp[i - 2] + cost[i - 2]); + f[i] = min(f[i - 2] + cost[i - 2], f[i - 1] + cost[i - 1]); } - return dp[n]; + return f[n]; } }; ``` @@ -168,13 +144,13 @@ public: class Solution { public: int minCostClimbingStairs(vector& cost) { - int a = 0, b = 0; - for (int i = 1; i < cost.size(); ++i) { - int c = min(a + cost[i - 1], b + cost[i]); - a = b; - b = c; + int f = 0, g = 0; + for (int i = 2; i <= cost.size(); ++i) { + int gg = min(f + cost[i - 2], g + cost[i - 1]); + f = g; + g = gg; } - return b; + return g; } }; ``` @@ -184,21 +160,74 @@ public: ```go func minCostClimbingStairs(cost []int) int { n := len(cost) - dp := make([]int, n+1) + f := make([]int, n+1) for i := 2; i <= n; i++ { - dp[i] = min(dp[i-1]+cost[i-1], dp[i-2]+cost[i-2]) + f[i] = min(f[i-1]+cost[i-1], f[i-2]+cost[i-2]) } - return dp[n] + return f[n] } ``` ```go func minCostClimbingStairs(cost []int) int { - a, b := 0, 0 - for i := 1; i < len(cost); i++ { - a, b = b, min(a+cost[i-1], b+cost[i]) + var f, g int + for i := 2; i <= n; i++ { + f, g = g, min(f+cost[i-2], g+cost[i-1]) } - return b + return g +} +``` + +### **TypeScript** + +```ts +function minCostClimbingStairs(cost: number[]): number { + const n = cost.length; + const f: number[] = Array(n + 1).fill(0); + for (let i = 2; i <= n; ++i) { + f[i] = Math.min(f[i - 1] + cost[i - 1], f[i - 2] + cost[i - 2]); + } + return f[n]; +} +``` + +```ts +function minCostClimbingStairs(cost: number[]): number { + let a = 0, + b = 0; + for (let i = 1; i < cost.length; ++i) { + [a, b] = [b, Math.min(a + cost[i - 1], b + cost[i])]; + } + return b; +} +``` + +### **Rust** + +```rust +impl Solution { + pub fn min_cost_climbing_stairs(cost: Vec) -> i32 { + let n = cost.len(); + let mut f = vec![0; n + 1]; + for i in 2..=n { + f[i] = std::cmp::min(f[i - 2] + cost[i - 2], f[i - 1] + cost[i - 1]); + } + f[n] + } +} +``` + +```rust +impl Solution { + pub fn min_cost_climbing_stairs(cost: Vec) -> i32 { + let (mut f, mut g) = (0, 0); + for i in 2..=cost.len() { + let gg = std::cmp::min(f + cost[i - 2], g + cost[i - 1]); + f = g; + g = gg; + } + g + } } ``` diff --git a/solution/0700-0799/0746.Min Cost Climbing Stairs/README_EN.md b/solution/0700-0799/0746.Min Cost Climbing Stairs/README_EN.md index 4212825f450fd..583c3645935ba 100644 --- a/solution/0700-0799/0746.Min Cost Climbing Stairs/README_EN.md +++ b/solution/0700-0799/0746.Min Cost Climbing Stairs/README_EN.md @@ -46,6 +46,22 @@ The total cost is 6. ## Solutions +**Solution 1: Dynamic Programming** + +We define $f[i]$ as the minimum cost required to reach the $i$th step, initially $f[0] = f[1] = 0$. The answer is $f[n]$. + +When $i \ge 2$, we can directly reach the $i$th step from the $(i - 1)$th step using $1$ step, or reach the $i$th step from the $(i - 2)$th step using $2$ steps. Therefore, we have the state transition equation: + +$$ +f[i] = \min(f[i - 1] + cost[i - 1], f[i - 2] + cost[i - 2]) +$$ + +The final answer is $f[n]$. + +The time complexity is $O(n)$, and the space complexity is $O(n)$. Here, $n$ is the length of the `cost` array. + +We notice that $f[i]$ in the state transition equation is only related to $f[i - 1]$ and $f[i - 2]$. Therefore, we can use two variables $f$ and $g$ to alternately record the values of $f[i - 2]$ and $f[i - 1]$, which optimizes the space complexity to $O(1)$. + ### **Python3** @@ -54,19 +70,19 @@ The total cost is 6. class Solution: def minCostClimbingStairs(self, cost: List[int]) -> int: n = len(cost) - dp = [0] * (n + 1) + f = [0] * (n + 1) for i in range(2, n + 1): - dp[i] = min(dp[i - 1] + cost[i - 1], dp[i - 2] + cost[i - 2]) - return dp[-1] + f[i] = min(f[i - 2] + cost[i - 2], f[i - 1] + cost[i - 1]) + return f[n] ``` ```python class Solution: def minCostClimbingStairs(self, cost: List[int]) -> int: - a = b = 0 - for i in range(1, len(cost)): - a, b = b, min(a + cost[i - 1], b + cost[i]) - return b + f = g = 0 + for i in range(2, len(cost) + 1): + f, g = g, min(f + cost[i - 2], g + cost[i - 1]) + return g ``` ### **Java** @@ -75,11 +91,11 @@ class Solution: class Solution { public int minCostClimbingStairs(int[] cost) { int n = cost.length; - int[] dp = new int[n + 1]; + int[] f = new int[n + 1]; for (int i = 2; i <= n; ++i) { - dp[i] = Math.min(dp[i - 1] + cost[i - 1], dp[i - 2] + cost[i - 2]); + f[i] = Math.min(f[i - 2] + cost[i - 2], f[i - 1] + cost[i - 1]); } - return dp[n]; + return f[n]; } } ``` @@ -87,38 +103,14 @@ class Solution { ```java class Solution { public int minCostClimbingStairs(int[] cost) { - int a = 0, b = 0; - for (int i = 1; i < cost.length; ++i) { - int c = Math.min(a + cost[i - 1], b + cost[i]); - a = b; - b = c; + int f = 0, g = 0; + for (int i = 2; i <= cost.length; ++i) { + int gg = Math.min(f + cost[i - 2], g + cost[i - 1]); + f = g; + g = gg; } - return b; - } -} -``` - -### **TypeScript** - -```ts -function minCostClimbingStairs(cost: number[]): number { - const n = cost.length; - const dp = new Array(n + 1).fill(0); - for (let i = 2; i <= n; ++i) { - dp[i] = Math.min(dp[i - 1] + cost[i - 1], dp[i - 2] + cost[i - 2]); + return g; } - return dp[n]; -} -``` - -```ts -function minCostClimbingStairs(cost: number[]): number { - let a = 0, - b = 0; - for (let i = 1; i < cost.length; ++i) { - [a, b] = [b, Math.min(a + cost[i - 1], b + cost[i])]; - } - return b; } ``` @@ -129,11 +121,11 @@ class Solution { public: int minCostClimbingStairs(vector& cost) { int n = cost.size(); - vector dp(n + 1); + vector f(n + 1); for (int i = 2; i <= n; ++i) { - dp[i] = min(dp[i - 1] + cost[i - 1], dp[i - 2] + cost[i - 2]); + f[i] = min(f[i - 2] + cost[i - 2], f[i - 1] + cost[i - 1]); } - return dp[n]; + return f[n]; } }; ``` @@ -142,13 +134,13 @@ public: class Solution { public: int minCostClimbingStairs(vector& cost) { - int a = 0, b = 0; - for (int i = 1; i < cost.size(); ++i) { - int c = min(a + cost[i - 1], b + cost[i]); - a = b; - b = c; + int f = 0, g = 0; + for (int i = 2; i <= cost.size(); ++i) { + int gg = min(f + cost[i - 2], g + cost[i - 1]); + f = g; + g = gg; } - return b; + return g; } }; ``` @@ -158,21 +150,73 @@ public: ```go func minCostClimbingStairs(cost []int) int { n := len(cost) - dp := make([]int, n+1) + f := make([]int, n+1) for i := 2; i <= n; i++ { - dp[i] = min(dp[i-1]+cost[i-1], dp[i-2]+cost[i-2]) + f[i] = min(f[i-1]+cost[i-1], f[i-2]+cost[i-2]) } - return dp[n] + return f[n] } ``` ```go func minCostClimbingStairs(cost []int) int { - a, b := 0, 0 - for i := 1; i < len(cost); i++ { - a, b = b, min(a+cost[i-1], b+cost[i]) + var f, g int + for i := 2; i <= n; i++ { + f, g = g, min(f+cost[i-2], g+cost[i-1]) } - return b + return g +} +``` + +### **TypeScript** + +```ts +function minCostClimbingStairs(cost: number[]): number { + const n = cost.length; + const f: number[] = Array(n + 1).fill(0); + for (let i = 2; i <= n; ++i) { + f[i] = Math.min(f[i - 1] + cost[i - 1], f[i - 2] + cost[i - 2]); + } + return f[n]; +} +``` + +```ts +function minCostClimbingStairs(cost: number[]): number { + let [f, g] = [0, 0]; + for (let i = 2; i <= cost.length; ++i) { + [f, g] = [g, Math.min(f + cost[i - 2], g + cost[i - 1])]; + } + return g; +} +``` + +### **Rust** + +```rust +impl Solution { + pub fn min_cost_climbing_stairs(cost: Vec) -> i32 { + let n = cost.len(); + let mut f = vec![0; n + 1]; + for i in 2..=n { + f[i] = std::cmp::min(f[i - 2] + cost[i - 2], f[i - 1] + cost[i - 1]); + } + f[n] + } +} +``` + +```rust +impl Solution { + pub fn min_cost_climbing_stairs(cost: Vec) -> i32 { + let (mut f, mut g) = (0, 0); + for i in 2..=cost.len() { + let gg = std::cmp::min(f + cost[i - 2], g + cost[i - 1]); + f = g; + g = gg; + } + g + } } ``` diff --git a/solution/0700-0799/0746.Min Cost Climbing Stairs/Solution.cpp b/solution/0700-0799/0746.Min Cost Climbing Stairs/Solution.cpp index 4908ed9e240d4..3e83bd9c0896d 100644 --- a/solution/0700-0799/0746.Min Cost Climbing Stairs/Solution.cpp +++ b/solution/0700-0799/0746.Min Cost Climbing Stairs/Solution.cpp @@ -1,12 +1,12 @@ -class Solution { -public: - int minCostClimbingStairs(vector& cost) { - int a = 0, b = 0; - for (int i = 1; i < cost.size(); ++i) { - int c = min(a + cost[i - 1], b + cost[i]); - a = b; - b = c; - } - return b; - } +class Solution { +public: + int minCostClimbingStairs(vector& cost) { + int f = 0, g = 0; + for (int i = 2; i <= cost.size(); ++i) { + int gg = min(f + cost[i - 2], g + cost[i - 1]); + f = g; + g = gg; + } + return g; + } }; \ No newline at end of file diff --git a/solution/0700-0799/0746.Min Cost Climbing Stairs/Solution.go b/solution/0700-0799/0746.Min Cost Climbing Stairs/Solution.go index 5eeec3b9006e3..24764a4c60f57 100644 --- a/solution/0700-0799/0746.Min Cost Climbing Stairs/Solution.go +++ b/solution/0700-0799/0746.Min Cost Climbing Stairs/Solution.go @@ -1,7 +1,7 @@ func minCostClimbingStairs(cost []int) int { - a, b := 0, 0 - for i := 1; i < len(cost); i++ { - a, b = b, min(a+cost[i-1], b+cost[i]) + var f, g int + for i := 2; i <= n; i++ { + f, g = g, min(f+cost[i-2], g+cost[i-1]) } - return b + return g } \ No newline at end of file diff --git a/solution/0700-0799/0746.Min Cost Climbing Stairs/Solution.java b/solution/0700-0799/0746.Min Cost Climbing Stairs/Solution.java index 85369621c102e..78e778bcf49d3 100644 --- a/solution/0700-0799/0746.Min Cost Climbing Stairs/Solution.java +++ b/solution/0700-0799/0746.Min Cost Climbing Stairs/Solution.java @@ -1,11 +1,11 @@ -class Solution { - public int minCostClimbingStairs(int[] cost) { - int a = 0, b = 0; - for (int i = 1; i < cost.length; ++i) { - int c = Math.min(a + cost[i - 1], b + cost[i]); - a = b; - b = c; - } - return b; - } +class Solution { + public int minCostClimbingStairs(int[] cost) { + int f = 0, g = 0; + for (int i = 2; i <= cost.length; ++i) { + int gg = Math.min(f + cost[i - 2], g + cost[i - 1]); + f = g; + g = gg; + } + return g; + } } \ No newline at end of file diff --git a/solution/0700-0799/0746.Min Cost Climbing Stairs/Solution.py b/solution/0700-0799/0746.Min Cost Climbing Stairs/Solution.py index 5166afc4fd42e..ae51a443d9f8e 100644 --- a/solution/0700-0799/0746.Min Cost Climbing Stairs/Solution.py +++ b/solution/0700-0799/0746.Min Cost Climbing Stairs/Solution.py @@ -1,6 +1,6 @@ -class Solution: - def minCostClimbingStairs(self, cost: List[int]) -> int: - a = b = 0 - for i in range(1, len(cost)): - a, b = b, min(a + cost[i - 1], b + cost[i]) - return b +class Solution: + def minCostClimbingStairs(self, cost: List[int]) -> int: + f = g = 0 + for i in range(2, len(cost) + 1): + f, g = g, min(f + cost[i - 2], g + cost[i - 1]) + return g diff --git a/solution/0700-0799/0746.Min Cost Climbing Stairs/Solution.rs b/solution/0700-0799/0746.Min Cost Climbing Stairs/Solution.rs new file mode 100644 index 0000000000000..5d62ffd744c5c --- /dev/null +++ b/solution/0700-0799/0746.Min Cost Climbing Stairs/Solution.rs @@ -0,0 +1,11 @@ +impl Solution { + pub fn min_cost_climbing_stairs(cost: Vec) -> i32 { + let (mut f, mut g) = (0, 0); + for i in 2..=cost.len() { + let gg = std::cmp::min(f + cost[i - 2], g + cost[i - 1]); + f = g; + g = gg; + } + g + } +} diff --git a/solution/0700-0799/0746.Min Cost Climbing Stairs/Solution.ts b/solution/0700-0799/0746.Min Cost Climbing Stairs/Solution.ts index 2b133cba36647..dc38fa0f3da7f 100644 --- a/solution/0700-0799/0746.Min Cost Climbing Stairs/Solution.ts +++ b/solution/0700-0799/0746.Min Cost Climbing Stairs/Solution.ts @@ -1,8 +1,7 @@ function minCostClimbingStairs(cost: number[]): number { - let a = 0, - b = 0; - for (let i = 1; i < cost.length; ++i) { - [a, b] = [b, Math.min(a + cost[i - 1], b + cost[i])]; + let [f, g] = [0, 0]; + for (let i = 2; i <= cost.length; ++i) { + [f, g] = [g, Math.min(f + cost[i - 2], g + cost[i - 1])]; } - return b; + return g; } diff --git a/solution/0700-0799/0747.Largest Number At Least Twice of Others/README.md b/solution/0700-0799/0747.Largest Number At Least Twice of Others/README.md index 6be746334bf5a..aeb3d49369c01 100644 --- a/solution/0700-0799/0747.Largest Number At Least Twice of Others/README.md +++ b/solution/0700-0799/0747.Largest Number At Least Twice of Others/README.md @@ -42,7 +42,13 @@ -遍历数组找到最大值和次大值,最后判断是否满足条件即可。 +**方法一:遍历** + +我们可以遍历数组 $nums$,找到数组中的最大值 $x$ 和第二大的值 $y$,如果 $x \ge 2y$,则返回 $x$ 的下标,否则返回 $-1$。 + +我们也可以先找到数组中的最大值 $x$,同时找到最大值 $x$ 的下标 $k$。然后再遍历一次数组,如果发现 $k$ 以外的元素 $y$ 满足 $x < 2y$,则返回 $-1$。否则遍历结束后返回 $k$。 + +时间复杂度 $O(n)$,其中 $n$ 是数组 $nums$ 的长度。空间复杂度 $O(1)$。 @@ -53,15 +59,8 @@ ```python class Solution: def dominantIndex(self, nums: List[int]) -> int: - mx = mid = 0 - ans = -1 - for i, v in enumerate(nums): - if v > mx: - mid, mx = mx, v - ans = i - elif v > mid: - mid = v - return ans if mx >= 2 * mid else -1 + x, y = nlargest(2, nums) + return nums.index(x) if x >= 2 * y else -1 ``` ### **Java** @@ -71,18 +70,19 @@ class Solution: ```java class Solution { public int dominantIndex(int[] nums) { - int mx = 0, mid = 0; - int ans = -1; - for (int i = 0; i < nums.length; ++i) { - if (nums[i] > mx) { - mid = mx; - mx = nums[i]; - ans = i; - } else if (nums[i] > mid) { - mid = nums[i]; + int n = nums.length; + int k = 0; + for (int i = 0; i < n; ++i) { + if (nums[k] < nums[i]) { + k = i; } } - return mx >= mid * 2 ? ans : -1; + for (int i = 0; i < n; ++i) { + if (k != i && nums[k] < nums[i] * 2) { + return -1; + } + } + return k; } } ``` @@ -93,17 +93,19 @@ class Solution { class Solution { public: int dominantIndex(vector& nums) { - int mx = 0, mid = 0; - int ans = 0; - for (int i = 0; i < nums.size(); ++i) { - if (nums[i] > mx) { - mid = mx; - mx = nums[i]; - ans = i; - } else if (nums[i] > mid) - mid = nums[i]; + int n = nums.size(); + int k = 0; + for (int i = 0; i < n; ++i) { + if (nums[k] < nums[i]) { + k = i; + } } - return mx >= mid * 2 ? ans : -1; + for (int i = 0; i < n; ++i) { + if (k != i && nums[k] < nums[i] * 2) { + return -1; + } + } + return k; } }; ``` @@ -112,20 +114,37 @@ public: ```go func dominantIndex(nums []int) int { - mx, mid := 0, 0 - ans := 0 - for i, v := range nums { - if v > mx { - mid, mx = mx, v - ans = i - } else if v > mid { - mid = v + k := 0 + for i, x := range nums { + if nums[k] < x { + k = i } } - if mx >= mid*2 { - return ans + for i, x := range nums { + if k != i && nums[k] < x*2 { + return -1 + } } - return -1 + return k +} +``` + +### **TypeScript** + +```ts +function dominantIndex(nums: number[]): number { + let k = 0; + for (let i = 0; i < nums.length; ++i) { + if (nums[i] > nums[k]) { + k = i; + } + } + for (let i = 0; i < nums.length; ++i) { + if (i !== k && nums[k] < nums[i] * 2) { + return -1; + } + } + return k; } ``` @@ -137,19 +156,18 @@ func dominantIndex(nums []int) int { * @return {number} */ var dominantIndex = function (nums) { - let mx = 0, - mid = 0; - let ans = 0; + let k = 0; + for (let i = 0; i < nums.length; ++i) { + if (nums[i] > nums[k]) { + k = i; + } + } for (let i = 0; i < nums.length; ++i) { - if (nums[i] > mx) { - mid = mx; - mx = nums[i]; - ans = i; - } else if (nums[i] > mid) { - mid = nums[i]; + if (i !== k && nums[k] < nums[i] * 2) { + return -1; } } - return mx >= mid * 2 ? ans : -1; + return k; }; ``` diff --git a/solution/0700-0799/0747.Largest Number At Least Twice of Others/README_EN.md b/solution/0700-0799/0747.Largest Number At Least Twice of Others/README_EN.md index 70756a6655869..098ab39966fff 100644 --- a/solution/0700-0799/0747.Largest Number At Least Twice of Others/README_EN.md +++ b/solution/0700-0799/0747.Largest Number At Least Twice of Others/README_EN.md @@ -38,6 +38,14 @@ The index of value 6 is 1, so we return 1. ## Solutions +**Solution 1: Traversal** + +We can traverse the array $nums$ to find the maximum value $x$ and the second largest value $y$ in the array. If $x \ge 2y$, then return the index of $x$, otherwise return $-1$. + +We can also first find the maximum value $x$ in the array and find the index $k$ of the maximum value $x$ at the same time. Then traverse the array again. If we find an element $y$ outside of $k$ that satisfies $x < 2y$, then return $-1$. Otherwise, return $k$ after the traversal ends. + +The time complexity is $O(n)$, where $n$ is the length of the array $nums$. The space complexity is $O(1)$. + ### **Python3** @@ -45,15 +53,8 @@ The index of value 6 is 1, so we return 1. ```python class Solution: def dominantIndex(self, nums: List[int]) -> int: - mx = mid = 0 - ans = -1 - for i, v in enumerate(nums): - if v > mx: - mid, mx = mx, v - ans = i - elif v > mid: - mid = v - return ans if mx >= 2 * mid else -1 + x, y = nlargest(2, nums) + return nums.index(x) if x >= 2 * y else -1 ``` ### **Java** @@ -61,18 +62,19 @@ class Solution: ```java class Solution { public int dominantIndex(int[] nums) { - int mx = 0, mid = 0; - int ans = -1; - for (int i = 0; i < nums.length; ++i) { - if (nums[i] > mx) { - mid = mx; - mx = nums[i]; - ans = i; - } else if (nums[i] > mid) { - mid = nums[i]; + int n = nums.length; + int k = 0; + for (int i = 0; i < n; ++i) { + if (nums[k] < nums[i]) { + k = i; + } + } + for (int i = 0; i < n; ++i) { + if (k != i && nums[k] < nums[i] * 2) { + return -1; } } - return mx >= mid * 2 ? ans : -1; + return k; } } ``` @@ -83,17 +85,19 @@ class Solution { class Solution { public: int dominantIndex(vector& nums) { - int mx = 0, mid = 0; - int ans = 0; - for (int i = 0; i < nums.size(); ++i) { - if (nums[i] > mx) { - mid = mx; - mx = nums[i]; - ans = i; - } else if (nums[i] > mid) - mid = nums[i]; + int n = nums.size(); + int k = 0; + for (int i = 0; i < n; ++i) { + if (nums[k] < nums[i]) { + k = i; + } + } + for (int i = 0; i < n; ++i) { + if (k != i && nums[k] < nums[i] * 2) { + return -1; + } } - return mx >= mid * 2 ? ans : -1; + return k; } }; ``` @@ -102,20 +106,37 @@ public: ```go func dominantIndex(nums []int) int { - mx, mid := 0, 0 - ans := 0 - for i, v := range nums { - if v > mx { - mid, mx = mx, v - ans = i - } else if v > mid { - mid = v + k := 0 + for i, x := range nums { + if nums[k] < x { + k = i } } - if mx >= mid*2 { - return ans + for i, x := range nums { + if k != i && nums[k] < x*2 { + return -1 + } } - return -1 + return k +} +``` + +### **TypeScript** + +```ts +function dominantIndex(nums: number[]): number { + let k = 0; + for (let i = 0; i < nums.length; ++i) { + if (nums[i] > nums[k]) { + k = i; + } + } + for (let i = 0; i < nums.length; ++i) { + if (i !== k && nums[k] < nums[i] * 2) { + return -1; + } + } + return k; } ``` @@ -127,19 +148,18 @@ func dominantIndex(nums []int) int { * @return {number} */ var dominantIndex = function (nums) { - let mx = 0, - mid = 0; - let ans = 0; + let k = 0; + for (let i = 0; i < nums.length; ++i) { + if (nums[i] > nums[k]) { + k = i; + } + } for (let i = 0; i < nums.length; ++i) { - if (nums[i] > mx) { - mid = mx; - mx = nums[i]; - ans = i; - } else if (nums[i] > mid) { - mid = nums[i]; + if (i !== k && nums[k] < nums[i] * 2) { + return -1; } } - return mx >= mid * 2 ? ans : -1; + return k; }; ``` diff --git a/solution/0700-0799/0747.Largest Number At Least Twice of Others/Solution.cpp b/solution/0700-0799/0747.Largest Number At Least Twice of Others/Solution.cpp index 3e00c2f9a9f15..6f58941b1b216 100644 --- a/solution/0700-0799/0747.Largest Number At Least Twice of Others/Solution.cpp +++ b/solution/0700-0799/0747.Largest Number At Least Twice of Others/Solution.cpp @@ -1,16 +1,18 @@ -class Solution { -public: - int dominantIndex(vector& nums) { - int mx = 0, mid = 0; - int ans = 0; - for (int i = 0; i < nums.size(); ++i) { - if (nums[i] > mx) { - mid = mx; - mx = nums[i]; - ans = i; - } else if (nums[i] > mid) - mid = nums[i]; - } - return mx >= mid * 2 ? ans : -1; - } +class Solution { +public: + int dominantIndex(vector& nums) { + int n = nums.size(); + int k = 0; + for (int i = 0; i < n; ++i) { + if (nums[k] < nums[i]) { + k = i; + } + } + for (int i = 0; i < n; ++i) { + if (k != i && nums[k] < nums[i] * 2) { + return -1; + } + } + return k; + } }; \ No newline at end of file diff --git a/solution/0700-0799/0747.Largest Number At Least Twice of Others/Solution.go b/solution/0700-0799/0747.Largest Number At Least Twice of Others/Solution.go index 158c453ccf75e..69865c6d7b6d6 100644 --- a/solution/0700-0799/0747.Largest Number At Least Twice of Others/Solution.go +++ b/solution/0700-0799/0747.Largest Number At Least Twice of Others/Solution.go @@ -1,16 +1,14 @@ func dominantIndex(nums []int) int { - mx, mid := 0, 0 - ans := 0 - for i, v := range nums { - if v > mx { - mid, mx = mx, v - ans = i - } else if v > mid { - mid = v + k := 0 + for i, x := range nums { + if nums[k] < x { + k = i } } - if mx >= mid*2 { - return ans + for i, x := range nums { + if k != i && nums[k] < x*2 { + return -1 + } } - return -1 + return k } \ No newline at end of file diff --git a/solution/0700-0799/0747.Largest Number At Least Twice of Others/Solution.java b/solution/0700-0799/0747.Largest Number At Least Twice of Others/Solution.java index 5fdb66df1adf7..1ba2fe8e8acbb 100644 --- a/solution/0700-0799/0747.Largest Number At Least Twice of Others/Solution.java +++ b/solution/0700-0799/0747.Largest Number At Least Twice of Others/Solution.java @@ -1,16 +1,17 @@ -class Solution { - public int dominantIndex(int[] nums) { - int mx = Integer.MIN_VALUE, mid = Integer.MIN_VALUE; - int ans = -1; - for (int i = 0; i < nums.length; ++i) { - if (nums[i] > mx) { - mid = mx; - mx = nums[i]; - ans = i; - } else if (nums[i] > mid) { - mid = nums[i]; - } - } - return mx >= mid * 2 ? ans : -1; - } +class Solution { + public int dominantIndex(int[] nums) { + int n = nums.length; + int k = 0; + for (int i = 0; i < n; ++i) { + if (nums[k] < nums[i]) { + k = i; + } + } + for (int i = 0; i < n; ++i) { + if (k != i && nums[k] < nums[i] * 2) { + return -1; + } + } + return k; + } } \ No newline at end of file diff --git a/solution/0700-0799/0747.Largest Number At Least Twice of Others/Solution.js b/solution/0700-0799/0747.Largest Number At Least Twice of Others/Solution.js index 81b980dd548bb..78436921e6505 100644 --- a/solution/0700-0799/0747.Largest Number At Least Twice of Others/Solution.js +++ b/solution/0700-0799/0747.Largest Number At Least Twice of Others/Solution.js @@ -3,17 +3,16 @@ * @return {number} */ var dominantIndex = function (nums) { - let mx = 0, - mid = 0; - let ans = 0; + let k = 0; for (let i = 0; i < nums.length; ++i) { - if (nums[i] > mx) { - mid = mx; - mx = nums[i]; - ans = i; - } else if (nums[i] > mid) { - mid = nums[i]; + if (nums[i] > nums[k]) { + k = i; } } - return mx >= mid * 2 ? ans : -1; + for (let i = 0; i < nums.length; ++i) { + if (i !== k && nums[k] < nums[i] * 2) { + return -1; + } + } + return k; }; diff --git a/solution/0700-0799/0747.Largest Number At Least Twice of Others/Solution.py b/solution/0700-0799/0747.Largest Number At Least Twice of Others/Solution.py index 3b4e284e4ad0e..3c23b293c01f8 100644 --- a/solution/0700-0799/0747.Largest Number At Least Twice of Others/Solution.py +++ b/solution/0700-0799/0747.Largest Number At Least Twice of Others/Solution.py @@ -1,11 +1,4 @@ -class Solution: - def dominantIndex(self, nums: List[int]) -> int: - mx = mid = 0 - ans = -1 - for i, v in enumerate(nums): - if v > mx: - mid, mx = mx, v - ans = i - elif v > mid: - mid = v - return ans if mx >= 2 * mid else -1 +class Solution: + def dominantIndex(self, nums: List[int]) -> int: + x, y = nlargest(2, nums) + return nums.index(x) if x >= 2 * y else -1 diff --git a/solution/0700-0799/0747.Largest Number At Least Twice of Others/Solution.ts b/solution/0700-0799/0747.Largest Number At Least Twice of Others/Solution.ts new file mode 100644 index 0000000000000..22531648076f9 --- /dev/null +++ b/solution/0700-0799/0747.Largest Number At Least Twice of Others/Solution.ts @@ -0,0 +1,14 @@ +function dominantIndex(nums: number[]): number { + let k = 0; + for (let i = 0; i < nums.length; ++i) { + if (nums[i] > nums[k]) { + k = i; + } + } + for (let i = 0; i < nums.length; ++i) { + if (i !== k && nums[k] < nums[i] * 2) { + return -1; + } + } + return k; +} From 0d35c05bee314813b89d5c55b3ccff35bfe5f2db Mon Sep 17 00:00:00 2001 From: Herschel Date: Sun, 17 Dec 2023 09:12:59 +0800 Subject: [PATCH 2/8] feat: add rust solution to lc problem: No.60 (#2106) --- .../0060.Permutation Sequence/README.md | 34 +++++++++++++++++++ .../0060.Permutation Sequence/README_EN.md | 34 +++++++++++++++++++ .../0060.Permutation Sequence/Solution.rs | 29 ++++++++++++++++ 3 files changed, 97 insertions(+) create mode 100644 solution/0000-0099/0060.Permutation Sequence/Solution.rs diff --git a/solution/0000-0099/0060.Permutation Sequence/README.md b/solution/0000-0099/0060.Permutation Sequence/README.md index 8d18182a67cac..b8f0a8c3358a9 100644 --- a/solution/0000-0099/0060.Permutation Sequence/README.md +++ b/solution/0000-0099/0060.Permutation Sequence/README.md @@ -207,6 +207,40 @@ public class Solution { } ``` +### **Rust** + +```rust +impl Solution { + pub fn get_permutation(n: i32, k: i32) -> String { + let mut k = k; + let mut ans = String::new(); + let mut fact = vec![1; n as usize]; + for i in 1..n as usize { + fact[i] = fact[i - 1] * (i as i32); + } + let mut vis = vec![false; n as usize + 1]; + + for i in 0..n as usize { + let cnt = fact[(n as usize) - i - 1]; + for j in 1..=n { + if vis[j as usize] { + continue; + } + if k > cnt { + k -= cnt; + } else { + ans.push_str(&j.to_string()); + vis[j as usize] = true; + break; + } + } + } + + ans + } +} +``` + ### **...** ``` diff --git a/solution/0000-0099/0060.Permutation Sequence/README_EN.md b/solution/0000-0099/0060.Permutation Sequence/README_EN.md index 2592152c51554..99d568056ded4 100644 --- a/solution/0000-0099/0060.Permutation Sequence/README_EN.md +++ b/solution/0000-0099/0060.Permutation Sequence/README_EN.md @@ -186,6 +186,40 @@ public class Solution { } ``` +### **Rust** + +```rust +impl Solution { + pub fn get_permutation(n: i32, k: i32) -> String { + let mut k = k; + let mut ans = String::new(); + let mut fact = vec![1; n as usize]; + for i in 1..n as usize { + fact[i] = fact[i - 1] * (i as i32); + } + let mut vis = vec![false; n as usize + 1]; + + for i in 0..n as usize { + let cnt = fact[(n as usize) - i - 1]; + for j in 1..=n { + if vis[j as usize] { + continue; + } + if k > cnt { + k -= cnt; + } else { + ans.push_str(&j.to_string()); + vis[j as usize] = true; + break; + } + } + } + + ans + } +} +``` + ### **...** ``` diff --git a/solution/0000-0099/0060.Permutation Sequence/Solution.rs b/solution/0000-0099/0060.Permutation Sequence/Solution.rs new file mode 100644 index 0000000000000..6d43aa728c022 --- /dev/null +++ b/solution/0000-0099/0060.Permutation Sequence/Solution.rs @@ -0,0 +1,29 @@ +impl Solution { + pub fn get_permutation(n: i32, k: i32) -> String { + let mut k = k; + let mut ans = String::new(); + let mut fact = vec![1; n as usize]; + for i in 1..n as usize { + fact[i] = fact[i - 1] * (i as i32); + } + let mut vis = vec![false; n as usize + 1]; + + for i in 0..n as usize { + let cnt = fact[(n as usize) - i - 1]; + for j in 1..=n { + if vis[j as usize] { + continue; + } + if k > cnt { + k -= cnt; + } else { + ans.push_str(&j.to_string()); + vis[j as usize] = true; + break; + } + } + } + + ans + } +} From 30a16289d689a2234dee384a226006bfc530b57d Mon Sep 17 00:00:00 2001 From: Libin YANG Date: Sun, 17 Dec 2023 10:13:31 +0800 Subject: [PATCH 3/8] feat: add solutions to lc problem: No.0748 (#2110) No.0748.Shortest Completing Word --- .../0748.Shortest Completing Word/README.md | 250 +++++++++++------- .../README_EN.md | 250 +++++++++++------- .../Solution.cpp | 62 ++--- .../0748.Shortest Completing Word/Solution.go | 49 ++-- .../Solution.java | 67 +++-- .../0748.Shortest Completing Word/Solution.py | 35 +-- .../0748.Shortest Completing Word/Solution.rs | 31 +++ .../0748.Shortest Completing Word/Solution.ts | 30 +++ .../README_EN.md | 6 + 9 files changed, 465 insertions(+), 315 deletions(-) create mode 100644 solution/0700-0799/0748.Shortest Completing Word/Solution.rs create mode 100644 solution/0700-0799/0748.Shortest Completing Word/Solution.ts diff --git a/solution/0700-0799/0748.Shortest Completing Word/README.md b/solution/0700-0799/0748.Shortest Completing Word/README.md index 3392b5ea2aad0..f25b4ee1a2d6b 100644 --- a/solution/0700-0799/0748.Shortest Completing Word/README.md +++ b/solution/0700-0799/0748.Shortest Completing Word/README.md @@ -52,6 +52,14 @@ +**方法一:计数** + +我们先用哈希表或者一个长度为 $26$ 的数组 $cnt$ 统计字符串 `licensePlate` 中每个字母出现的次数,注意这里我们统一将字母转换为小写进行计数。 + +然后,我们遍历数组 `words` 中的每个单词 $w$,如果单词 $w$ 的长度比答案 $ans$ 的长度长,那么我们直接跳过该单词。否则,我们再用哈希表或者一个长度为 $26$ 的数组 $t$ 统计单词 $w$ 中每个字母出现的次数。如果对于任意一个字母,$t$ 中该字母出现的次数小于 $cnt$ 中该字母出现的次数,那么我们也可以直接跳过该单词。否则,我们就找到了一个满足条件的单词,我们更新答案 $ans$ 为当前单词 $w$。 + +时间复杂度 $O(n \times |\Sigma|)$,空间复杂度 $O(|\Sigma|)$,其中 $n$ 是数组 `words` 的长度,而 $\Sigma$ 是字符集,这里字符集为所有小写字母,因此 $|\Sigma| = 26$。 + ### **Python3** @@ -61,27 +69,14 @@ ```python class Solution: def shortestCompletingWord(self, licensePlate: str, words: List[str]) -> str: - def count(word): - counter = [0] * 26 - for c in word: - counter[ord(c) - ord('a')] += 1 - return counter - - def check(counter1, counter2): - for i in range(26): - if counter1[i] > counter2[i]: - return False - return True - - counter = count(c.lower() for c in licensePlate if c.isalpha()) - ans, n = None, 16 - for word in words: - if n <= len(word): + cnt = Counter(c.lower() for c in licensePlate if c.isalpha()) + ans = None + for w in words: + if ans and len(w) >= len(ans): continue - t = count(word) - if check(counter, t): - n = len(word) - ans = word + t = Counter(w) + if all(v <= t[c] for c, v in cnt.items()): + ans = w return ans ``` @@ -92,39 +87,34 @@ class Solution: ```java class Solution { public String shortestCompletingWord(String licensePlate, String[] words) { - int[] counter = count(licensePlate.toLowerCase()); - String ans = null; - int n = 16; - for (String word : words) { - if (n <= word.length()) { + int[] cnt = new int[26]; + for (int i = 0; i < licensePlate.length(); ++i) { + char c = licensePlate.charAt(i); + if (Character.isLetter(c)) { + cnt[Character.toLowerCase(c) - 'a']++; + } + } + String ans = ""; + for (String w : words) { + if (!ans.isEmpty() && w.length() >= ans.length()) { continue; } - int[] t = count(word); - if (check(counter, t)) { - n = word.length(); - ans = word; + int[] t = new int[26]; + for (int i = 0; i < w.length(); ++i) { + t[w.charAt(i) - 'a']++; } - } - return ans; - } - - private int[] count(String word) { - int[] counter = new int[26]; - for (char c : word.toCharArray()) { - if (Character.isLetter(c)) { - ++counter[c - 'a']; + boolean ok = true; + for (int i = 0; i < 26; ++i) { + if (t[i] < cnt[i]) { + ok = false; + break; + } } - } - return counter; - } - - private boolean check(int[] counter1, int[] counter2) { - for (int i = 0; i < 26; ++i) { - if (counter1[i] > counter2[i]) { - return false; + if (ok) { + ans = w; } } - return true; + return ans; } } ``` @@ -135,74 +125,138 @@ class Solution { class Solution { public: string shortestCompletingWord(string licensePlate, vector& words) { - vector counter = count(licensePlate); - int n = 16; + int cnt[26]{}; + for (char& c : licensePlate) { + if (isalpha(c)) { + ++cnt[tolower(c) - 'a']; + } + } string ans; - for (auto& word : words) { - if (n <= word.size()) continue; - vector t = count(word); - if (check(counter, t)) { - n = word.size(); - ans = word; + for (auto& w : words) { + if (ans.size() && ans.size() <= w.size()) { + continue; + } + int t[26]{}; + for (char& c : w) { + ++t[c - 'a']; + } + bool ok = true; + for (int i = 0; i < 26; ++i) { + if (cnt[i] > t[i]) { + ok = false; + break; + } + } + if (ok) { + ans = w; } } return ans; } - - vector count(string& word) { - vector counter(26); - for (char& c : word) - if (isalpha(c)) - ++counter[tolower(c) - 'a']; - return counter; - } - - bool check(vector& counter1, vector& counter2) { - for (int i = 0; i < 26; ++i) - if (counter1[i] > counter2[i]) - return false; - return true; - } }; ``` ### **Go** ```go -func shortestCompletingWord(licensePlate string, words []string) string { - count := func(word string) []int { - counter := make([]int, 26) - for _, c := range word { - if unicode.IsLetter(c) { - counter[c-'a']++ - } - } - return counter - } - - check := func(cnt1, cnt2 []int) bool { - for i := 0; i < 26; i++ { - if cnt1[i] > cnt2[i] { - return false - } +func shortestCompletingWord(licensePlate string, words []string) (ans string) { + cnt := [26]int{} + for _, c := range licensePlate { + if unicode.IsLetter(c) { + cnt[unicode.ToLower(c)-'a']++ } - return true } - - counter := count(strings.ToLower(licensePlate)) - var ans string - n := 16 - for _, word := range words { - if n <= len(word) { + for _, w := range words { + if len(ans) > 0 && len(ans) <= len(w) { continue } - t := count(word) - if check(counter, t) { - n = len(word) - ans = word + t := [26]int{} + for _, c := range w { + t[c-'a']++ + } + ok := true + for i, v := range cnt { + if t[i] < v { + ok = false + break + } + } + if ok { + ans = w } } - return ans + return +} +``` + +### **TypeScript** + +```ts +function shortestCompletingWord(licensePlate: string, words: string[]): string { + const cnt: number[] = Array(26).fill(0); + for (const c of licensePlate) { + const i = c.toLowerCase().charCodeAt(0) - 97; + if (0 <= i && i < 26) { + ++cnt[i]; + } + } + let ans = ''; + for (const w of words) { + if (ans.length && ans.length <= w.length) { + continue; + } + const t = Array(26).fill(0); + for (const c of w) { + ++t[c.charCodeAt(0) - 97]; + } + let ok = true; + for (let i = 0; i < 26; ++i) { + if (t[i] < cnt[i]) { + ok = false; + break; + } + } + if (ok) { + ans = w; + } + } + return ans; +} +``` + +### **Rust** + +```rust +impl Solution { + pub fn shortest_completing_word(license_plate: String, words: Vec) -> String { + let mut cnt = vec![0; 26]; + for c in license_plate.chars() { + if c.is_ascii_alphabetic() { + cnt[((c.to_ascii_lowercase() as u8) - b'a') as usize] += 1; + } + } + let mut ans = String::new(); + for w in words { + if !ans.is_empty() && w.len() >= ans.len() { + continue; + } + let mut t = vec![0; 26]; + for c in w.chars() { + t[((c as u8) - b'a') as usize] += 1; + } + let mut ok = true; + for i in 0..26 { + if t[i] < cnt[i] { + ok = false; + break; + } + } + if ok { + ans = w; + } + } + ans + } } ``` diff --git a/solution/0700-0799/0748.Shortest Completing Word/README_EN.md b/solution/0700-0799/0748.Shortest Completing Word/README_EN.md index 3cb6956f3fd3d..c4e611d0e741c 100644 --- a/solution/0700-0799/0748.Shortest Completing Word/README_EN.md +++ b/solution/0700-0799/0748.Shortest Completing Word/README_EN.md @@ -47,6 +47,14 @@ Since "steps" is the only word containing all the letters, that is the ## Solutions +**Solution 1: Counting** + +First, we use a hash table or an array $cnt$ of length $26$ to count the frequency of each letter in the string `licensePlate`. Note that we convert all letters to lowercase for counting. + +Then, we traverse each word $w$ in the array `words`. If the length of the word $w$ is longer than the length of the answer $ans$, we directly skip this word. Otherwise, we use another hash table or an array $t$ of length $26$ to count the frequency of each letter in the word $w$. If for any letter, the frequency of this letter in $t$ is less than the frequency of this letter in $cnt$, we can also directly skip this word. Otherwise, we have found a word that meets the conditions, and we update the answer $ans$ to the current word $w$. + +The time complexity is $O(n \times |\Sigma|)$, and the space complexity is $O(|\Sigma|)$. Here, $n$ is the length of the array `words`, and $\Sigma$ is the character set. In this case, the character set is all lowercase letters, so $|\Sigma| = 26$. + ### **Python3** @@ -54,27 +62,14 @@ Since "steps" is the only word containing all the letters, that is the ```python class Solution: def shortestCompletingWord(self, licensePlate: str, words: List[str]) -> str: - def count(word): - counter = [0] * 26 - for c in word: - counter[ord(c) - ord('a')] += 1 - return counter - - def check(counter1, counter2): - for i in range(26): - if counter1[i] > counter2[i]: - return False - return True - - counter = count(c.lower() for c in licensePlate if c.isalpha()) - ans, n = None, 16 - for word in words: - if n <= len(word): + cnt = Counter(c.lower() for c in licensePlate if c.isalpha()) + ans = None + for w in words: + if ans and len(w) >= len(ans): continue - t = count(word) - if check(counter, t): - n = len(word) - ans = word + t = Counter(w) + if all(v <= t[c] for c, v in cnt.items()): + ans = w return ans ``` @@ -83,39 +78,34 @@ class Solution: ```java class Solution { public String shortestCompletingWord(String licensePlate, String[] words) { - int[] counter = count(licensePlate.toLowerCase()); - String ans = null; - int n = 16; - for (String word : words) { - if (n <= word.length()) { + int[] cnt = new int[26]; + for (int i = 0; i < licensePlate.length(); ++i) { + char c = licensePlate.charAt(i); + if (Character.isLetter(c)) { + cnt[Character.toLowerCase(c) - 'a']++; + } + } + String ans = ""; + for (String w : words) { + if (!ans.isEmpty() && w.length() >= ans.length()) { continue; } - int[] t = count(word); - if (check(counter, t)) { - n = word.length(); - ans = word; + int[] t = new int[26]; + for (int i = 0; i < w.length(); ++i) { + t[w.charAt(i) - 'a']++; } - } - return ans; - } - - private int[] count(String word) { - int[] counter = new int[26]; - for (char c : word.toCharArray()) { - if (Character.isLetter(c)) { - ++counter[c - 'a']; + boolean ok = true; + for (int i = 0; i < 26; ++i) { + if (t[i] < cnt[i]) { + ok = false; + break; + } } - } - return counter; - } - - private boolean check(int[] counter1, int[] counter2) { - for (int i = 0; i < 26; ++i) { - if (counter1[i] > counter2[i]) { - return false; + if (ok) { + ans = w; } } - return true; + return ans; } } ``` @@ -126,74 +116,138 @@ class Solution { class Solution { public: string shortestCompletingWord(string licensePlate, vector& words) { - vector counter = count(licensePlate); - int n = 16; + int cnt[26]{}; + for (char& c : licensePlate) { + if (isalpha(c)) { + ++cnt[tolower(c) - 'a']; + } + } string ans; - for (auto& word : words) { - if (n <= word.size()) continue; - vector t = count(word); - if (check(counter, t)) { - n = word.size(); - ans = word; + for (auto& w : words) { + if (ans.size() && ans.size() <= w.size()) { + continue; + } + int t[26]{}; + for (char& c : w) { + ++t[c - 'a']; + } + bool ok = true; + for (int i = 0; i < 26; ++i) { + if (cnt[i] > t[i]) { + ok = false; + break; + } + } + if (ok) { + ans = w; } } return ans; } - - vector count(string& word) { - vector counter(26); - for (char& c : word) - if (isalpha(c)) - ++counter[tolower(c) - 'a']; - return counter; - } - - bool check(vector& counter1, vector& counter2) { - for (int i = 0; i < 26; ++i) - if (counter1[i] > counter2[i]) - return false; - return true; - } }; ``` ### **Go** ```go -func shortestCompletingWord(licensePlate string, words []string) string { - count := func(word string) []int { - counter := make([]int, 26) - for _, c := range word { - if unicode.IsLetter(c) { - counter[c-'a']++ - } - } - return counter - } - - check := func(cnt1, cnt2 []int) bool { - for i := 0; i < 26; i++ { - if cnt1[i] > cnt2[i] { - return false - } +func shortestCompletingWord(licensePlate string, words []string) (ans string) { + cnt := [26]int{} + for _, c := range licensePlate { + if unicode.IsLetter(c) { + cnt[unicode.ToLower(c)-'a']++ } - return true } - - counter := count(strings.ToLower(licensePlate)) - var ans string - n := 16 - for _, word := range words { - if n <= len(word) { + for _, w := range words { + if len(ans) > 0 && len(ans) <= len(w) { continue } - t := count(word) - if check(counter, t) { - n = len(word) - ans = word + t := [26]int{} + for _, c := range w { + t[c-'a']++ + } + ok := true + for i, v := range cnt { + if t[i] < v { + ok = false + break + } + } + if ok { + ans = w } } - return ans + return +} +``` + +### **TypeScript** + +```ts +function shortestCompletingWord(licensePlate: string, words: string[]): string { + const cnt: number[] = Array(26).fill(0); + for (const c of licensePlate) { + const i = c.toLowerCase().charCodeAt(0) - 97; + if (0 <= i && i < 26) { + ++cnt[i]; + } + } + let ans = ''; + for (const w of words) { + if (ans.length && ans.length <= w.length) { + continue; + } + const t = Array(26).fill(0); + for (const c of w) { + ++t[c.charCodeAt(0) - 97]; + } + let ok = true; + for (let i = 0; i < 26; ++i) { + if (t[i] < cnt[i]) { + ok = false; + break; + } + } + if (ok) { + ans = w; + } + } + return ans; +} +``` + +### **Rust** + +```rust +impl Solution { + pub fn shortest_completing_word(license_plate: String, words: Vec) -> String { + let mut cnt = vec![0; 26]; + for c in license_plate.chars() { + if c.is_ascii_alphabetic() { + cnt[((c.to_ascii_lowercase() as u8) - b'a') as usize] += 1; + } + } + let mut ans = String::new(); + for w in words { + if !ans.is_empty() && w.len() >= ans.len() { + continue; + } + let mut t = vec![0; 26]; + for c in w.chars() { + t[((c as u8) - b'a') as usize] += 1; + } + let mut ok = true; + for i in 0..26 { + if t[i] < cnt[i] { + ok = false; + break; + } + } + if ok { + ans = w; + } + } + ans + } } ``` diff --git a/solution/0700-0799/0748.Shortest Completing Word/Solution.cpp b/solution/0700-0799/0748.Shortest Completing Word/Solution.cpp index 0694afd751f49..c79c78bd37d6b 100644 --- a/solution/0700-0799/0748.Shortest Completing Word/Solution.cpp +++ b/solution/0700-0799/0748.Shortest Completing Word/Solution.cpp @@ -1,32 +1,32 @@ -class Solution { -public: - string shortestCompletingWord(string licensePlate, vector& words) { - vector counter = count(licensePlate); - int n = 16; - string ans; - for (auto& word : words) { - if (n <= word.size()) continue; - vector t = count(word); - if (check(counter, t)) { - n = word.size(); - ans = word; - } - } - return ans; - } - - vector count(string& word) { - vector counter(26); - for (char& c : word) - if (isalpha(c)) - ++counter[tolower(c) - 'a']; - return counter; - } - - bool check(vector& counter1, vector& counter2) { - for (int i = 0; i < 26; ++i) - if (counter1[i] > counter2[i]) - return false; - return true; - } +class Solution { +public: + string shortestCompletingWord(string licensePlate, vector& words) { + int cnt[26]{}; + for (char& c : licensePlate) { + if (isalpha(c)) { + ++cnt[tolower(c) - 'a']; + } + } + string ans; + for (auto& w : words) { + if (ans.size() && ans.size() <= w.size()) { + continue; + } + int t[26]{}; + for (char& c : w) { + ++t[c - 'a']; + } + bool ok = true; + for (int i = 0; i < 26; ++i) { + if (cnt[i] > t[i]) { + ok = false; + break; + } + } + if (ok) { + ans = w; + } + } + return ans; + } }; \ No newline at end of file diff --git a/solution/0700-0799/0748.Shortest Completing Word/Solution.go b/solution/0700-0799/0748.Shortest Completing Word/Solution.go index d3820f177d38e..4051ceedc6a4c 100644 --- a/solution/0700-0799/0748.Shortest Completing Word/Solution.go +++ b/solution/0700-0799/0748.Shortest Completing Word/Solution.go @@ -1,35 +1,28 @@ -func shortestCompletingWord(licensePlate string, words []string) string { - count := func(word string) []int { - counter := make([]int, 26) - for _, c := range word { - if unicode.IsLetter(c) { - counter[c-'a']++ - } - } - return counter - } - - check := func(cnt1, cnt2 []int) bool { - for i := 0; i < 26; i++ { - if cnt1[i] > cnt2[i] { - return false - } +func shortestCompletingWord(licensePlate string, words []string) (ans string) { + cnt := [26]int{} + for _, c := range licensePlate { + if unicode.IsLetter(c) { + cnt[unicode.ToLower(c)-'a']++ } - return true } - - counter := count(strings.ToLower(licensePlate)) - var ans string - n := 16 - for _, word := range words { - if n <= len(word) { + for _, w := range words { + if len(ans) > 0 && len(ans) <= len(w) { continue } - t := count(word) - if check(counter, t) { - n = len(word) - ans = word + t := [26]int{} + for _, c := range w { + t[c-'a']++ + } + ok := true + for i, v := range cnt { + if t[i] < v { + ok = false + break + } + } + if ok { + ans = w } } - return ans + return } \ No newline at end of file diff --git a/solution/0700-0799/0748.Shortest Completing Word/Solution.java b/solution/0700-0799/0748.Shortest Completing Word/Solution.java index 4efe1ccb4b2be..1338440a8bdcb 100644 --- a/solution/0700-0799/0748.Shortest Completing Word/Solution.java +++ b/solution/0700-0799/0748.Shortest Completing Word/Solution.java @@ -1,37 +1,32 @@ -class Solution { - public String shortestCompletingWord(String licensePlate, String[] words) { - int[] counter = count(licensePlate.toLowerCase()); - String ans = null; - int n = 16; - for (String word : words) { - if (n <= word.length()) { - continue; - } - int[] t = count(word); - if (check(counter, t)) { - n = word.length(); - ans = word; - } - } - return ans; - } - - private int[] count(String word) { - int[] counter = new int[26]; - for (char c : word.toCharArray()) { - if (Character.isLetter(c)) { - ++counter[c - 'a']; - } - } - return counter; - } - - private boolean check(int[] counter1, int[] counter2) { - for (int i = 0; i < 26; ++i) { - if (counter1[i] > counter2[i]) { - return false; - } - } - return true; - } +class Solution { + public String shortestCompletingWord(String licensePlate, String[] words) { + int[] cnt = new int[26]; + for (int i = 0; i < licensePlate.length(); ++i) { + char c = licensePlate.charAt(i); + if (Character.isLetter(c)) { + cnt[Character.toLowerCase(c) - 'a']++; + } + } + String ans = ""; + for (String w : words) { + if (!ans.isEmpty() && w.length() >= ans.length()) { + continue; + } + int[] t = new int[26]; + for (int i = 0; i < w.length(); ++i) { + t[w.charAt(i) - 'a']++; + } + boolean ok = true; + for (int i = 0; i < 26; ++i) { + if (t[i] < cnt[i]) { + ok = false; + break; + } + } + if (ok) { + ans = w; + } + } + return ans; + } } \ No newline at end of file diff --git a/solution/0700-0799/0748.Shortest Completing Word/Solution.py b/solution/0700-0799/0748.Shortest Completing Word/Solution.py index e7b9d91eb1e3d..02452f1fad5e5 100644 --- a/solution/0700-0799/0748.Shortest Completing Word/Solution.py +++ b/solution/0700-0799/0748.Shortest Completing Word/Solution.py @@ -1,24 +1,11 @@ -class Solution: - def shortestCompletingWord(self, licensePlate: str, words: List[str]) -> str: - def count(word): - counter = [0] * 26 - for c in word: - counter[ord(c) - ord('a')] += 1 - return counter - - def check(counter1, counter2): - for i in range(26): - if counter1[i] > counter2[i]: - return False - return True - - counter = count(c.lower() for c in licensePlate if c.isalpha()) - ans, n = None, 16 - for word in words: - if n <= len(word): - continue - t = count(word) - if check(counter, t): - n = len(word) - ans = word - return ans +class Solution: + def shortestCompletingWord(self, licensePlate: str, words: List[str]) -> str: + cnt = Counter(c.lower() for c in licensePlate if c.isalpha()) + ans = None + for w in words: + if ans and len(w) >= len(ans): + continue + t = Counter(w) + if all(v <= t[c] for c, v in cnt.items()): + ans = w + return ans diff --git a/solution/0700-0799/0748.Shortest Completing Word/Solution.rs b/solution/0700-0799/0748.Shortest Completing Word/Solution.rs new file mode 100644 index 0000000000000..b3d710e9cde07 --- /dev/null +++ b/solution/0700-0799/0748.Shortest Completing Word/Solution.rs @@ -0,0 +1,31 @@ +impl Solution { + pub fn shortest_completing_word(license_plate: String, words: Vec) -> String { + let mut cnt = vec![0; 26]; + for c in license_plate.chars() { + if c.is_ascii_alphabetic() { + cnt[((c.to_ascii_lowercase() as u8) - b'a') as usize] += 1; + } + } + let mut ans = String::new(); + for w in words { + if !ans.is_empty() && w.len() >= ans.len() { + continue; + } + let mut t = vec![0; 26]; + for c in w.chars() { + t[((c as u8) - b'a') as usize] += 1; + } + let mut ok = true; + for i in 0..26 { + if t[i] < cnt[i] { + ok = false; + break; + } + } + if ok { + ans = w; + } + } + ans + } +} diff --git a/solution/0700-0799/0748.Shortest Completing Word/Solution.ts b/solution/0700-0799/0748.Shortest Completing Word/Solution.ts new file mode 100644 index 0000000000000..bc56ab46807c1 --- /dev/null +++ b/solution/0700-0799/0748.Shortest Completing Word/Solution.ts @@ -0,0 +1,30 @@ +function shortestCompletingWord(licensePlate: string, words: string[]): string { + const cnt: number[] = Array(26).fill(0); + for (const c of licensePlate) { + const i = c.toLowerCase().charCodeAt(0) - 97; + if (0 <= i && i < 26) { + ++cnt[i]; + } + } + let ans = ''; + for (const w of words) { + if (ans.length && ans.length <= w.length) { + continue; + } + const t = Array(26).fill(0); + for (const c of w) { + ++t[c.charCodeAt(0) - 97]; + } + let ok = true; + for (let i = 0; i < 26; ++i) { + if (t[i] < cnt[i]) { + ok = false; + break; + } + } + if (ok) { + ans = w; + } + } + return ans; +} diff --git a/solution/0700-0799/0750.Number Of Corner Rectangles/README_EN.md b/solution/0700-0799/0750.Number Of Corner Rectangles/README_EN.md index 09d33e3f609cf..c7319e005b52b 100644 --- a/solution/0700-0799/0750.Number Of Corner Rectangles/README_EN.md +++ b/solution/0700-0799/0750.Number Of Corner Rectangles/README_EN.md @@ -46,6 +46,12 @@ ## Solutions +**Solution 1: Hash Table + Enumeration** + +We enumerate each row as the bottom of the rectangle. For the current row, if both column $i$ and column $j$ are $1$, then we use a hash table to find out how many of the previous rows have both columns $i$ and $j$ as $1$. This is the number of rectangles with $(i, j)$ as the bottom right corner, and we add this number to the answer. Then we add $(i, j)$ to the hash table and continue to enumerate the next pair $(i, j)$. + +The time complexity is $O(m \times n^2)$, and the space complexity is $O(n^2)$. Here, $m$ and $n$ are the number of rows and columns of the matrix, respectively. + ### **Python3** From 37f4c1faaf48cba641088413e95c54b4ddf92d01 Mon Sep 17 00:00:00 2001 From: acbin <44314231+acbin@users.noreply.github.com> Date: Sun, 17 Dec 2023 12:43:08 +0800 Subject: [PATCH 4/8] feat: add weekly contest 376 (#2111) --- .../README.md | 85 +++++++++++++++ .../README_EN.md | 73 +++++++++++++ .../README.md | 92 ++++++++++++++++ .../README_EN.md | 82 ++++++++++++++ .../README.md | 103 ++++++++++++++++++ .../README_EN.md | 93 ++++++++++++++++ .../README.md | 96 ++++++++++++++++ .../README_EN.md | 86 +++++++++++++++ solution/CONTEST_README.md | 7 ++ solution/CONTEST_README_EN.md | 7 ++ solution/README.md | 4 + solution/README_EN.md | 4 + solution/summary.md | 4 + solution/summary_en.md | 4 + 14 files changed, 740 insertions(+) create mode 100644 solution/2900-2999/2965.Find Missing and Repeated Values/README.md create mode 100644 solution/2900-2999/2965.Find Missing and Repeated Values/README_EN.md create mode 100644 solution/2900-2999/2966.Divide Array Into Arrays With Max Difference/README.md create mode 100644 solution/2900-2999/2966.Divide Array Into Arrays With Max Difference/README_EN.md create mode 100644 solution/2900-2999/2967.Minimum Cost to Make Array Equalindromic/README.md create mode 100644 solution/2900-2999/2967.Minimum Cost to Make Array Equalindromic/README_EN.md create mode 100644 solution/2900-2999/2968.Apply Operations to Maximize Frequency Score/README.md create mode 100644 solution/2900-2999/2968.Apply Operations to Maximize Frequency Score/README_EN.md diff --git a/solution/2900-2999/2965.Find Missing and Repeated Values/README.md b/solution/2900-2999/2965.Find Missing and Repeated Values/README.md new file mode 100644 index 0000000000000..a7ccb011dbbec --- /dev/null +++ b/solution/2900-2999/2965.Find Missing and Repeated Values/README.md @@ -0,0 +1,85 @@ +# [2965. 找出缺失和重复的数字](https://leetcode.cn/problems/find-missing-and-repeated-values) + +[English Version](/solution/2900-2999/2965.Find%20Missing%20and%20Repeated%20Values/README_EN.md) + +## 题目描述 + + + +

给你一个下标从 0 开始的二维整数矩阵 grid,大小为 n * n ,其中的值在 [1, n2] 范围内。除了 a 出现 两次b 缺失 之外,每个整数都 恰好出现一次

+ +

任务是找出重复的数字a 和缺失的数字 b

+ +

返回一个下标从 0 开始、长度为 2 的整数数组 ans ,其中 ans[0] 等于 aans[1] 等于 b

+ +

 

+ +

示例 1:

+ +
+输入:grid = [[1,3],[2,2]]
+输出:[2,4]
+解释:数字 2 重复,数字 4 缺失,所以答案是 [2,4] 。
+
+ +

示例 2:

+ +
+输入:grid = [[9,1,7],[8,9,2],[3,4,6]]
+输出:[9,5]
+解释:数字 9 重复,数字 5 缺失,所以答案是 [9,5] 。
+
+ +

 

+ +

提示:

+ +
    +
  • 2 <= n == grid.length == grid[i].length <= 50
  • +
  • 1 <= grid[i][j] <= n * n
  • +
  • 对于所有满足1 <= x <= n * nx ,恰好存在一个 x 与矩阵中的任何成员都不相等。
  • +
  • 对于所有满足1 <= x <= n * nx ,恰好存在一个 x 与矩阵中的两个成员相等。
  • +
  • 除上述的两个之外,对于所有满足1 <= x <= n * nx ,都恰好存在一对 i, j 满足 0 <= i, j <= n - 1grid[i][j] == x
  • +
+ +## 解法 + + + + + +### **Python3** + + + +```python + +``` + +### **Java** + + + +```java + +``` + +### **C++** + +```cpp + +``` + +### **Go** + +```go + +``` + +### **...** + +``` + +``` + + diff --git a/solution/2900-2999/2965.Find Missing and Repeated Values/README_EN.md b/solution/2900-2999/2965.Find Missing and Repeated Values/README_EN.md new file mode 100644 index 0000000000000..add969d22e787 --- /dev/null +++ b/solution/2900-2999/2965.Find Missing and Repeated Values/README_EN.md @@ -0,0 +1,73 @@ +# [2965. Find Missing and Repeated Values](https://leetcode.com/problems/find-missing-and-repeated-values) + +[中文文档](/solution/2900-2999/2965.Find%20Missing%20and%20Repeated%20Values/README.md) + +## Description + +

You are given a 0-indexed 2D integer matrix grid of size n * n with values in the range [1, n2]. Each integer appears exactly once except a which appears twice and b which is missing. The task is to find the repeating and missing numbers a and b.

+ +

Return a 0-indexed integer array ans of size 2 where ans[0] equals to a and ans[1] equals to b.

+ +

 

+

Example 1:

+ +
+Input: grid = [[1,3],[2,2]]
+Output: [2,4]
+Explanation: Number 2 is repeated and number 4 is missing so the answer is [2,4].
+
+ +

Example 2:

+ +
+Input: grid = [[9,1,7],[8,9,2],[3,4,6]]
+Output: [9,5]
+Explanation: Number 9 is repeated and number 5 is missing so the answer is [9,5].
+
+ +

 

+

Constraints:

+ +
    +
  • 2 <= n == grid.length == grid[i].length <= 50
  • +
  • 1 <= grid[i][j] <= n * n
  • +
  • For all x that 1 <= x <= n * n there is exactly one x that is not equal to any of the grid members.
  • +
  • For all x that 1 <= x <= n * n there is exactly one x that is equal to exactly two of the grid members.
  • +
  • For all x that 1 <= x <= n * n except two of them there is exatly one pair of i, j that 0 <= i, j <= n - 1 and grid[i][j] == x.
  • +
+ +## Solutions + + + +### **Python3** + +```python + +``` + +### **Java** + +```java + +``` + +### **C++** + +```cpp + +``` + +### **Go** + +```go + +``` + +### **...** + +``` + +``` + + diff --git a/solution/2900-2999/2966.Divide Array Into Arrays With Max Difference/README.md b/solution/2900-2999/2966.Divide Array Into Arrays With Max Difference/README.md new file mode 100644 index 0000000000000..1c8248e8dcf22 --- /dev/null +++ b/solution/2900-2999/2966.Divide Array Into Arrays With Max Difference/README.md @@ -0,0 +1,92 @@ +# [2966. 划分数组并满足最大差限制](https://leetcode.cn/problems/divide-array-into-arrays-with-max-difference) + +[English Version](/solution/2900-2999/2966.Divide%20Array%20Into%20Arrays%20With%20Max%20Difference/README_EN.md) + +## 题目描述 + + + +

给你一个长度为 n 的整数数组 nums,以及一个正整数 k

+ +

将这个数组划分为一个或多个长度为 3 的子数组,并满足以下条件:

+ +
    +
  • nums 中的 每个 元素都必须 恰好 存在于某个子数组中。
  • +
  • 子数组中 任意 两个元素的差必须小于或等于 k
  • +
+ +

返回一个 二维数组 ,包含所有的子数组。如果不可能满足条件,就返回一个空数组。如果有多个答案,返回 任意一个 即可。

+ +

 

+ +

示例 1:

+ +
+输入:nums = [1,3,4,8,7,9,3,5,1], k = 2
+输出:[[1,1,3],[3,4,5],[7,8,9]]
+解释:可以将数组划分为以下子数组:[1,1,3],[3,4,5] 和 [7,8,9] 。
+每个子数组中任意两个元素的差都小于或等于 2 。
+注意,元素的顺序并不重要。
+
+ +

示例 2:

+ +
+输入:nums = [1,3,3,2,7,3], k = 3
+输出:[]
+解释:无法划分数组满足所有条件。
+
+ +

 

+ +

提示:

+ +
    +
  • n == nums.length
  • +
  • 1 <= n <= 105
  • +
  • n3 的倍数
  • +
  • 1 <= nums[i] <= 105
  • +
  • 1 <= k <= 105
  • +
+ +## 解法 + + + + + +### **Python3** + + + +```python + +``` + +### **Java** + + + +```java + +``` + +### **C++** + +```cpp + +``` + +### **Go** + +```go + +``` + +### **...** + +``` + +``` + + diff --git a/solution/2900-2999/2966.Divide Array Into Arrays With Max Difference/README_EN.md b/solution/2900-2999/2966.Divide Array Into Arrays With Max Difference/README_EN.md new file mode 100644 index 0000000000000..8c6739fb26aaf --- /dev/null +++ b/solution/2900-2999/2966.Divide Array Into Arrays With Max Difference/README_EN.md @@ -0,0 +1,82 @@ +# [2966. Divide Array Into Arrays With Max Difference](https://leetcode.com/problems/divide-array-into-arrays-with-max-difference) + +[中文文档](/solution/2900-2999/2966.Divide%20Array%20Into%20Arrays%20With%20Max%20Difference/README.md) + +## Description + +

You are given an integer array nums of size n and a positive integer k.

+ +

Divide the array into one or more arrays of size 3 satisfying the following conditions:

+ +
    +
  • Each element of nums should be in exactly one array.
  • +
  • The difference between any two elements in one array is less than or equal to k.
  • +
+ +

Return a 2D array containing all the arrays. If it is impossible to satisfy the conditions, return an empty array. And if there are multiple answers, return any of them.

+ +

 

+

Example 1:

+ +
+Input: nums = [1,3,4,8,7,9,3,5,1], k = 2
+Output: [[1,1,3],[3,4,5],[7,8,9]]
+Explanation: We can divide the array into the following arrays: [1,1,3], [3,4,5] and [7,8,9].
+The difference between any two elements in each array is less than or equal to 2.
+Note that the order of elements is not important.
+
+ +

Example 2:

+ +
+Input: nums = [1,3,3,2,7,3], k = 3
+Output: []
+Explanation: It is not possible to divide the array satisfying all the conditions.
+
+ +

 

+

Constraints:

+ +
    +
  • n == nums.length
  • +
  • 1 <= n <= 105
  • +
  • n is a multiple of 3.
  • +
  • 1 <= nums[i] <= 105
  • +
  • 1 <= k <= 105
  • +
+ +## Solutions + + + +### **Python3** + +```python + +``` + +### **Java** + +```java + +``` + +### **C++** + +```cpp + +``` + +### **Go** + +```go + +``` + +### **...** + +``` + +``` + + diff --git a/solution/2900-2999/2967.Minimum Cost to Make Array Equalindromic/README.md b/solution/2900-2999/2967.Minimum Cost to Make Array Equalindromic/README.md new file mode 100644 index 0000000000000..d72a88ca8090e --- /dev/null +++ b/solution/2900-2999/2967.Minimum Cost to Make Array Equalindromic/README.md @@ -0,0 +1,103 @@ +# [2967. 使数组成为等数数组的最小代价](https://leetcode.cn/problems/minimum-cost-to-make-array-equalindromic) + +[English Version](/solution/2900-2999/2967.Minimum%20Cost%20to%20Make%20Array%20Equalindromic/README_EN.md) + +## 题目描述 + + + +

给你一个长度为 n 下标从 0 开始的整数数组 nums 。

+ +

你可以对 nums 执行特殊操作 任意次 (也可以 0 次)。每一次特殊操作中,你需要 按顺序 执行以下步骤:

+ +
    +
  • 从范围 [0, n - 1] 里选择一个下标 i 和一个  整数 x 。
  • +
  • 将 |nums[i] - x| 添加到总代价里。
  • +
  • nums[i] 变为 x 。
  • +
+ +

如果一个正整数正着读和反着读都相同,那么我们称这个数是 回文数 。比方说,121 ,2552 和 65756 都是回文数,但是 24 ,46 ,235 都不是回文数。

+ +

如果一个数组中的所有元素都等于一个整数 y ,且 y 是一个小于 109 的 回文数 ,那么我们称这个数组是一个 等数数组 

+ +

请你返回一个整数,表示执行任意次特殊操作后使 nums 成为 等数数组 的 最小 总代价。

+ +

 

+ +

示例 1:

+ +
+输入:nums = [1,2,3,4,5]
+输出:6
+解释:我们可以将数组中所有元素变为回文数 3 得到等数数组,数组变成 [3,3,3,3,3] 需要执行 4 次特殊操作,代价为 |1 - 3| + |2 - 3| + |4 - 3| + |5 - 3| = 6 。
+将所有元素变为其他回文数的总代价都大于 6 。
+
+ +

示例 2:

+ +
+输入:nums = [10,12,13,14,15]
+输出:11
+解释:我们可以将数组中所有元素变为回文数 11 得到等数数组,数组变成 [11,11,11,11,11] 需要执行 5 次特殊操作,代价为 |10 - 11| + |12 - 11| + |13 - 11| + |14 - 11| + |15 - 11| = 11 。
+将所有元素变为其他回文数的总代价都大于 11 。
+
+ +

示例 3 :

+ +
+输入:nums = [22,33,22,33,22]
+输出:22
+解释:我们可以将数组中所有元素变为回文数 22 得到等数数组,数组变为 [22,22,22,22,22] 需要执行 2 次特殊操作,代价为 |33 - 22| + |33 - 22| = 22 。
+将所有元素变为其他回文数的总代价都大于 22 。
+
+ +

 

+ +

提示:

+ +
    +
  • 1 <= n <= 105
  • +
  • 1 <= nums[i] <= 109
  • +
+ +## 解法 + + + + + +### **Python3** + + + +```python + +``` + +### **Java** + + + +```java + +``` + +### **C++** + +```cpp + +``` + +### **Go** + +```go + +``` + +### **...** + +``` + +``` + + diff --git a/solution/2900-2999/2967.Minimum Cost to Make Array Equalindromic/README_EN.md b/solution/2900-2999/2967.Minimum Cost to Make Array Equalindromic/README_EN.md new file mode 100644 index 0000000000000..2e9b90c469847 --- /dev/null +++ b/solution/2900-2999/2967.Minimum Cost to Make Array Equalindromic/README_EN.md @@ -0,0 +1,93 @@ +# [2967. Minimum Cost to Make Array Equalindromic](https://leetcode.com/problems/minimum-cost-to-make-array-equalindromic) + +[中文文档](/solution/2900-2999/2967.Minimum%20Cost%20to%20Make%20Array%20Equalindromic/README.md) + +## Description + +

You are given a 0-indexed integer array nums having length n.

+ +

You are allowed to perform a special move any number of times (including zero) on nums. In one special move you perform the following steps in order:

+ +
    +
  • Choose an index i in the range [0, n - 1], and a positive integer x.
  • +
  • Add |nums[i] - x| to the total cost.
  • +
  • Change the value of nums[i] to x.
  • +
+ +

A palindromic number is a positive integer that remains the same when its digits are reversed. For example, 121, 2552 and 65756 are palindromic numbers whereas 24, 46, 235 are not palindromic numbers.

+ +

An array is considered equalindromic if all the elements in the array are equal to an integer y, where y is a palindromic number less than 109.

+ +

Return an integer denoting the minimum possible total cost to make nums equalindromic by performing any number of special moves.

+ +

 

+

Example 1:

+ +
+Input: nums = [1,2,3,4,5]
+Output: 6
+Explanation: We can make the array equalindromic by changing all elements to 3 which is a palindromic number. The cost of changing the array to [3,3,3,3,3] using 4 special moves is given by |1 - 3| + |2 - 3| + |4 - 3| + |5 - 3| = 6.
+It can be shown that changing all elements to any palindromic number other than 3 cannot be achieved at a lower cost.
+
+ +

Example 2:

+ +
+Input: nums = [10,12,13,14,15]
+Output: 11
+Explanation: We can make the array equalindromic by changing all elements to 11 which is a palindromic number. The cost of changing the array to [11,11,11,11,11] using 5 special moves is given by |10 - 11| + |12 - 11| + |13 - 11| + |14 - 11| + |15 - 11| = 11.
+It can be shown that changing all elements to any palindromic number other than 11 cannot be achieved at a lower cost.
+
+ +

Example 3:

+ +
+Input: nums = [22,33,22,33,22]
+Output: 22
+Explanation: We can make the array equalindromic by changing all elements to 22 which is a palindromic number. The cost of changing the array to [22,22,22,22,22] using 2 special moves is given by |33 - 22| + |33 - 22| = 22.
+It can be shown that changing all elements to any palindromic number other than 22 cannot be achieved at a lower cost.
+
+ +

 

+

Constraints:

+ +
    +
  • 1 <= n <= 105
  • +
  • 1 <= nums[i] <= 109
  • +
+ +## Solutions + + + +### **Python3** + +```python + +``` + +### **Java** + +```java + +``` + +### **C++** + +```cpp + +``` + +### **Go** + +```go + +``` + +### **...** + +``` + +``` + + diff --git a/solution/2900-2999/2968.Apply Operations to Maximize Frequency Score/README.md b/solution/2900-2999/2968.Apply Operations to Maximize Frequency Score/README.md new file mode 100644 index 0000000000000..ccb8f0392b6cb --- /dev/null +++ b/solution/2900-2999/2968.Apply Operations to Maximize Frequency Score/README.md @@ -0,0 +1,96 @@ +# [2968. 执行操作使频率分数最大](https://leetcode.cn/problems/apply-operations-to-maximize-frequency-score) + +[English Version](/solution/2900-2999/2968.Apply%20Operations%20to%20Maximize%20Frequency%20Score/README_EN.md) + +## 题目描述 + + + +

给你一个下标从 0 开始的整数数组 nums 和一个整数 k 。

+ +

你可以对数组执行 至多 k 次操作:

+ +
    +
  • 从数组中选择一个下标 i ,将 nums[i] 增加 或者 减少 1 。
  • +
+ +

最终数组的频率分数定义为数组中众数的 频率 。

+ +

请你返回你可以得到的 最大 频率分数。

+ +

众数指的是数组中出现次数最多的数。一个元素的频率指的是数组中这个元素的出现次数。

+ +

 

+ +

示例 1:

+ +
+输入:nums = [1,2,6,4], k = 3
+输出:3
+解释:我们可以对数组执行以下操作:
+- 选择 i = 0 ,将 nums[0] 增加 1 。得到数组 [2,2,6,4] 。
+- 选择 i = 3 ,将 nums[3] 减少 1 ,得到数组 [2,2,6,3] 。
+- 选择 i = 3 ,将 nums[3] 减少 1 ,得到数组 [2,2,6,2] 。
+元素 2 是最终数组中的众数,出现了 3 次,所以频率分数为 3 。
+3 是所有可行方案里的最大频率分数。
+
+ +

示例 2:

+ +
+输入:nums = [1,4,4,2,4], k = 0
+输出:3
+解释:我们无法执行任何操作,所以得到的频率分数是原数组中众数的频率 3 。
+
+ +

 

+ +

提示:

+ +
    +
  • 1 <= nums.length <= 105
  • +
  • 1 <= nums[i] <= 109
  • +
  • 0 <= k <= 1014
  • +
+ +## 解法 + + + + + +### **Python3** + + + +```python + +``` + +### **Java** + + + +```java + +``` + +### **C++** + +```cpp + +``` + +### **Go** + +```go + +``` + +### **...** + +``` + +``` + + diff --git a/solution/2900-2999/2968.Apply Operations to Maximize Frequency Score/README_EN.md b/solution/2900-2999/2968.Apply Operations to Maximize Frequency Score/README_EN.md new file mode 100644 index 0000000000000..5af4970451bd1 --- /dev/null +++ b/solution/2900-2999/2968.Apply Operations to Maximize Frequency Score/README_EN.md @@ -0,0 +1,86 @@ +# [2968. Apply Operations to Maximize Frequency Score](https://leetcode.com/problems/apply-operations-to-maximize-frequency-score) + +[中文文档](/solution/2900-2999/2968.Apply%20Operations%20to%20Maximize%20Frequency%20Score/README.md) + +## Description + +

You are given a 0-indexed integer array nums and an integer k.

+ +

You can perform the following operation on the array at most k times:

+ +
    +
  • Choose any index i from the array and increase or decrease nums[i] by 1.
  • +
+ +

The score of the final array is the frequency of the most frequent element in the array.

+ +

Return the maximum score you can achieve.

+ +

The frequency of an element is the number of occurences of that element in the array.

+ +

 

+

Example 1:

+ +
+Input: nums = [1,2,6,4], k = 3
+Output: 3
+Explanation: We can do the following operations on the array:
+- Choose i = 0, and increase the value of nums[0] by 1. The resulting array is [2,2,6,4].
+- Choose i = 3, and decrease the value of nums[3] by 1. The resulting array is [2,2,6,3].
+- Choose i = 3, and decrease the value of nums[3] by 1. The resulting array is [2,2,6,2].
+The element 2 is the most frequent in the final array so our score is 3.
+It can be shown that we cannot achieve a better score.
+
+ +

Example 2:

+ +
+Input: nums = [1,4,4,2,4], k = 0
+Output: 3
+Explanation: We cannot apply any operations so our score will be the frequency of the most frequent element in the original array, which is 3.
+
+ +

 

+

Constraints:

+ +
    +
  • 1 <= nums.length <= 105
  • +
  • 1 <= nums[i] <= 109
  • +
  • 0 <= k <= 1014
  • +
+ +## Solutions + + + +### **Python3** + +```python + +``` + +### **Java** + +```java + +``` + +### **C++** + +```cpp + +``` + +### **Go** + +```go + +``` + +### **...** + +``` + +``` + + diff --git a/solution/CONTEST_README.md b/solution/CONTEST_README.md index bfb3c200c07ea..efc40bbb12da5 100644 --- a/solution/CONTEST_README.md +++ b/solution/CONTEST_README.md @@ -22,6 +22,13 @@ ## 往期竞赛 +#### 第 376 场周赛(2023-12-17 10:30, 90 分钟) 参赛人数 3409 + +- [2965. 找出缺失和重复的数字](/solution/2900-2999/2965.Find%20Missing%20and%20Repeated%20Values/README.md) +- [2966. 划分数组并满足最大差限制](/solution/2900-2999/2966.Divide%20Array%20Into%20Arrays%20With%20Max%20Difference/README.md) +- [2967. 使数组成为等数数组的最小代价](/solution/2900-2999/2967.Minimum%20Cost%20to%20Make%20Array%20Equalindromic/README.md) +- [2968. 执行操作使频率分数最大](/solution/2900-2999/2968.Apply%20Operations%20to%20Maximize%20Frequency%20Score/README.md) + #### 第 375 场周赛(2023-12-10 10:30, 90 分钟) 参赛人数 3518 - [2960. 统计已测试设备](/solution/2900-2999/2960.Count%20Tested%20Devices%20After%20Test%20Operations/README.md) diff --git a/solution/CONTEST_README_EN.md b/solution/CONTEST_README_EN.md index 4340ca2b4d553..86b32036bc22d 100644 --- a/solution/CONTEST_README_EN.md +++ b/solution/CONTEST_README_EN.md @@ -25,6 +25,13 @@ Get your rating changes right after the completion of LeetCode contests, https:/ ## Past Contests +#### Weekly Contest 376 + +- [2965. Find Missing and Repeated Values](/solution/2900-2999/2965.Find%20Missing%20and%20Repeated%20Values/README_EN.md) +- [2966. Divide Array Into Arrays With Max Difference](/solution/2900-2999/2966.Divide%20Array%20Into%20Arrays%20With%20Max%20Difference/README_EN.md) +- [2967. Minimum Cost to Make Array Equalindromic](/solution/2900-2999/2967.Minimum%20Cost%20to%20Make%20Array%20Equalindromic/README_EN.md) +- [2968. Apply Operations to Maximize Frequency Score](/solution/2900-2999/2968.Apply%20Operations%20to%20Maximize%20Frequency%20Score/README_EN.md) + #### Weekly Contest 375 - [2960. Count Tested Devices After Test Operations](/solution/2900-2999/2960.Count%20Tested%20Devices%20After%20Test%20Operations/README_EN.md) diff --git a/solution/README.md b/solution/README.md index a6035ff538924..9027686fd1c66 100644 --- a/solution/README.md +++ b/solution/README.md @@ -2975,6 +2975,10 @@ | 2962 | [统计最大元素出现至少 K 次的子数组](/solution/2900-2999/2962.Count%20Subarrays%20Where%20Max%20Element%20Appears%20at%20Least%20K%20Times/README.md) | `数组`,`滑动窗口` | 中等 | 第 375 场周赛 | | 2963 | [统计好分割方案的数目](/solution/2900-2999/2963.Count%20the%20Number%20of%20Good%20Partitions/README.md) | `数组`,`哈希表`,`数学`,`组合数学` | 困难 | 第 375 场周赛 | | 2964 | [Number of Divisible Triplet Sums](/solution/2900-2999/2964.Number%20of%20Divisible%20Triplet%20Sums/README.md) | | 中等 | 🔒 | +| 2965 | [找出缺失和重复的数字](/solution/2900-2999/2965.Find%20Missing%20and%20Repeated%20Values/README.md) | | 简单 | 第 376 场周赛 | +| 2966 | [划分数组并满足最大差限制](/solution/2900-2999/2966.Divide%20Array%20Into%20Arrays%20With%20Max%20Difference/README.md) | | 中等 | 第 376 场周赛 | +| 2967 | [使数组成为等数数组的最小代价](/solution/2900-2999/2967.Minimum%20Cost%20to%20Make%20Array%20Equalindromic/README.md) | | 中等 | 第 376 场周赛 | +| 2968 | [执行操作使频率分数最大](/solution/2900-2999/2968.Apply%20Operations%20to%20Maximize%20Frequency%20Score/README.md) | | 困难 | 第 376 场周赛 | ## 版权 diff --git a/solution/README_EN.md b/solution/README_EN.md index d03d1761e03ff..a02b5ce25f38a 100644 --- a/solution/README_EN.md +++ b/solution/README_EN.md @@ -2973,6 +2973,10 @@ Press Control + F(or Command + F on | 2962 | [Count Subarrays Where Max Element Appears at Least K Times](/solution/2900-2999/2962.Count%20Subarrays%20Where%20Max%20Element%20Appears%20at%20Least%20K%20Times/README_EN.md) | `Array`,`Sliding Window` | Medium | Weekly Contest 375 | | 2963 | [Count the Number of Good Partitions](/solution/2900-2999/2963.Count%20the%20Number%20of%20Good%20Partitions/README_EN.md) | `Array`,`Hash Table`,`Math`,`Combinatorics` | Hard | Weekly Contest 375 | | 2964 | [Number of Divisible Triplet Sums](/solution/2900-2999/2964.Number%20of%20Divisible%20Triplet%20Sums/README_EN.md) | | Medium | 🔒 | +| 2965 | [Find Missing and Repeated Values](/solution/2900-2999/2965.Find%20Missing%20and%20Repeated%20Values/README_EN.md) | | Easy | Weekly Contest 376 | +| 2966 | [Divide Array Into Arrays With Max Difference](/solution/2900-2999/2966.Divide%20Array%20Into%20Arrays%20With%20Max%20Difference/README_EN.md) | | Medium | Weekly Contest 376 | +| 2967 | [Minimum Cost to Make Array Equalindromic](/solution/2900-2999/2967.Minimum%20Cost%20to%20Make%20Array%20Equalindromic/README_EN.md) | | Medium | Weekly Contest 376 | +| 2968 | [Apply Operations to Maximize Frequency Score](/solution/2900-2999/2968.Apply%20Operations%20to%20Maximize%20Frequency%20Score/README_EN.md) | | Hard | Weekly Contest 376 | ## Copyright diff --git a/solution/summary.md b/solution/summary.md index ccb77c3e8a1df..c0c71264c584e 100644 --- a/solution/summary.md +++ b/solution/summary.md @@ -3022,3 +3022,7 @@ - [2962.统计最大元素出现至少 K 次的子数组](/solution/2900-2999/2962.Count%20Subarrays%20Where%20Max%20Element%20Appears%20at%20Least%20K%20Times/README.md) - [2963.统计好分割方案的数目](/solution/2900-2999/2963.Count%20the%20Number%20of%20Good%20Partitions/README.md) - [2964.Number of Divisible Triplet Sums](/solution/2900-2999/2964.Number%20of%20Divisible%20Triplet%20Sums/README.md) + - [2965.找出缺失和重复的数字](/solution/2900-2999/2965.Find%20Missing%20and%20Repeated%20Values/README.md) + - [2966.划分数组并满足最大差限制](/solution/2900-2999/2966.Divide%20Array%20Into%20Arrays%20With%20Max%20Difference/README.md) + - [2967.使数组成为等数数组的最小代价](/solution/2900-2999/2967.Minimum%20Cost%20to%20Make%20Array%20Equalindromic/README.md) + - [2968.执行操作使频率分数最大](/solution/2900-2999/2968.Apply%20Operations%20to%20Maximize%20Frequency%20Score/README.md) diff --git a/solution/summary_en.md b/solution/summary_en.md index 3750c3e3d2966..8ca362264e6c1 100644 --- a/solution/summary_en.md +++ b/solution/summary_en.md @@ -3022,3 +3022,7 @@ - [2962.Count Subarrays Where Max Element Appears at Least K Times](/solution/2900-2999/2962.Count%20Subarrays%20Where%20Max%20Element%20Appears%20at%20Least%20K%20Times/README_EN.md) - [2963.Count the Number of Good Partitions](/solution/2900-2999/2963.Count%20the%20Number%20of%20Good%20Partitions/README_EN.md) - [2964.Number of Divisible Triplet Sums](/solution/2900-2999/2964.Number%20of%20Divisible%20Triplet%20Sums/README_EN.md) + - [2965.Find Missing and Repeated Values](/solution/2900-2999/2965.Find%20Missing%20and%20Repeated%20Values/README_EN.md) + - [2966.Divide Array Into Arrays With Max Difference](/solution/2900-2999/2966.Divide%20Array%20Into%20Arrays%20With%20Max%20Difference/README_EN.md) + - [2967.Minimum Cost to Make Array Equalindromic](/solution/2900-2999/2967.Minimum%20Cost%20to%20Make%20Array%20Equalindromic/README_EN.md) + - [2968.Apply Operations to Maximize Frequency Score](/solution/2900-2999/2968.Apply%20Operations%20to%20Maximize%20Frequency%20Score/README_EN.md) From 3e0485456682e6753eb926ebad3099f02ee8166d Mon Sep 17 00:00:00 2001 From: Libin YANG Date: Sun, 17 Dec 2023 13:20:54 +0800 Subject: [PATCH 5/8] feat: add solutions to lc problems: No.2965~2968 (#2112) * No.2965.Find Missing and Repeated Values * No.2966.Divide Array Into Arrays With Max Difference * No.2968.Apply Operations to Maximize Frequency Score --- .../README.md | 107 +++++++++- .../README_EN.md | 107 +++++++++- .../Solution.cpp | 21 ++ .../Solution.go | 19 ++ .../Solution.java | 20 ++ .../Solution.py | 14 ++ .../Solution.ts | 18 ++ .../README.md | 79 ++++++- .../README_EN.md | 79 ++++++- .../Solution.cpp | 16 ++ .../Solution.go | 12 ++ .../Solution.java | 15 ++ .../Solution.py | 11 + .../Solution.ts | 12 ++ .../README.md | 196 +++++++++++++++++- .../README_EN.md | 196 +++++++++++++++++- .../Solution.cpp | 37 ++++ .../Solution.go | 34 +++ .../Solution.java | 34 +++ .../Solution.py | 22 ++ .../Solution.ts | 32 +++ 21 files changed, 1063 insertions(+), 18 deletions(-) create mode 100644 solution/2900-2999/2965.Find Missing and Repeated Values/Solution.cpp create mode 100644 solution/2900-2999/2965.Find Missing and Repeated Values/Solution.go create mode 100644 solution/2900-2999/2965.Find Missing and Repeated Values/Solution.java create mode 100644 solution/2900-2999/2965.Find Missing and Repeated Values/Solution.py create mode 100644 solution/2900-2999/2965.Find Missing and Repeated Values/Solution.ts create mode 100644 solution/2900-2999/2966.Divide Array Into Arrays With Max Difference/Solution.cpp create mode 100644 solution/2900-2999/2966.Divide Array Into Arrays With Max Difference/Solution.go create mode 100644 solution/2900-2999/2966.Divide Array Into Arrays With Max Difference/Solution.java create mode 100644 solution/2900-2999/2966.Divide Array Into Arrays With Max Difference/Solution.py create mode 100644 solution/2900-2999/2966.Divide Array Into Arrays With Max Difference/Solution.ts create mode 100644 solution/2900-2999/2968.Apply Operations to Maximize Frequency Score/Solution.cpp create mode 100644 solution/2900-2999/2968.Apply Operations to Maximize Frequency Score/Solution.go create mode 100644 solution/2900-2999/2968.Apply Operations to Maximize Frequency Score/Solution.java create mode 100644 solution/2900-2999/2968.Apply Operations to Maximize Frequency Score/Solution.py create mode 100644 solution/2900-2999/2968.Apply Operations to Maximize Frequency Score/Solution.ts diff --git a/solution/2900-2999/2965.Find Missing and Repeated Values/README.md b/solution/2900-2999/2965.Find Missing and Repeated Values/README.md index a7ccb011dbbec..dea13dc8508c7 100644 --- a/solution/2900-2999/2965.Find Missing and Repeated Values/README.md +++ b/solution/2900-2999/2965.Find Missing and Repeated Values/README.md @@ -46,6 +46,14 @@ +**方法一:计数** + +我们创建一个长度为 $n^2 + 1$ 的数组 $cnt$,统计矩阵中每个数字出现的次数。 + +接下来遍历 $i \in [1, n^2]$,如果 $cnt[i] = 2$,则 $i$ 是重复的数字,我们将答案的第一个元素设为 $i$;如果 $cnt[i] = 0$,则 $i$ 是缺失的数字,我们将答案的第二个元素设为 $i$。 + +时间复杂度 $O(n^2)$,空间复杂度 $O(n^2)$。其中 $n$ 是矩阵的边长。 + ### **Python3** @@ -53,7 +61,20 @@ ```python - +class Solution: + def findMissingAndRepeatedValues(self, grid: List[List[int]]) -> List[int]: + n = len(grid) + cnt = [0] * (n * n + 1) + for row in grid: + for v in row: + cnt[v] += 1 + ans = [0] * 2 + for i in range(1, n * n + 1): + if cnt[i] == 2: + ans[0] = i + if cnt[i] == 0: + ans[1] = i + return ans ``` ### **Java** @@ -61,19 +82,99 @@ ```java - +class Solution { + public int[] findMissingAndRepeatedValues(int[][] grid) { + int n = grid.length; + int[] cnt = new int[n * n + 1]; + int[] ans = new int[2]; + for (int[] row : grid) { + for (int x : row) { + if (++cnt[x] == 2) { + ans[0] = x; + } + } + } + for (int x = 1;; ++x) { + if (cnt[x] == 0) { + ans[1] = x; + return ans; + } + } + } +} ``` ### **C++** ```cpp - +class Solution { +public: + vector findMissingAndRepeatedValues(vector>& grid) { + int n = grid.size(); + vector cnt(n * n + 1); + vector ans(2); + for (auto& row : grid) { + for (int x : row) { + if (++cnt[x] == 2) { + ans[0] = x; + } + } + } + for (int x = 1;; ++x) { + if (cnt[x] == 0) { + ans[1] = x; + return ans; + } + } + } +}; ``` ### **Go** ```go +func findMissingAndRepeatedValues(grid [][]int) []int { + n := len(grid) + ans := make([]int, 2) + cnt := make([]int, n*n+1) + for _, row := range grid { + for _, x := range row { + cnt[x]++ + if cnt[x] == 2 { + ans[0] = x + } + } + } + for x := 1; ; x++ { + if cnt[x] == 0 { + ans[1] = x + return ans + } + } +} +``` +### **TypeScript** + +```ts +function findMissingAndRepeatedValues(grid: number[][]): number[] { + const n = grid.length; + const cnt: number[] = Array(n * n + 1).fill(0); + const ans: number[] = Array(2).fill(0); + for (const row of grid) { + for (const x of row) { + if (++cnt[x] === 2) { + ans[0] = x; + } + } + } + for (let x = 1; ; ++x) { + if (cnt[x] === 0) { + ans[1] = x; + return ans; + } + } +} ``` ### **...** diff --git a/solution/2900-2999/2965.Find Missing and Repeated Values/README_EN.md b/solution/2900-2999/2965.Find Missing and Repeated Values/README_EN.md index add969d22e787..ca7c4b95844ba 100644 --- a/solution/2900-2999/2965.Find Missing and Repeated Values/README_EN.md +++ b/solution/2900-2999/2965.Find Missing and Repeated Values/README_EN.md @@ -38,30 +38,131 @@ ## Solutions +**Solution 1: Counting** + +We create an array $cnt$ of length $n^2 + 1$ to count the frequency of each number in the matrix. + +Next, we traverse $i \in [1, n^2]$. If $cnt[i] = 2$, then $i$ is the duplicated number, and we set the first element of the answer to $i$. If $cnt[i] = 0$, then $i$ is the missing number, and we set the second element of the answer to $i$. + +The time complexity is $O(n^2)$, and the space complexity is $O(n^2)$. Here, $n$ is the side length of the matrix. + ### **Python3** ```python - +class Solution: + def findMissingAndRepeatedValues(self, grid: List[List[int]]) -> List[int]: + n = len(grid) + cnt = [0] * (n * n + 1) + for row in grid: + for v in row: + cnt[v] += 1 + ans = [0] * 2 + for i in range(1, n * n + 1): + if cnt[i] == 2: + ans[0] = i + if cnt[i] == 0: + ans[1] = i + return ans ``` ### **Java** ```java - +class Solution { + public int[] findMissingAndRepeatedValues(int[][] grid) { + int n = grid.length; + int[] cnt = new int[n * n + 1]; + int[] ans = new int[2]; + for (int[] row : grid) { + for (int x : row) { + if (++cnt[x] == 2) { + ans[0] = x; + } + } + } + for (int x = 1;; ++x) { + if (cnt[x] == 0) { + ans[1] = x; + return ans; + } + } + } +} ``` ### **C++** ```cpp - +class Solution { +public: + vector findMissingAndRepeatedValues(vector>& grid) { + int n = grid.size(); + vector cnt(n * n + 1); + vector ans(2); + for (auto& row : grid) { + for (int x : row) { + if (++cnt[x] == 2) { + ans[0] = x; + } + } + } + for (int x = 1;; ++x) { + if (cnt[x] == 0) { + ans[1] = x; + return ans; + } + } + } +}; ``` ### **Go** ```go +func findMissingAndRepeatedValues(grid [][]int) []int { + n := len(grid) + ans := make([]int, 2) + cnt := make([]int, n*n+1) + for _, row := range grid { + for _, x := range row { + cnt[x]++ + if cnt[x] == 2 { + ans[0] = x + } + } + } + for x := 1; ; x++ { + if cnt[x] == 0 { + ans[1] = x + return ans + } + } +} +``` +### **TypeScript** + +```ts +function findMissingAndRepeatedValues(grid: number[][]): number[] { + const n = grid.length; + const cnt: number[] = Array(n * n + 1).fill(0); + const ans: number[] = Array(2).fill(0); + for (const row of grid) { + for (const x of row) { + if (++cnt[x] === 2) { + ans[0] = x; + } + } + } + for (let x = 1; ; ++x) { + if (cnt[x] === 0) { + ans[1] = x; + return ans; + } + } +} ``` ### **...** diff --git a/solution/2900-2999/2965.Find Missing and Repeated Values/Solution.cpp b/solution/2900-2999/2965.Find Missing and Repeated Values/Solution.cpp new file mode 100644 index 0000000000000..a94e3d15225cc --- /dev/null +++ b/solution/2900-2999/2965.Find Missing and Repeated Values/Solution.cpp @@ -0,0 +1,21 @@ +class Solution { +public: + vector findMissingAndRepeatedValues(vector>& grid) { + int n = grid.size(); + vector cnt(n * n + 1); + vector ans(2); + for (auto& row : grid) { + for (int x : row) { + if (++cnt[x] == 2) { + ans[0] = x; + } + } + } + for (int x = 1;; ++x) { + if (cnt[x] == 0) { + ans[1] = x; + return ans; + } + } + } +}; \ No newline at end of file diff --git a/solution/2900-2999/2965.Find Missing and Repeated Values/Solution.go b/solution/2900-2999/2965.Find Missing and Repeated Values/Solution.go new file mode 100644 index 0000000000000..841abb696fdd2 --- /dev/null +++ b/solution/2900-2999/2965.Find Missing and Repeated Values/Solution.go @@ -0,0 +1,19 @@ +func findMissingAndRepeatedValues(grid [][]int) []int { + n := len(grid) + ans := make([]int, 2) + cnt := make([]int, n*n+1) + for _, row := range grid { + for _, x := range row { + cnt[x]++ + if cnt[x] == 2 { + ans[0] = x + } + } + } + for x := 1; ; x++ { + if cnt[x] == 0 { + ans[1] = x + return ans + } + } +} \ No newline at end of file diff --git a/solution/2900-2999/2965.Find Missing and Repeated Values/Solution.java b/solution/2900-2999/2965.Find Missing and Repeated Values/Solution.java new file mode 100644 index 0000000000000..6e16f6e31d662 --- /dev/null +++ b/solution/2900-2999/2965.Find Missing and Repeated Values/Solution.java @@ -0,0 +1,20 @@ +class Solution { + public int[] findMissingAndRepeatedValues(int[][] grid) { + int n = grid.length; + int[] cnt = new int[n * n + 1]; + int[] ans = new int[2]; + for (int[] row : grid) { + for (int x : row) { + if (++cnt[x] == 2) { + ans[0] = x; + } + } + } + for (int x = 1;; ++x) { + if (cnt[x] == 0) { + ans[1] = x; + return ans; + } + } + } +} \ No newline at end of file diff --git a/solution/2900-2999/2965.Find Missing and Repeated Values/Solution.py b/solution/2900-2999/2965.Find Missing and Repeated Values/Solution.py new file mode 100644 index 0000000000000..71e02fe1cf02f --- /dev/null +++ b/solution/2900-2999/2965.Find Missing and Repeated Values/Solution.py @@ -0,0 +1,14 @@ +class Solution: + def findMissingAndRepeatedValues(self, grid: List[List[int]]) -> List[int]: + n = len(grid) + cnt = [0] * (n * n + 1) + for row in grid: + for v in row: + cnt[v] += 1 + ans = [0] * 2 + for i in range(1, n * n + 1): + if cnt[i] == 2: + ans[0] = i + if cnt[i] == 0: + ans[1] = i + return ans diff --git a/solution/2900-2999/2965.Find Missing and Repeated Values/Solution.ts b/solution/2900-2999/2965.Find Missing and Repeated Values/Solution.ts new file mode 100644 index 0000000000000..8603d081c0d10 --- /dev/null +++ b/solution/2900-2999/2965.Find Missing and Repeated Values/Solution.ts @@ -0,0 +1,18 @@ +function findMissingAndRepeatedValues(grid: number[][]): number[] { + const n = grid.length; + const cnt: number[] = Array(n * n + 1).fill(0); + const ans: number[] = Array(2).fill(0); + for (const row of grid) { + for (const x of row) { + if (++cnt[x] === 2) { + ans[0] = x; + } + } + } + for (let x = 1; ; ++x) { + if (cnt[x] === 0) { + ans[1] = x; + return ans; + } + } +} diff --git a/solution/2900-2999/2966.Divide Array Into Arrays With Max Difference/README.md b/solution/2900-2999/2966.Divide Array Into Arrays With Max Difference/README.md index 1c8248e8dcf22..de3dab0415aab 100644 --- a/solution/2900-2999/2966.Divide Array Into Arrays With Max Difference/README.md +++ b/solution/2900-2999/2966.Divide Array Into Arrays With Max Difference/README.md @@ -53,6 +53,12 @@ +**方法一:排序** + +我们先对数组进行排序,然后每次取出三个元素,如果这三个元素的最大值和最小值的差大于 $k$,则无法满足条件,返回空数组。否则,我们将这三个元素组成的数组加入答案数组中。 + +时间复杂度 $O(n \times \log n)$,空间复杂度 $O(n)$。其中 $n$ 是数组的长度。 + ### **Python3** @@ -60,7 +66,17 @@ ```python - +class Solution: + def divideArray(self, nums: List[int], k: int) -> List[List[int]]: + nums.sort() + ans = [] + n = len(nums) + for i in range(0, n, 3): + t = nums[i : i + 3] + if t[2] - t[0] > k: + return [] + ans.append(t) + return ans ``` ### **Java** @@ -68,19 +84,76 @@ ```java - +class Solution { + public int[][] divideArray(int[] nums, int k) { + Arrays.sort(nums); + int n = nums.length; + int[][] ans = new int[n / 3][]; + for (int i = 0; i < n; i += 3) { + int[] t = Arrays.copyOfRange(nums, i, i + 3); + if (t[2] - t[0] > k) { + return new int[][] {}; + } + ans[i / 3] = t; + } + return ans; + } +} ``` ### **C++** ```cpp - +class Solution { +public: + vector> divideArray(vector& nums, int k) { + sort(nums.begin(), nums.end()); + vector> ans; + int n = nums.size(); + for (int i = 0; i < n; i += 3) { + vector t = {nums[i], nums[i + 1], nums[i + 2]}; + if (t[2] - t[0] > k) { + return {}; + } + ans.emplace_back(t); + } + return ans; + } +}; ``` ### **Go** ```go +func divideArray(nums []int, k int) [][]int { + sort.Ints(nums) + ans := [][]int{} + for i := 0; i < len(nums); i += 3 { + t := slices.Clone(nums[i : i+3]) + if t[2]-t[0] > k { + return [][]int{} + } + ans = append(ans, t) + } + return ans +} +``` +### **TypeScript** + +```ts +function divideArray(nums: number[], k: number): number[][] { + nums.sort((a, b) => a - b); + const ans: number[][] = []; + for (let i = 0; i < nums.length; i += 3) { + const t = nums.slice(i, i + 3); + if (t[2] - t[0] > k) { + return []; + } + ans.push(t); + } + return ans; +} ``` ### **...** diff --git a/solution/2900-2999/2966.Divide Array Into Arrays With Max Difference/README_EN.md b/solution/2900-2999/2966.Divide Array Into Arrays With Max Difference/README_EN.md index 8c6739fb26aaf..bdd693f15c105 100644 --- a/solution/2900-2999/2966.Divide Array Into Arrays With Max Difference/README_EN.md +++ b/solution/2900-2999/2966.Divide Array Into Arrays With Max Difference/README_EN.md @@ -47,30 +47,103 @@ Note that the order of elements is not important. ## Solutions +**Solution 1: Sorting** + +First, we sort the array. Then, we take out three elements each time. If the difference between the maximum and minimum values of these three elements is greater than $k$, then the condition cannot be satisfied, and we return an empty array. Otherwise, we add the array composed of these three elements to the answer array. + +The time complexity is $O(n \times \log n)$, and the space complexity is $O(n)$. Here, $n$ is the length of the array. + ### **Python3** ```python - +class Solution: + def divideArray(self, nums: List[int], k: int) -> List[List[int]]: + nums.sort() + ans = [] + n = len(nums) + for i in range(0, n, 3): + t = nums[i : i + 3] + if t[2] - t[0] > k: + return [] + ans.append(t) + return ans ``` ### **Java** ```java - +class Solution { + public int[][] divideArray(int[] nums, int k) { + Arrays.sort(nums); + int n = nums.length; + int[][] ans = new int[n / 3][]; + for (int i = 0; i < n; i += 3) { + int[] t = Arrays.copyOfRange(nums, i, i + 3); + if (t[2] - t[0] > k) { + return new int[][] {}; + } + ans[i / 3] = t; + } + return ans; + } +} ``` ### **C++** ```cpp - +class Solution { +public: + vector> divideArray(vector& nums, int k) { + sort(nums.begin(), nums.end()); + vector> ans; + int n = nums.size(); + for (int i = 0; i < n; i += 3) { + vector t = {nums[i], nums[i + 1], nums[i + 2]}; + if (t[2] - t[0] > k) { + return {}; + } + ans.emplace_back(t); + } + return ans; + } +}; ``` ### **Go** ```go +func divideArray(nums []int, k int) [][]int { + sort.Ints(nums) + ans := [][]int{} + for i := 0; i < len(nums); i += 3 { + t := slices.Clone(nums[i : i+3]) + if t[2]-t[0] > k { + return [][]int{} + } + ans = append(ans, t) + } + return ans +} +``` +### **TypeScript** + +```ts +function divideArray(nums: number[], k: number): number[][] { + nums.sort((a, b) => a - b); + const ans: number[][] = []; + for (let i = 0; i < nums.length; i += 3) { + const t = nums.slice(i, i + 3); + if (t[2] - t[0] > k) { + return []; + } + ans.push(t); + } + return ans; +} ``` ### **...** diff --git a/solution/2900-2999/2966.Divide Array Into Arrays With Max Difference/Solution.cpp b/solution/2900-2999/2966.Divide Array Into Arrays With Max Difference/Solution.cpp new file mode 100644 index 0000000000000..9eba2fe563175 --- /dev/null +++ b/solution/2900-2999/2966.Divide Array Into Arrays With Max Difference/Solution.cpp @@ -0,0 +1,16 @@ +class Solution { +public: + vector> divideArray(vector& nums, int k) { + sort(nums.begin(), nums.end()); + vector> ans; + int n = nums.size(); + for (int i = 0; i < n; i += 3) { + vector t = {nums[i], nums[i + 1], nums[i + 2]}; + if (t[2] - t[0] > k) { + return {}; + } + ans.emplace_back(t); + } + return ans; + } +}; \ No newline at end of file diff --git a/solution/2900-2999/2966.Divide Array Into Arrays With Max Difference/Solution.go b/solution/2900-2999/2966.Divide Array Into Arrays With Max Difference/Solution.go new file mode 100644 index 0000000000000..d9ab6189f21bf --- /dev/null +++ b/solution/2900-2999/2966.Divide Array Into Arrays With Max Difference/Solution.go @@ -0,0 +1,12 @@ +func divideArray(nums []int, k int) [][]int { + sort.Ints(nums) + ans := [][]int{} + for i := 0; i < len(nums); i += 3 { + t := slices.Clone(nums[i : i+3]) + if t[2]-t[0] > k { + return [][]int{} + } + ans = append(ans, t) + } + return ans +} \ No newline at end of file diff --git a/solution/2900-2999/2966.Divide Array Into Arrays With Max Difference/Solution.java b/solution/2900-2999/2966.Divide Array Into Arrays With Max Difference/Solution.java new file mode 100644 index 0000000000000..0497818388191 --- /dev/null +++ b/solution/2900-2999/2966.Divide Array Into Arrays With Max Difference/Solution.java @@ -0,0 +1,15 @@ +class Solution { + public int[][] divideArray(int[] nums, int k) { + Arrays.sort(nums); + int n = nums.length; + int[][] ans = new int[n / 3][]; + for (int i = 0; i < n; i += 3) { + int[] t = Arrays.copyOfRange(nums, i, i + 3); + if (t[2] - t[0] > k) { + return new int[][] {}; + } + ans[i / 3] = t; + } + return ans; + } +} \ No newline at end of file diff --git a/solution/2900-2999/2966.Divide Array Into Arrays With Max Difference/Solution.py b/solution/2900-2999/2966.Divide Array Into Arrays With Max Difference/Solution.py new file mode 100644 index 0000000000000..9b1bd2b3f8c1e --- /dev/null +++ b/solution/2900-2999/2966.Divide Array Into Arrays With Max Difference/Solution.py @@ -0,0 +1,11 @@ +class Solution: + def divideArray(self, nums: List[int], k: int) -> List[List[int]]: + nums.sort() + ans = [] + n = len(nums) + for i in range(0, n, 3): + t = nums[i : i + 3] + if t[2] - t[0] > k: + return [] + ans.append(t) + return ans diff --git a/solution/2900-2999/2966.Divide Array Into Arrays With Max Difference/Solution.ts b/solution/2900-2999/2966.Divide Array Into Arrays With Max Difference/Solution.ts new file mode 100644 index 0000000000000..3e2841c973c2c --- /dev/null +++ b/solution/2900-2999/2966.Divide Array Into Arrays With Max Difference/Solution.ts @@ -0,0 +1,12 @@ +function divideArray(nums: number[], k: number): number[][] { + nums.sort((a, b) => a - b); + const ans: number[][] = []; + for (let i = 0; i < nums.length; i += 3) { + const t = nums.slice(i, i + 3); + if (t[2] - t[0] > k) { + return []; + } + ans.push(t); + } + return ans; +} diff --git a/solution/2900-2999/2968.Apply Operations to Maximize Frequency Score/README.md b/solution/2900-2999/2968.Apply Operations to Maximize Frequency Score/README.md index ccb8f0392b6cb..2da90d5ae24be 100644 --- a/solution/2900-2999/2968.Apply Operations to Maximize Frequency Score/README.md +++ b/solution/2900-2999/2968.Apply Operations to Maximize Frequency Score/README.md @@ -57,6 +57,36 @@ +**方法一:排序 + 前缀和 + 二分查找** + +题目求的是在最多进行 $k$ 次操作的情况下,我们能得到的众数的最大频率。如果我们将数组 $nums$ 按照从小到大的顺序排列,那么最好就是将一段连续的数字都变成同一个数,这样可以使得操作次数较少,并且众数的频率较高。 + +因此,我们不妨先对数组 $nums$ 进行排序。 + +接下来,我们再分析,如果一个频率 $x$ 是可行的,那么对于任意 $y \le x$,频率 $y$ 也是可行的,这存在着单调性。因此,我们可以通过二分查找,找到最大的满足条件的频率。 + +我们二分枚举频率,定义二分查找的左边界 $l = 0$,右边界 $r = n$,其中 $n$ 是数组的长度。每次二分查找的过程中,我们取中间值 $mid = \lfloor \frac{l + r + 1}{2} \rfloor$,然后判断 $nums$ 中是否存在一个长度为 $mid$ 的连续子数组,使得这个子数组中的所有元素都变成这个子数组的中位数,且操作次数不超过 $k$。如果存在,那么我们就将左边界 $l$ 更新为 $mid$,否则我们就将右边界 $r$ 更新为 $mid - 1$。 + +为了判断是否存在这样的子数组,我们可以使用前缀和。我们首先定义两个指针 $i$ 和 $j$,初始时 $i = 0$, $j = i + mid$。那么 $nums[i]$ 到 $nums[j - 1]$ 这一段的元素都变成 $nums[(i + j) / 2]$,所需要的操作次数为 $left + right$,其中: + +$$ +\begin{aligned} +\text{left} &= \sum_{k = i}^{(i + j) / 2 - 1} (nums[(i + j) / 2] - nums[k]) \\ +&= ((i + j) / 2 - i) \times nums[(i + j) / 2] - \sum_{k = i}^{(i + j) / 2 - 1} nums[k] +\end{aligned} +$$ + +$$ +\begin{aligned} +\text{right} &= \sum_{k = (i + j) / 2 + 1}^{j} (nums[k] - nums[(i + j) / 2]) \\ +&= \sum_{k = (i + j) / 2 + 1}^{j} nums[k] - (j - (i + j) / 2) \times nums[(i + j) / 2] +\end{aligned} +$$ + +我们可以通过前缀和数组 $s$ 来计算 $\sum_{k = i}^{j} nums[k]$,从而在 $O(1)$ 的时间内计算出 $left$ 和 $right$。 + +时间复杂度 $O(n \times \log n)$,空间复杂度 $O(n)$。其中 $n$ 是数组的长度。 + ### **Python3** @@ -64,7 +94,28 @@ ```python - +class Solution: + def maxFrequencyScore(self, nums: List[int], k: int) -> int: + nums.sort() + s = list(accumulate(nums, initial=0)) + n = len(nums) + l, r = 0, n + while l < r: + mid = (l + r + 1) >> 1 + ok = False + for i in range(n - mid + 1): + j = i + mid + x = nums[(i + j) // 2] + left = ((i + j) // 2 - i) * x - (s[(i + j) // 2] - s[i]) + right = (s[j] - s[(i + j) // 2]) - ((j - (i + j) // 2) * x) + if left + right <= k: + ok = True + break + if ok: + l = mid + else: + r = mid - 1 + return l ``` ### **Java** @@ -72,19 +123,158 @@ ```java - +class Solution { + public int maxFrequencyScore(int[] nums, long k) { + Arrays.sort(nums); + int n = nums.length; + long[] s = new long[n + 1]; + for (int i = 1; i <= n; i++) { + s[i] = s[i - 1] + nums[i - 1]; + } + int l = 0, r = n; + while (l < r) { + int mid = (l + r + 1) >> 1; + boolean ok = false; + + for (int i = 0; i <= n - mid; i++) { + int j = i + mid; + int x = nums[(i + j) / 2]; + long left = ((i + j) / 2 - i) * (long) x - (s[(i + j) / 2] - s[i]); + long right = (s[j] - s[(i + j) / 2]) - ((j - (i + j) / 2) * (long) x); + if (left + right <= k) { + ok = true; + break; + } + } + + if (ok) { + l = mid; + } else { + r = mid - 1; + } + } + + return l; + } +} ``` ### **C++** ```cpp - +class Solution { +public: + int maxFrequencyScore(vector& nums, long long k) { + sort(nums.begin(), nums.end()); + int n = nums.size(); + vector s(n + 1, 0); + for (int i = 1; i <= n; i++) { + s[i] = s[i - 1] + nums[i - 1]; + } + + int l = 0, r = n; + while (l < r) { + int mid = (l + r + 1) >> 1; + bool ok = false; + + for (int i = 0; i <= n - mid; i++) { + int j = i + mid; + int x = nums[(i + j) / 2]; + long long left = ((i + j) / 2 - i) * (long long) x - (s[(i + j) / 2] - s[i]); + long long right = (s[j] - s[(i + j) / 2]) - ((j - (i + j) / 2) * (long long) x); + + if (left + right <= k) { + ok = true; + break; + } + } + + if (ok) { + l = mid; + } else { + r = mid - 1; + } + } + + return l; + } +}; ``` ### **Go** ```go +func maxFrequencyScore(nums []int, k int64) int { + sort.Ints(nums) + n := len(nums) + s := make([]int64, n+1) + for i := 1; i <= n; i++ { + s[i] = s[i-1] + int64(nums[i-1]) + } + + l, r := 0, n + for l < r { + mid := (l + r + 1) >> 1 + ok := false + + for i := 0; i <= n-mid; i++ { + j := i + mid + x := int64(nums[(i+j)/2]) + left := (int64((i+j)/2-i) * x) - (s[(i+j)/2] - s[i]) + right := (s[j] - s[(i+j)/2]) - (int64(j-(i+j)/2) * x) + + if left+right <= k { + ok = true + break + } + } + + if ok { + l = mid + } else { + r = mid - 1 + } + } + + return l +} +``` +### **TypeScript** + +```ts +function maxFrequencyScore(nums: number[], k: number): number { + nums.sort((a, b) => a - b); + const n = nums.length; + const s: number[] = Array(n + 1).fill(0); + for (let i = 1; i <= n; i++) { + s[i] = s[i - 1] + nums[i - 1]; + } + + let l: number = 0; + let r: number = n; + while (l < r) { + const mid: number = (l + r + 1) >> 1; + let ok: boolean = false; + for (let i = 0; i <= n - mid; i++) { + const j = i + mid; + const x = nums[Math.floor((i + j) / 2)]; + const left = (Math.floor((i + j) / 2) - i) * x - (s[Math.floor((i + j) / 2)] - s[i]); + const right = s[j] - s[Math.floor((i + j) / 2)] - (j - Math.floor((i + j) / 2)) * x; + if (left + right <= k) { + ok = true; + break; + } + } + if (ok) { + l = mid; + } else { + r = mid - 1; + } + } + + return l; +} ``` ### **...** diff --git a/solution/2900-2999/2968.Apply Operations to Maximize Frequency Score/README_EN.md b/solution/2900-2999/2968.Apply Operations to Maximize Frequency Score/README_EN.md index 5af4970451bd1..8bd11dd5a708b 100644 --- a/solution/2900-2999/2968.Apply Operations to Maximize Frequency Score/README_EN.md +++ b/solution/2900-2999/2968.Apply Operations to Maximize Frequency Score/README_EN.md @@ -51,30 +51,220 @@ It can be shown that we cannot achieve a better score. ## Solutions +**Solution 1: Sorting + Prefix Sum + Binary Search** + +The problem asks for the maximum frequency of the mode we can get after performing at most $k$ operations. If we sort the array $nums$ in ascending order, it would be best to turn a continuous segment of numbers into the same number, which can reduce the number of operations and increase the frequency of the mode. + +Therefore, we might as well sort the array $nums$ first. + +Next, we analyze that if a frequency $x$ is feasible, then for any $y \le x$, the frequency $y$ is also feasible, which shows monotonicity. Therefore, we can use binary search to find the maximum feasible frequency. + +We binary search the frequency, define the left boundary of the binary search as $l = 0$, and the right boundary as $r = n$, where $n$ is the length of the array. In each binary search process, we take the middle value $mid = \lfloor \frac{l + r + 1}{2} \rfloor$, and then determine whether there exists a continuous subarray of length $mid$ in $nums$, such that all elements in this subarray become the median of this subarray, and the number of operations does not exceed $k$. If it exists, then we update the left boundary $l$ to $mid$, otherwise we update the right boundary $r$ to $mid - 1$. + +To determine whether such a subarray exists, we can use prefix sum. We first define two pointers $i$ and $j$, initially $i = 0$, $j = i + mid$. Then all elements from $nums[i]$ to $nums[j - 1]$ are changed to $nums[(i + j) / 2]$, and the number of operations required is $left + right$, where: + +$$ +\begin{aligned} +\text{left} &= \sum_{k = i}^{(i + j) / 2 - 1} (nums[(i + j) / 2] - nums[k]) \\ +&= ((i + j) / 2 - i) \times nums[(i + j) / 2] - \sum_{k = i}^{(i + j) / 2 - 1} nums[k] +\end{aligned} +$$ + +$$ +\begin{aligned} +\text{right} &= \sum_{k = (i + j) / 2 + 1}^{j} (nums[k] - nums[(i + j) / 2]) \\ +&= \sum_{k = (i + j) / 2 + 1}^{j} nums[k] - (j - (i + j) / 2) \times nums[(i + j) / 2] +\end{aligned} +$$ + +We can use the prefix sum array $s$ to calculate $\sum_{k = i}^{j} nums[k]$, so as to calculate $left$ and $right$ in $O(1)$ time. + +The time complexity is $O(n \times \log n)$, and the space complexity is $O(n)$. Here, $n$ is the length of the array. + ### **Python3** ```python - +class Solution: + def maxFrequencyScore(self, nums: List[int], k: int) -> int: + nums.sort() + s = list(accumulate(nums, initial=0)) + n = len(nums) + l, r = 0, n + while l < r: + mid = (l + r + 1) >> 1 + ok = False + for i in range(n - mid + 1): + j = i + mid + x = nums[(i + j) // 2] + left = ((i + j) // 2 - i) * x - (s[(i + j) // 2] - s[i]) + right = (s[j] - s[(i + j) // 2]) - ((j - (i + j) // 2) * x) + if left + right <= k: + ok = True + break + if ok: + l = mid + else: + r = mid - 1 + return l ``` ### **Java** ```java - +class Solution { + public int maxFrequencyScore(int[] nums, long k) { + Arrays.sort(nums); + int n = nums.length; + long[] s = new long[n + 1]; + for (int i = 1; i <= n; i++) { + s[i] = s[i - 1] + nums[i - 1]; + } + int l = 0, r = n; + while (l < r) { + int mid = (l + r + 1) >> 1; + boolean ok = false; + + for (int i = 0; i <= n - mid; i++) { + int j = i + mid; + int x = nums[(i + j) / 2]; + long left = ((i + j) / 2 - i) * (long) x - (s[(i + j) / 2] - s[i]); + long right = (s[j] - s[(i + j) / 2]) - ((j - (i + j) / 2) * (long) x); + if (left + right <= k) { + ok = true; + break; + } + } + + if (ok) { + l = mid; + } else { + r = mid - 1; + } + } + + return l; + } +} ``` ### **C++** ```cpp - +class Solution { +public: + int maxFrequencyScore(vector& nums, long long k) { + sort(nums.begin(), nums.end()); + int n = nums.size(); + vector s(n + 1, 0); + for (int i = 1; i <= n; i++) { + s[i] = s[i - 1] + nums[i - 1]; + } + + int l = 0, r = n; + while (l < r) { + int mid = (l + r + 1) >> 1; + bool ok = false; + + for (int i = 0; i <= n - mid; i++) { + int j = i + mid; + int x = nums[(i + j) / 2]; + long long left = ((i + j) / 2 - i) * (long long) x - (s[(i + j) / 2] - s[i]); + long long right = (s[j] - s[(i + j) / 2]) - ((j - (i + j) / 2) * (long long) x); + + if (left + right <= k) { + ok = true; + break; + } + } + + if (ok) { + l = mid; + } else { + r = mid - 1; + } + } + + return l; + } +}; ``` ### **Go** ```go +func maxFrequencyScore(nums []int, k int64) int { + sort.Ints(nums) + n := len(nums) + s := make([]int64, n+1) + for i := 1; i <= n; i++ { + s[i] = s[i-1] + int64(nums[i-1]) + } + + l, r := 0, n + for l < r { + mid := (l + r + 1) >> 1 + ok := false + + for i := 0; i <= n-mid; i++ { + j := i + mid + x := int64(nums[(i+j)/2]) + left := (int64((i+j)/2-i) * x) - (s[(i+j)/2] - s[i]) + right := (s[j] - s[(i+j)/2]) - (int64(j-(i+j)/2) * x) + + if left+right <= k { + ok = true + break + } + } + + if ok { + l = mid + } else { + r = mid - 1 + } + } + + return l +} +``` +### **TypeScript** + +```ts +function maxFrequencyScore(nums: number[], k: number): number { + nums.sort((a, b) => a - b); + const n = nums.length; + const s: number[] = Array(n + 1).fill(0); + for (let i = 1; i <= n; i++) { + s[i] = s[i - 1] + nums[i - 1]; + } + + let l: number = 0; + let r: number = n; + while (l < r) { + const mid: number = (l + r + 1) >> 1; + let ok: boolean = false; + for (let i = 0; i <= n - mid; i++) { + const j = i + mid; + const x = nums[Math.floor((i + j) / 2)]; + const left = (Math.floor((i + j) / 2) - i) * x - (s[Math.floor((i + j) / 2)] - s[i]); + const right = s[j] - s[Math.floor((i + j) / 2)] - (j - Math.floor((i + j) / 2)) * x; + if (left + right <= k) { + ok = true; + break; + } + } + if (ok) { + l = mid; + } else { + r = mid - 1; + } + } + + return l; +} ``` ### **...** diff --git a/solution/2900-2999/2968.Apply Operations to Maximize Frequency Score/Solution.cpp b/solution/2900-2999/2968.Apply Operations to Maximize Frequency Score/Solution.cpp new file mode 100644 index 0000000000000..4f8653ba8856a --- /dev/null +++ b/solution/2900-2999/2968.Apply Operations to Maximize Frequency Score/Solution.cpp @@ -0,0 +1,37 @@ +class Solution { +public: + int maxFrequencyScore(vector& nums, long long k) { + sort(nums.begin(), nums.end()); + int n = nums.size(); + vector s(n + 1, 0); + for (int i = 1; i <= n; i++) { + s[i] = s[i - 1] + nums[i - 1]; + } + + int l = 0, r = n; + while (l < r) { + int mid = (l + r + 1) >> 1; + bool ok = false; + + for (int i = 0; i <= n - mid; i++) { + int j = i + mid; + int x = nums[(i + j) / 2]; + long long left = ((i + j) / 2 - i) * (long long) x - (s[(i + j) / 2] - s[i]); + long long right = (s[j] - s[(i + j) / 2]) - ((j - (i + j) / 2) * (long long) x); + + if (left + right <= k) { + ok = true; + break; + } + } + + if (ok) { + l = mid; + } else { + r = mid - 1; + } + } + + return l; + } +}; \ No newline at end of file diff --git a/solution/2900-2999/2968.Apply Operations to Maximize Frequency Score/Solution.go b/solution/2900-2999/2968.Apply Operations to Maximize Frequency Score/Solution.go new file mode 100644 index 0000000000000..1a54371c31360 --- /dev/null +++ b/solution/2900-2999/2968.Apply Operations to Maximize Frequency Score/Solution.go @@ -0,0 +1,34 @@ +func maxFrequencyScore(nums []int, k int64) int { + sort.Ints(nums) + n := len(nums) + s := make([]int64, n+1) + for i := 1; i <= n; i++ { + s[i] = s[i-1] + int64(nums[i-1]) + } + + l, r := 0, n + for l < r { + mid := (l + r + 1) >> 1 + ok := false + + for i := 0; i <= n-mid; i++ { + j := i + mid + x := int64(nums[(i+j)/2]) + left := (int64((i+j)/2-i) * x) - (s[(i+j)/2] - s[i]) + right := (s[j] - s[(i+j)/2]) - (int64(j-(i+j)/2) * x) + + if left+right <= k { + ok = true + break + } + } + + if ok { + l = mid + } else { + r = mid - 1 + } + } + + return l +} \ No newline at end of file diff --git a/solution/2900-2999/2968.Apply Operations to Maximize Frequency Score/Solution.java b/solution/2900-2999/2968.Apply Operations to Maximize Frequency Score/Solution.java new file mode 100644 index 0000000000000..4419fce9c5fbb --- /dev/null +++ b/solution/2900-2999/2968.Apply Operations to Maximize Frequency Score/Solution.java @@ -0,0 +1,34 @@ +class Solution { + public int maxFrequencyScore(int[] nums, long k) { + Arrays.sort(nums); + int n = nums.length; + long[] s = new long[n + 1]; + for (int i = 1; i <= n; i++) { + s[i] = s[i - 1] + nums[i - 1]; + } + int l = 0, r = n; + while (l < r) { + int mid = (l + r + 1) >> 1; + boolean ok = false; + + for (int i = 0; i <= n - mid; i++) { + int j = i + mid; + int x = nums[(i + j) / 2]; + long left = ((i + j) / 2 - i) * (long) x - (s[(i + j) / 2] - s[i]); + long right = (s[j] - s[(i + j) / 2]) - ((j - (i + j) / 2) * (long) x); + if (left + right <= k) { + ok = true; + break; + } + } + + if (ok) { + l = mid; + } else { + r = mid - 1; + } + } + + return l; + } +} \ No newline at end of file diff --git a/solution/2900-2999/2968.Apply Operations to Maximize Frequency Score/Solution.py b/solution/2900-2999/2968.Apply Operations to Maximize Frequency Score/Solution.py new file mode 100644 index 0000000000000..5ac1360566fcc --- /dev/null +++ b/solution/2900-2999/2968.Apply Operations to Maximize Frequency Score/Solution.py @@ -0,0 +1,22 @@ +class Solution: + def maxFrequencyScore(self, nums: List[int], k: int) -> int: + nums.sort() + s = list(accumulate(nums, initial=0)) + n = len(nums) + l, r = 0, n + while l < r: + mid = (l + r + 1) >> 1 + ok = False + for i in range(n - mid + 1): + j = i + mid + x = nums[(i + j) // 2] + left = ((i + j) // 2 - i) * x - (s[(i + j) // 2] - s[i]) + right = (s[j] - s[(i + j) // 2]) - ((j - (i + j) // 2) * x) + if left + right <= k: + ok = True + break + if ok: + l = mid + else: + r = mid - 1 + return l diff --git a/solution/2900-2999/2968.Apply Operations to Maximize Frequency Score/Solution.ts b/solution/2900-2999/2968.Apply Operations to Maximize Frequency Score/Solution.ts new file mode 100644 index 0000000000000..f3e49ea231c4d --- /dev/null +++ b/solution/2900-2999/2968.Apply Operations to Maximize Frequency Score/Solution.ts @@ -0,0 +1,32 @@ +function maxFrequencyScore(nums: number[], k: number): number { + nums.sort((a, b) => a - b); + const n = nums.length; + const s: number[] = Array(n + 1).fill(0); + for (let i = 1; i <= n; i++) { + s[i] = s[i - 1] + nums[i - 1]; + } + + let l: number = 0; + let r: number = n; + while (l < r) { + const mid: number = (l + r + 1) >> 1; + let ok: boolean = false; + for (let i = 0; i <= n - mid; i++) { + const j = i + mid; + const x = nums[Math.floor((i + j) / 2)]; + const left = (Math.floor((i + j) / 2) - i) * x - (s[Math.floor((i + j) / 2)] - s[i]); + const right = s[j] - s[Math.floor((i + j) / 2)] - (j - Math.floor((i + j) / 2)) * x; + if (left + right <= k) { + ok = true; + break; + } + } + if (ok) { + l = mid; + } else { + r = mid - 1; + } + } + + return l; +} From f0ec4ac5e0b343b553c714983c28df3b1859204e Mon Sep 17 00:00:00 2001 From: Libin YANG Date: Sun, 17 Dec 2023 14:02:24 +0800 Subject: [PATCH 6/8] feat: add solutions to lc problem: No.2967 (#2113) No.2967.Minimum Cost to Make Array Equalindromic --- .../README.md | 202 +++++++++++++++++- .../README_EN.md | 202 +++++++++++++++++- .../Solution.cpp | 39 ++++ .../Solution.go | 52 +++++ .../Solution.java | 38 ++++ .../Solution.py | 18 ++ .../Solution.ts | 40 ++++ 7 files changed, 585 insertions(+), 6 deletions(-) create mode 100644 solution/2900-2999/2967.Minimum Cost to Make Array Equalindromic/Solution.cpp create mode 100644 solution/2900-2999/2967.Minimum Cost to Make Array Equalindromic/Solution.go create mode 100644 solution/2900-2999/2967.Minimum Cost to Make Array Equalindromic/Solution.java create mode 100644 solution/2900-2999/2967.Minimum Cost to Make Array Equalindromic/Solution.py create mode 100644 solution/2900-2999/2967.Minimum Cost to Make Array Equalindromic/Solution.ts diff --git a/solution/2900-2999/2967.Minimum Cost to Make Array Equalindromic/README.md b/solution/2900-2999/2967.Minimum Cost to Make Array Equalindromic/README.md index d72a88ca8090e..2c4c5cf39502c 100644 --- a/solution/2900-2999/2967.Minimum Cost to Make Array Equalindromic/README.md +++ b/solution/2900-2999/2967.Minimum Cost to Make Array Equalindromic/README.md @@ -64,6 +64,14 @@ +**方法一:预处理 + 排序 + 二分查找** + +题目中回文数的范围是 $[1, 10^9]$,回文数由于对称性,我们可以在 $[1, 10^5]$ 的范围内枚举,然后将其翻转后拼接,得到所有的回文数,注意,如果是奇数长度的回文数,我们在翻转前要去掉最后一位。预处理得到的回文数数组记为 $ps$。我们对数组 $ps$ 进行排序。 + +接下来,我们对数组 $nums$ 进行排序,然后取 $nums$ 的中位数 $x$,我们只需要通过二分查找,在回文数组 $ps$ 中,找到一个与 $x$ 最接近的数,然后计算 $nums$ 变成这个数的代价,即可得到答案。 + +时间复杂度 $O(n \times \log n)$,空间复杂度 $O(M)$。其中 $n$ 是数组 $nums$ 的长度,而 $M$ 是回文数组 $ps$ 的长度。 + ### **Python3** @@ -71,7 +79,24 @@ ```python - +ps = [] +for i in range(1, 10**5 + 1): + s = str(i) + t1 = s[::-1] + t2 = s[:-1][::-1] + ps.append(int(s + t1)) + ps.append(int(s + t2)) +ps.sort() + + +class Solution: + def minimumCost(self, nums: List[int]) -> int: + def f(x: int) -> int: + return sum(abs(v - x) for v in nums) + + nums.sort() + i = bisect_left(ps, nums[len(nums) // 2]) + return min(f(ps[j]) for j in range(i - 1, i + 2) if 0 <= j < len(ps)) ``` ### **Java** @@ -79,19 +104,190 @@ ```java - +public class Solution { + private static long[] ps; + private int[] nums; + + static { + ps = new long[2 * (int) 1e5]; + for (int i = 1; i <= 1e5; i++) { + String s = Integer.toString(i); + String t1 = new StringBuilder(s).reverse().toString(); + String t2 = new StringBuilder(s.substring(0, s.length() - 1)).reverse().toString(); + ps[2 * i - 2] = Long.parseLong(s + t1); + ps[2 * i - 1] = Long.parseLong(s + t2); + } + Arrays.sort(ps); + } + + public long minimumCost(int[] nums) { + this.nums = nums; + Arrays.sort(nums); + int i = Arrays.binarySearch(ps, nums[nums.length / 2]); + i = i < 0 ? -i - 1 : i; + long ans = 1L << 60; + for (int j = i - 1; j <= i + 1; j++) { + if (0 <= j && j < ps.length) { + ans = Math.min(ans, f(ps[j])); + } + } + return ans; + } + + private long f(long x) { + long ans = 0; + for (int v : nums) { + ans += Math.abs(v - x); + } + return ans; + } +} ``` ### **C++** ```cpp - +using ll = long long; + +ll ps[2 * 100000]; + +int init = [] { + for (int i = 1; i <= 100000; i++) { + string s = to_string(i); + string t1 = s; + reverse(t1.begin(), t1.end()); + string t2 = s.substr(0, s.length() - 1); + reverse(t2.begin(), t2.end()); + ps[2 * i - 2] = stoll(s + t1); + ps[2 * i - 1] = stoll(s + t2); + } + sort(ps, ps + 2 * 100000); + return 0; +}(); + +class Solution { +public: + long long minimumCost(vector& nums) { + sort(nums.begin(), nums.end()); + int i = lower_bound(ps, ps + 2 * 100000, nums[nums.size() / 2]) - ps; + auto f = [&](ll x) { + ll ans = 0; + for (int& v : nums) { + ans += abs(v - x); + } + return ans; + }; + ll ans = LLONG_MAX; + for (int j = i - 1; j <= i + 1; j++) { + if (0 <= j && j < 2 * 100000) { + ans = min(ans, f(ps[j])); + } + } + return ans; + } +}; ``` ### **Go** ```go +var ps [2 * 100000]int64 + +func init() { + for i := 1; i <= 100000; i++ { + s := strconv.Itoa(i) + t1 := reverseString(s) + t2 := reverseString(s[:len(s)-1]) + ps[2*i-2], _ = strconv.ParseInt(s+t1, 10, 64) + ps[2*i-1], _ = strconv.ParseInt(s+t2, 10, 64) + } + sort.Slice(ps[:], func(i, j int) bool { + return ps[i] < ps[j] + }) +} + +func reverseString(s string) string { + cs := []rune(s) + for i, j := 0, len(cs)-1; i < j; i, j = i+1, j-1 { + cs[i], cs[j] = cs[j], cs[i] + } + return string(cs) +} + +func minimumCost(nums []int) int64 { + sort.Ints(nums) + i := sort.Search(len(ps), func(i int) bool { + return ps[i] >= int64(nums[len(nums)/2]) + }) + + f := func(x int64) int64 { + var ans int64 + for _, v := range nums { + ans += int64(abs(int(x - int64(v)))) + } + return ans + } + + ans := int64(math.MaxInt64) + for j := i - 1; j <= i+1; j++ { + if 0 <= j && j < len(ps) { + ans = min(ans, f(ps[j])) + } + } + return ans +} + +func abs(x int) int { + if x < 0 { + return -x + } + return x +} +``` +### **TypeScript** + +```ts +const ps = Array(2e5).fill(0); + +const init = (() => { + for (let i = 1; i <= 1e5; ++i) { + const s: string = i.toString(); + const t1: string = s.split('').reverse().join(''); + const t2: string = s.slice(0, -1).split('').reverse().join(''); + ps[2 * i - 2] = parseInt(s + t1, 10); + ps[2 * i - 1] = parseInt(s + t2, 10); + } + ps.sort((a, b) => a - b); +})(); + +function minimumCost(nums: number[]): number { + const search = (x: number): number => { + let [l, r] = [0, ps.length]; + while (l < r) { + const mid = (l + r) >> 1; + if (ps[mid] >= x) { + r = mid; + } else { + l = mid + 1; + } + } + return l; + }; + const f = (x: number): number => { + return nums.reduce((acc, v) => acc + Math.abs(v - x), 0); + }; + + nums.sort((a, b) => a - b); + const i: number = search(nums[nums.length >> 1]); + let ans: number = Number.MAX_SAFE_INTEGER; + for (let j = i - 1; j <= i + 1; j++) { + if (j >= 0 && j < ps.length) { + ans = Math.min(ans, f(ps[j])); + } + } + return ans; +} ``` ### **...** diff --git a/solution/2900-2999/2967.Minimum Cost to Make Array Equalindromic/README_EN.md b/solution/2900-2999/2967.Minimum Cost to Make Array Equalindromic/README_EN.md index 2e9b90c469847..7d70b0530e373 100644 --- a/solution/2900-2999/2967.Minimum Cost to Make Array Equalindromic/README_EN.md +++ b/solution/2900-2999/2967.Minimum Cost to Make Array Equalindromic/README_EN.md @@ -58,30 +58,226 @@ It can be shown that changing all elements to any palindromic number other than ## Solutions +**Solution 1: Preprocessing + Sorting + Binary Search** + +The range of palindrome numbers in the problem is $[1, 10^9]$. Due to the symmetry of palindrome numbers, we can enumerate in the range of $[1, 10^5]$, then reverse and concatenate them to get all palindrome numbers. Note that if it is an odd-length palindrome number, we need to remove the last digit before reversing. The array of palindrome numbers obtained by preprocessing is denoted as $ps$. We sort the array $ps$. + +Next, we sort the array $nums$ and take the median $x$ of $nums$. We only need to find a number in the palindrome array $ps$ that is closest to $x$ through binary search, and then calculate the cost of $nums$ becoming this number to get the answer. + +The time complexity is $O(n \times \log n)$, and the space complexity is $O(M)$. Here, $n$ is the length of the array $nums$, and $M$ is the length of the palindrome array $ps$. + ### **Python3** ```python - +ps = [] +for i in range(1, 10**5 + 1): + s = str(i) + t1 = s[::-1] + t2 = s[:-1][::-1] + ps.append(int(s + t1)) + ps.append(int(s + t2)) +ps.sort() + + +class Solution: + def minimumCost(self, nums: List[int]) -> int: + def f(x: int) -> int: + return sum(abs(v - x) for v in nums) + + nums.sort() + i = bisect_left(ps, nums[len(nums) // 2]) + return min(f(ps[j]) for j in range(i - 1, i + 2) if 0 <= j < len(ps)) ``` ### **Java** ```java - +public class Solution { + private static long[] ps; + private int[] nums; + + static { + ps = new long[2 * (int) 1e5]; + for (int i = 1; i <= 1e5; i++) { + String s = Integer.toString(i); + String t1 = new StringBuilder(s).reverse().toString(); + String t2 = new StringBuilder(s.substring(0, s.length() - 1)).reverse().toString(); + ps[2 * i - 2] = Long.parseLong(s + t1); + ps[2 * i - 1] = Long.parseLong(s + t2); + } + Arrays.sort(ps); + } + + public long minimumCost(int[] nums) { + this.nums = nums; + Arrays.sort(nums); + int i = Arrays.binarySearch(ps, nums[nums.length / 2]); + i = i < 0 ? -i - 1 : i; + long ans = 1L << 60; + for (int j = i - 1; j <= i + 1; j++) { + if (0 <= j && j < ps.length) { + ans = Math.min(ans, f(ps[j])); + } + } + return ans; + } + + private long f(long x) { + long ans = 0; + for (int v : nums) { + ans += Math.abs(v - x); + } + return ans; + } +} ``` ### **C++** ```cpp - +using ll = long long; + +ll ps[2 * 100000]; + +int init = [] { + for (int i = 1; i <= 100000; i++) { + string s = to_string(i); + string t1 = s; + reverse(t1.begin(), t1.end()); + string t2 = s.substr(0, s.length() - 1); + reverse(t2.begin(), t2.end()); + ps[2 * i - 2] = stoll(s + t1); + ps[2 * i - 1] = stoll(s + t2); + } + sort(ps, ps + 2 * 100000); + return 0; +}(); + +class Solution { +public: + long long minimumCost(vector& nums) { + sort(nums.begin(), nums.end()); + int i = lower_bound(ps, ps + 2 * 100000, nums[nums.size() / 2]) - ps; + auto f = [&](ll x) { + ll ans = 0; + for (int& v : nums) { + ans += abs(v - x); + } + return ans; + }; + ll ans = LLONG_MAX; + for (int j = i - 1; j <= i + 1; j++) { + if (0 <= j && j < 2 * 100000) { + ans = min(ans, f(ps[j])); + } + } + return ans; + } +}; ``` ### **Go** ```go +var ps [2 * 100000]int64 + +func init() { + for i := 1; i <= 100000; i++ { + s := strconv.Itoa(i) + t1 := reverseString(s) + t2 := reverseString(s[:len(s)-1]) + ps[2*i-2], _ = strconv.ParseInt(s+t1, 10, 64) + ps[2*i-1], _ = strconv.ParseInt(s+t2, 10, 64) + } + sort.Slice(ps[:], func(i, j int) bool { + return ps[i] < ps[j] + }) +} + +func reverseString(s string) string { + cs := []rune(s) + for i, j := 0, len(cs)-1; i < j; i, j = i+1, j-1 { + cs[i], cs[j] = cs[j], cs[i] + } + return string(cs) +} + +func minimumCost(nums []int) int64 { + sort.Ints(nums) + i := sort.Search(len(ps), func(i int) bool { + return ps[i] >= int64(nums[len(nums)/2]) + }) + + f := func(x int64) int64 { + var ans int64 + for _, v := range nums { + ans += int64(abs(int(x - int64(v)))) + } + return ans + } + + ans := int64(math.MaxInt64) + for j := i - 1; j <= i+1; j++ { + if 0 <= j && j < len(ps) { + ans = min(ans, f(ps[j])) + } + } + return ans +} + +func abs(x int) int { + if x < 0 { + return -x + } + return x +} +``` +### **TypeScript** + +```ts +const ps = Array(2e5).fill(0); + +const init = (() => { + for (let i = 1; i <= 1e5; ++i) { + const s: string = i.toString(); + const t1: string = s.split('').reverse().join(''); + const t2: string = s.slice(0, -1).split('').reverse().join(''); + ps[2 * i - 2] = parseInt(s + t1, 10); + ps[2 * i - 1] = parseInt(s + t2, 10); + } + ps.sort((a, b) => a - b); +})(); + +function minimumCost(nums: number[]): number { + const search = (x: number): number => { + let [l, r] = [0, ps.length]; + while (l < r) { + const mid = (l + r) >> 1; + if (ps[mid] >= x) { + r = mid; + } else { + l = mid + 1; + } + } + return l; + }; + const f = (x: number): number => { + return nums.reduce((acc, v) => acc + Math.abs(v - x), 0); + }; + + nums.sort((a, b) => a - b); + const i: number = search(nums[nums.length >> 1]); + let ans: number = Number.MAX_SAFE_INTEGER; + for (let j = i - 1; j <= i + 1; j++) { + if (j >= 0 && j < ps.length) { + ans = Math.min(ans, f(ps[j])); + } + } + return ans; +} ``` ### **...** diff --git a/solution/2900-2999/2967.Minimum Cost to Make Array Equalindromic/Solution.cpp b/solution/2900-2999/2967.Minimum Cost to Make Array Equalindromic/Solution.cpp new file mode 100644 index 0000000000000..923c31f196570 --- /dev/null +++ b/solution/2900-2999/2967.Minimum Cost to Make Array Equalindromic/Solution.cpp @@ -0,0 +1,39 @@ +using ll = long long; + +ll ps[2 * 100000]; + +int init = [] { + for (int i = 1; i <= 100000; i++) { + string s = to_string(i); + string t1 = s; + reverse(t1.begin(), t1.end()); + string t2 = s.substr(0, s.length() - 1); + reverse(t2.begin(), t2.end()); + ps[2 * i - 2] = stoll(s + t1); + ps[2 * i - 1] = stoll(s + t2); + } + sort(ps, ps + 2 * 100000); + return 0; +}(); + +class Solution { +public: + long long minimumCost(vector& nums) { + sort(nums.begin(), nums.end()); + int i = lower_bound(ps, ps + 2 * 100000, nums[nums.size() / 2]) - ps; + auto f = [&](ll x) { + ll ans = 0; + for (int& v : nums) { + ans += abs(v - x); + } + return ans; + }; + ll ans = LLONG_MAX; + for (int j = i - 1; j <= i + 1; j++) { + if (0 <= j && j < 2 * 100000) { + ans = min(ans, f(ps[j])); + } + } + return ans; + } +}; \ No newline at end of file diff --git a/solution/2900-2999/2967.Minimum Cost to Make Array Equalindromic/Solution.go b/solution/2900-2999/2967.Minimum Cost to Make Array Equalindromic/Solution.go new file mode 100644 index 0000000000000..3f6b36621dcbd --- /dev/null +++ b/solution/2900-2999/2967.Minimum Cost to Make Array Equalindromic/Solution.go @@ -0,0 +1,52 @@ +var ps [2 * 100000]int64 + +func init() { + for i := 1; i <= 100000; i++ { + s := strconv.Itoa(i) + t1 := reverseString(s) + t2 := reverseString(s[:len(s)-1]) + ps[2*i-2], _ = strconv.ParseInt(s+t1, 10, 64) + ps[2*i-1], _ = strconv.ParseInt(s+t2, 10, 64) + } + sort.Slice(ps[:], func(i, j int) bool { + return ps[i] < ps[j] + }) +} + +func reverseString(s string) string { + cs := []rune(s) + for i, j := 0, len(cs)-1; i < j; i, j = i+1, j-1 { + cs[i], cs[j] = cs[j], cs[i] + } + return string(cs) +} + +func minimumCost(nums []int) int64 { + sort.Ints(nums) + i := sort.Search(len(ps), func(i int) bool { + return ps[i] >= int64(nums[len(nums)/2]) + }) + + f := func(x int64) int64 { + var ans int64 + for _, v := range nums { + ans += int64(abs(int(x - int64(v)))) + } + return ans + } + + ans := int64(math.MaxInt64) + for j := i - 1; j <= i+1; j++ { + if 0 <= j && j < len(ps) { + ans = min(ans, f(ps[j])) + } + } + return ans +} + +func abs(x int) int { + if x < 0 { + return -x + } + return x +} \ No newline at end of file diff --git a/solution/2900-2999/2967.Minimum Cost to Make Array Equalindromic/Solution.java b/solution/2900-2999/2967.Minimum Cost to Make Array Equalindromic/Solution.java new file mode 100644 index 0000000000000..a5fcc83957b9c --- /dev/null +++ b/solution/2900-2999/2967.Minimum Cost to Make Array Equalindromic/Solution.java @@ -0,0 +1,38 @@ +public class Solution { + private static long[] ps; + private int[] nums; + + static { + ps = new long[2 * (int) 1e5]; + for (int i = 1; i <= 1e5; i++) { + String s = Integer.toString(i); + String t1 = new StringBuilder(s).reverse().toString(); + String t2 = new StringBuilder(s.substring(0, s.length() - 1)).reverse().toString(); + ps[2 * i - 2] = Long.parseLong(s + t1); + ps[2 * i - 1] = Long.parseLong(s + t2); + } + Arrays.sort(ps); + } + + public long minimumCost(int[] nums) { + this.nums = nums; + Arrays.sort(nums); + int i = Arrays.binarySearch(ps, nums[nums.length / 2]); + i = i < 0 ? -i - 1 : i; + long ans = 1L << 60; + for (int j = i - 1; j <= i + 1; j++) { + if (0 <= j && j < ps.length) { + ans = Math.min(ans, f(ps[j])); + } + } + return ans; + } + + private long f(long x) { + long ans = 0; + for (int v : nums) { + ans += Math.abs(v - x); + } + return ans; + } +} \ No newline at end of file diff --git a/solution/2900-2999/2967.Minimum Cost to Make Array Equalindromic/Solution.py b/solution/2900-2999/2967.Minimum Cost to Make Array Equalindromic/Solution.py new file mode 100644 index 0000000000000..602f8df4810ee --- /dev/null +++ b/solution/2900-2999/2967.Minimum Cost to Make Array Equalindromic/Solution.py @@ -0,0 +1,18 @@ +ps = [] +for i in range(1, 10**5 + 1): + s = str(i) + t1 = s[::-1] + t2 = s[:-1][::-1] + ps.append(int(s + t1)) + ps.append(int(s + t2)) +ps.sort() + + +class Solution: + def minimumCost(self, nums: List[int]) -> int: + def f(x: int) -> int: + return sum(abs(v - x) for v in nums) + + nums.sort() + i = bisect_left(ps, nums[len(nums) // 2]) + return min(f(ps[j]) for j in range(i - 1, i + 2) if 0 <= j < len(ps)) diff --git a/solution/2900-2999/2967.Minimum Cost to Make Array Equalindromic/Solution.ts b/solution/2900-2999/2967.Minimum Cost to Make Array Equalindromic/Solution.ts new file mode 100644 index 0000000000000..431112126f4db --- /dev/null +++ b/solution/2900-2999/2967.Minimum Cost to Make Array Equalindromic/Solution.ts @@ -0,0 +1,40 @@ +const ps = Array(2e5).fill(0); + +const init = (() => { + for (let i = 1; i <= 1e5; ++i) { + const s: string = i.toString(); + const t1: string = s.split('').reverse().join(''); + const t2: string = s.slice(0, -1).split('').reverse().join(''); + ps[2 * i - 2] = parseInt(s + t1, 10); + ps[2 * i - 1] = parseInt(s + t2, 10); + } + ps.sort((a, b) => a - b); +})(); + +function minimumCost(nums: number[]): number { + const search = (x: number): number => { + let [l, r] = [0, ps.length]; + while (l < r) { + const mid = (l + r) >> 1; + if (ps[mid] >= x) { + r = mid; + } else { + l = mid + 1; + } + } + return l; + }; + const f = (x: number): number => { + return nums.reduce((acc, v) => acc + Math.abs(v - x), 0); + }; + + nums.sort((a, b) => a - b); + const i: number = search(nums[nums.length >> 1]); + let ans: number = Number.MAX_SAFE_INTEGER; + for (let j = i - 1; j <= i + 1; j++) { + if (j >= 0 && j < ps.length) { + ans = Math.min(ans, f(ps[j])); + } + } + return ans; +} From 5d4fd65b5ef10b4510174f29ceb18979f4945173 Mon Sep 17 00:00:00 2001 From: Herschel Date: Sun, 17 Dec 2023 15:31:37 +0800 Subject: [PATCH 7/8] feat: add rust solution to lc problem: No.65 (#2114) --- .../0000-0099/0065.Valid Number/README.md | 65 +++++++++++++++++++ .../0000-0099/0065.Valid Number/README_EN.md | 62 ++++++++++++++++++ .../0000-0099/0065.Valid Number/Solution.rs | 57 ++++++++++++++++ 3 files changed, 184 insertions(+) create mode 100644 solution/0000-0099/0065.Valid Number/Solution.rs diff --git a/solution/0000-0099/0065.Valid Number/README.md b/solution/0000-0099/0065.Valid Number/README.md index 77174ec8d40ad..a702e9d577960 100644 --- a/solution/0000-0099/0065.Valid Number/README.md +++ b/solution/0000-0099/0065.Valid Number/README.md @@ -260,6 +260,71 @@ public class Solution { } ``` +### **Rust** + +```rust +impl Solution { + pub fn is_number(s: String) -> bool { + let mut i = 0; + let n = s.len(); + + if let Some(c) = s.chars().nth(i) { + if c == '+' || c == '-' { + i += 1; + if i == n { + return false; + } + } + } + if let Some(x) = s.chars().nth(i) { + if x == '.' + && (i + 1 == n + || if let Some(m) = s.chars().nth(i + 1) { + m == 'e' || m == 'E' + } else { + false + }) + { + return false; + } + } + + let mut dot = 0; + let mut e = 0; + let mut j = i; + + while j < n { + if let Some(c) = s.chars().nth(j) { + if c == '.' { + if e > 0 || dot > 0 { + return false; + } + dot += 1; + } else if c == 'e' || c == 'E' { + if e > 0 || j == i || j == n - 1 { + return false; + } + e += 1; + if let Some(x) = s.chars().nth(j + 1) { + if x == '+' || x == '-' { + j += 1; + if j == n - 1 { + return false; + } + } + } + } else if !c.is_ascii_digit() { + return false; + } + } + j += 1; + } + + true + } +} +``` + ### **...** ``` diff --git a/solution/0000-0099/0065.Valid Number/README_EN.md b/solution/0000-0099/0065.Valid Number/README_EN.md index b95129c241a19..d1ede25f31a44 100644 --- a/solution/0000-0099/0065.Valid Number/README_EN.md +++ b/solution/0000-0099/0065.Valid Number/README_EN.md @@ -248,6 +248,68 @@ public class Solution { } ``` +### **Rust** + +```rust +impl Solution { + pub fn is_number(s: String) -> bool { + let mut i = 0; + let n = s.len(); + + if let Some(c) = s.chars().nth(i) { + if c == '+' || c == '-' { + i += 1; + if i == n { + return false; + } + } + } + if let Some(x) = s.chars().nth(i) { + if + x == '.' && + (i + 1 == n || + (if let Some(m) = s.chars().nth(i + 1) { m == 'e' || m == 'E' } else { false })) + { + return false; + } + } + + let mut dot = 0; + let mut e = 0; + let mut j = i; + + while j < n { + if let Some(c) = s.chars().nth(j) { + if c == '.' { + if e > 0 || dot > 0 { + return false; + } + dot += 1; + } else if c == 'e' || c == 'E' { + if e > 0 || j == i || j == n - 1 { + return false; + } + e += 1; + if let Some(x) = s.chars().nth(j + 1) { + if x == '+' || x == '-' { + j += 1; + if j == n - 1 { + return false; + } + } + } + } else if !c.is_ascii_digit() { + return false; + } + } + j += 1; + } + + true + } +} +``` + ### **...** ``` diff --git a/solution/0000-0099/0065.Valid Number/Solution.rs b/solution/0000-0099/0065.Valid Number/Solution.rs new file mode 100644 index 0000000000000..f4dc3fbc62698 --- /dev/null +++ b/solution/0000-0099/0065.Valid Number/Solution.rs @@ -0,0 +1,57 @@ +impl Solution { + pub fn is_number(s: String) -> bool { + let mut i = 0; + let n = s.len(); + + if let Some(c) = s.chars().nth(i) { + if c == '+' || c == '-' { + i += 1; + if i == n { + return false; + } + } + } + if let Some(x) = s.chars().nth(i) { + if + x == '.' && + (i + 1 == n || + (if let Some(m) = s.chars().nth(i + 1) { m == 'e' || m == 'E' } else { false })) + { + return false; + } + } + + let mut dot = 0; + let mut e = 0; + let mut j = i; + + while j < n { + if let Some(c) = s.chars().nth(j) { + if c == '.' { + if e > 0 || dot > 0 { + return false; + } + dot += 1; + } else if c == 'e' || c == 'E' { + if e > 0 || j == i || j == n - 1 { + return false; + } + e += 1; + if let Some(x) = s.chars().nth(j + 1) { + if x == '+' || x == '-' { + j += 1; + if j == n - 1 { + return false; + } + } + } + } else if !c.is_ascii_digit() { + return false; + } + } + j += 1; + } + + true + } +} From 7453d331a888095f8550295e78319bedd8fe9831 Mon Sep 17 00:00:00 2001 From: Libin YANG Date: Sun, 17 Dec 2023 16:57:13 +0800 Subject: [PATCH 8/8] feat: add solutions to lc problem: No.0090 (#2115) No.0090.Subsets II --- .../0000-0099/0038.Count and Say/Solution.rs | 43 ++- .../0000-0099/0065.Valid Number/README.md | 11 +- solution/0000-0099/0090.Subsets II/README.md | 322 ++++++++++++++---- .../0000-0099/0090.Subsets II/README_EN.md | 322 ++++++++++++++---- .../0000-0099/0090.Subsets II/Solution.cpp | 43 +-- .../0000-0099/0090.Subsets II/Solution.go | 30 +- .../0000-0099/0090.Subsets II/Solution.java | 46 +-- .../0000-0099/0090.Subsets II/Solution.py | 32 +- .../0000-0099/0090.Subsets II/Solution.rs | 38 ++- .../0000-0099/0090.Subsets II/Solution.ts | 31 +- 10 files changed, 653 insertions(+), 265 deletions(-) diff --git a/solution/0000-0099/0038.Count and Say/Solution.rs b/solution/0000-0099/0038.Count and Say/Solution.rs index e6a11b4d3ffaf..771fb88260526 100644 --- a/solution/0000-0099/0038.Count and Say/Solution.rs +++ b/solution/0000-0099/0038.Count and Say/Solution.rs @@ -1,22 +1,21 @@ -use std::iter::once; - -impl Solution { - pub fn count_and_say(n: i32) -> String { - (1..n) - .fold(vec![1], |curr, _| { - let mut next = vec![]; - let mut slow = 0; - for fast in 0..=curr.len() { - if fast == curr.len() || curr[slow] != curr[fast] { - next.extend(once((fast - slow) as u8).chain(once(curr[slow]))); - slow = fast; - } - } - next - }) - .into_iter() - .map(|digit| (digit + b'0') as char) - .collect() - } -} - +use std::iter::once; + +impl Solution { + pub fn count_and_say(n: i32) -> String { + (1..n) + .fold(vec![1], |curr, _| { + let mut next = vec![]; + let mut slow = 0; + for fast in 0..=curr.len() { + if fast == curr.len() || curr[slow] != curr[fast] { + next.extend(once((fast - slow) as u8).chain(once(curr[slow]))); + slow = fast; + } + } + next + }) + .into_iter() + .map(|digit| (digit + b'0') as char) + .collect() + } +} diff --git a/solution/0000-0099/0065.Valid Number/README.md b/solution/0000-0099/0065.Valid Number/README.md index a702e9d577960..1b0b9a108516e 100644 --- a/solution/0000-0099/0065.Valid Number/README.md +++ b/solution/0000-0099/0065.Valid Number/README.md @@ -277,13 +277,10 @@ impl Solution { } } if let Some(x) = s.chars().nth(i) { - if x == '.' - && (i + 1 == n - || if let Some(m) = s.chars().nth(i + 1) { - m == 'e' || m == 'E' - } else { - false - }) + if + x == '.' && + (i + 1 == n || + (if let Some(m) = s.chars().nth(i + 1) { m == 'e' || m == 'E' } else { false })) { return false; } diff --git a/solution/0000-0099/0090.Subsets II/README.md b/solution/0000-0099/0090.Subsets II/README.md index 632d684de96ea..abc5ddc3de256 100644 --- a/solution/0000-0099/0090.Subsets II/README.md +++ b/solution/0000-0099/0090.Subsets II/README.md @@ -43,6 +43,30 @@ +**方法一:排序 + DFS** + +我们可以先对数组 $nums$ 进行排序,方便去重。 + +然后,我们设计一个函数 $dfs(i)$,表示当前从第 $i$ 个元素开始搜索子集。函数 $dfs(i)$ 的执行逻辑如下: + +如果 $i \geq n$,说明已经搜索完所有元素,将当前子集加入答案数组中,递归结束。 + +如果 $i < n$,将第 $i$ 个元素加入子集,执行 $dfs(i + 1)$,然后将第 $i$ 个元素从子集中移除。接下来,我们判断第 $i$ 个元素是否和下一个元素相同,如果相同,则循环跳过该元素,直到找到第一个和第 $i$ 个元素不同的元素,执行 $dfs(i + 1)$。 + +最后,我们只需要调用 $dfs(0)$,返回答案数组即可。 + +时间复杂度 $O(n \times 2^n)$,空间复杂度 $O(n)$。其中 $n$ 是数组的长度。 + +**方法二:排序 + 二进制枚举** + +与方法一类似,我们先对数组 $nums$ 进行排序,方便去重。 + +接下来,我们在 $[0, 2^n)$ 的范围内枚举一个二进制数 $mask$,其中 $mask$ 的二进制表示是一个 $n$ 位的位串,如果 $mask$ 的第 $i$ 位为 $1$,表示选择 $nums[i]$,为 $0$ 表示不选择 $nums[i]$。注意,如果 $mask$ 的 $i - 1$ 位为 $0$,且 $nums[i] = nums[i - 1]$,则说明在当前枚举到的方案中,第 $i$ 个元素和第 $i - 1$ 个元素相同,为了避免重复,我们跳过这种情况。否则,我们将 $mask$ 对应的子集加入答案数组中。 + +枚举结束后,我们返回答案数组即可。 + +时间复杂度 $O(n \times 2^n)$,空间复杂度 $O(n)$。其中 $n$ 是数组的长度。 + ### **Python3** @@ -52,18 +76,41 @@ ```python class Solution: def subsetsWithDup(self, nums: List[int]) -> List[List[int]]: - def dfs(u, t): - ans.append(t[:]) - for i in range(u, len(nums)): - if i != u and nums[i] == nums[i - 1]: - continue - t.append(nums[i]) - dfs(i + 1, t) - t.pop() + def dfs(i: int): + if i == len(nums): + ans.append(t[:]) + return + t.append(nums[i]) + dfs(i + 1) + x = t.pop() + while i + 1 < len(nums) and nums[i + 1] == x: + i += 1 + dfs(i + 1) + nums.sort() ans = [] + t = [] + dfs(0) + return ans +``` + +```python +class Solution: + def subsetsWithDup(self, nums: List[int]) -> List[List[int]]: nums.sort() - dfs(0, []) + n = len(nums) + ans = [] + for mask in range(1 << n): + ok = True + t = [] + for i in range(n): + if mask >> i & 1: + if i and (mask >> (i - 1) & 1) == 0 and nums[i] == nums[i - 1]: + ok = False + break + t.append(nums[i]) + if ok: + ans.append(t) return ans ``` @@ -73,27 +120,56 @@ class Solution: ```java class Solution { - private List> ans; + private List> ans = new ArrayList<>(); + private List t = new ArrayList<>(); private int[] nums; public List> subsetsWithDup(int[] nums) { - ans = new ArrayList<>(); Arrays.sort(nums); this.nums = nums; - dfs(0, new ArrayList<>()); + dfs(0); return ans; } - private void dfs(int u, List t) { - ans.add(new ArrayList<>(t)); - for (int i = u; i < nums.length; ++i) { - if (i != u && nums[i] == nums[i - 1]) { - continue; + private void dfs(int i) { + if (i >= nums.length) { + ans.add(new ArrayList<>(t)); + return; + } + t.add(nums[i]); + dfs(i + 1); + int x = t.remove(t.size() - 1); + while (i + 1 < nums.length && nums[i + 1] == x) { + ++i; + } + dfs(i + 1); + } +} +``` + +```java +class Solution { + public List> subsetsWithDup(int[] nums) { + Arrays.sort(nums); + int n = nums.length; + List> ans = new ArrayList<>(); + for (int mask = 0; mask < 1 << n; ++mask) { + List t = new ArrayList<>(); + boolean ok = true; + for (int i = 0; i < n; ++i) { + if ((mask >> i & 1) == 1) { + if (i > 0 && (mask >> (i - 1) & 1) == 0 && nums[i] == nums[i - 1]) { + ok = false; + break; + } + t.add(nums[i]); + } + } + if (ok) { + ans.add(t); } - t.add(nums[i]); - dfs(i + 1, t); - t.remove(t.size() - 1); } + return ans; } } ``` @@ -107,18 +183,50 @@ public: sort(nums.begin(), nums.end()); vector> ans; vector t; - dfs(0, t, nums, ans); + int n = nums.size(); + function dfs = [&](int i) { + if (i >= n) { + ans.push_back(t); + return; + } + t.push_back(nums[i]); + dfs(i + 1); + t.pop_back(); + while (i + 1 < n && nums[i + 1] == nums[i]) { + ++i; + } + dfs(i + 1); + }; + dfs(0); return ans; } +}; +``` - void dfs(int u, vector& t, vector& nums, vector>& ans) { - ans.push_back(t); - for (int i = u; i < nums.size(); ++i) { - if (i != u && nums[i] == nums[i - 1]) continue; - t.push_back(nums[i]); - dfs(i + 1, t, nums, ans); - t.pop_back(); +```cpp +class Solution { +public: + vector> subsetsWithDup(vector& nums) { + sort(nums.begin(), nums.end()); + int n = nums.size(); + vector> ans; + for (int mask = 0; mask < 1 << n; ++mask) { + vector t; + bool ok = true; + for (int i = 0; i < n; ++i) { + if ((mask >> i & 1) == 1) { + if (i > 0 && (mask >> (i - 1) & 1) == 0 && nums[i] == nums[i - 1]) { + ok = false; + break; + } + t.push_back(nums[i]); + } + } + if (ok) { + ans.push_back(t); + } } + return ans; } }; ``` @@ -126,24 +234,50 @@ public: ### **Go** ```go -func subsetsWithDup(nums []int) [][]int { +func subsetsWithDup(nums []int) (ans [][]int) { sort.Ints(nums) - var ans [][]int - var dfs func(u int, t []int) - dfs = func(u int, t []int) { - ans = append(ans, append([]int(nil), t...)) - for i := u; i < len(nums); i++ { - if i != u && nums[i] == nums[i-1] { - continue + n := len(nums) + t := []int{} + var dfs func(int) + dfs = func(i int) { + if i >= n { + ans = append(ans, slices.Clone(t)) + return + } + t = append(t, nums[i]) + dfs(i + 1) + t = t[:len(t)-1] + for i+1 < n && nums[i+1] == nums[i] { + i++ + } + dfs(i + 1) + } + dfs(0) + return +} +``` + +```go +func subsetsWithDup(nums []int) (ans [][]int) { + sort.Ints(nums) + n := len(nums) + for mask := 0; mask < 1<>i&1 == 1 { + if i > 0 && mask>>(i-1)&1 == 0 && nums[i] == nums[i-1] { + ok = false + break + } + t = append(t, nums[i]) } - t = append(t, nums[i]) - dfs(i+1, t) - t = t[:len(t)-1] + } + if ok { + ans = append(ans, t) } } - var t []int - dfs(0, t) - return ans + return } ``` @@ -154,22 +288,47 @@ function subsetsWithDup(nums: number[]): number[][] { nums.sort((a, b) => a - b); const n = nums.length; const t: number[] = []; - const res: number[][] = []; - const dfs = (i: number) => { - if (i === n) { - res.push([...t]); + const ans: number[][] = []; + const dfs = (i: number): void => { + if (i >= n) { + ans.push([...t]); return; } t.push(nums[i]); dfs(i + 1); - const num = t.pop(); - while (i < n && nums[i] == num) { + t.pop(); + while (i + 1 < n && nums[i] === nums[i + 1]) { i++; } - dfs(i); + dfs(i + 1); }; dfs(0); - return res; + return ans; +} +``` + +```ts +function subsetsWithDup(nums: number[]): number[][] { + nums.sort((a, b) => a - b); + const n = nums.length; + const ans: number[][] = []; + for (let mask = 0; mask < 1 << n; ++mask) { + const t: number[] = []; + let ok: boolean = true; + for (let i = 0; i < n; ++i) { + if (((mask >> i) & 1) === 1) { + if (i && ((mask >> (i - 1)) & 1) === 0 && nums[i] === nums[i - 1]) { + ok = false; + break; + } + t.push(nums[i]); + } + } + if (ok) { + ans.push(t); + } + } + return ans; } ``` @@ -177,26 +336,57 @@ function subsetsWithDup(nums: number[]): number[][] { ```rust impl Solution { - fn dfs(mut i: usize, t: &mut Vec, res: &mut Vec>, nums: &Vec) { - let n = nums.len(); - if i == n { - res.push(t.clone()); - return; - } - t.push(nums[i]); - Self::dfs(i + 1, t, res, nums); - let num = t.pop().unwrap(); - while i < n && num == nums[i] { - i += 1; + pub fn subsets_with_dup(nums: Vec) -> Vec> { + let mut nums = nums; + nums.sort(); + let mut ans = Vec::new(); + let mut t = Vec::new(); + + fn dfs(i: usize, nums: &Vec, t: &mut Vec, ans: &mut Vec>) { + if i >= nums.len() { + ans.push(t.clone()); + return; + } + t.push(nums[i]); + dfs(i + 1, nums, t, ans); + t.pop(); + let mut i = i; + while i + 1 < nums.len() && nums[i + 1] == nums[i] { + i += 1; + } + dfs(i + 1, nums, t, ans); } - Self::dfs(i, t, res, nums); + + dfs(0, &nums, &mut t, &mut ans); + ans } +} +``` - pub fn subsets_with_dup(mut nums: Vec) -> Vec> { +```rust +impl Solution { + pub fn subsets_with_dup(nums: Vec) -> Vec> { + let mut nums = nums; nums.sort(); - let mut res = Vec::new(); - Self::dfs(0, &mut Vec::new(), &mut res, &nums); - res + let n = nums.len(); + let mut ans = Vec::new(); + for mask in 0..1 << n { + let mut t = Vec::new(); + let mut ok = true; + for i in 0..n { + if ((mask >> i) & 1) == 1 { + if i > 0 && ((mask >> (i - 1)) & 1) == 0 && nums[i] == nums[i - 1] { + ok = false; + break; + } + t.push(nums[i]); + } + } + if ok { + ans.push(t); + } + } + ans } } ``` diff --git a/solution/0000-0099/0090.Subsets II/README_EN.md b/solution/0000-0099/0090.Subsets II/README_EN.md index dfd653c7b3114..fcf2dbcd52cc9 100644 --- a/solution/0000-0099/0090.Subsets II/README_EN.md +++ b/solution/0000-0099/0090.Subsets II/README_EN.md @@ -26,6 +26,30 @@ ## Solutions +**Solution 1: Sorting + DFS** + +We can first sort the array $nums$ to facilitate deduplication. + +Then, we design a function $dfs(i)$, which represents searching for subsets starting from the $i$-th element. The execution logic of the function $dfs(i)$ is as follows: + +If $i \geq n$, it means that all elements have been searched, and the current subset is added to the answer array, and the recursion ends. + +If $i < n$, add the $i$-th element to the subset, execute $dfs(i + 1)$, and then remove the $i$-th element from the subset. Next, we judge whether the $i$-th element is the same as the next element. If it is the same, we loop to skip this element until we find the first element that is different from the $i$-th element, and execute $dfs(i + 1)$. + +Finally, we only need to call $dfs(0)$ and return the answer array. + +The time complexity is $O(n \times 2^n)$, and the space complexity is $O(n)$. Here, $n$ is the length of the array. + +**Solution 2: Sorting + Binary Enumeration** + +Similar to Solution 1, we first sort the array $nums$ to facilitate deduplication. + +Next, we enumerate a binary number $mask$ in the range of $[0, 2^n)$, where the binary representation of $mask$ is an $n$-bit bit string. If the $i$-th bit of $mask$ is $1$, it means to select $nums[i]$, and $0$ means not to select $nums[i]$. Note that if the $i - 1$ bit of $mask$ is $0$, and $nums[i] = nums[i - 1]$, it means that in the current enumerated scheme, the $i$-th element and the $i - 1$-th element are the same. To avoid repetition, we skip this situation. Otherwise, we add the subset corresponding to $mask$ to the answer array. + +After the enumeration ends, we return the answer array. + +The time complexity is $O(n \times 2^n)$, and the space complexity is $O(n)$. Here, $n$ is the length of the array. + ### **Python3** @@ -33,18 +57,41 @@ ```python class Solution: def subsetsWithDup(self, nums: List[int]) -> List[List[int]]: - def dfs(u, t): - ans.append(t[:]) - for i in range(u, len(nums)): - if i != u and nums[i] == nums[i - 1]: - continue - t.append(nums[i]) - dfs(i + 1, t) - t.pop() + def dfs(i: int): + if i == len(nums): + ans.append(t[:]) + return + t.append(nums[i]) + dfs(i + 1) + x = t.pop() + while i + 1 < len(nums) and nums[i + 1] == x: + i += 1 + dfs(i + 1) + nums.sort() ans = [] + t = [] + dfs(0) + return ans +``` + +```python +class Solution: + def subsetsWithDup(self, nums: List[int]) -> List[List[int]]: nums.sort() - dfs(0, []) + n = len(nums) + ans = [] + for mask in range(1 << n): + ok = True + t = [] + for i in range(n): + if mask >> i & 1: + if i and (mask >> (i - 1) & 1) == 0 and nums[i] == nums[i - 1]: + ok = False + break + t.append(nums[i]) + if ok: + ans.append(t) return ans ``` @@ -52,27 +99,56 @@ class Solution: ```java class Solution { - private List> ans; + private List> ans = new ArrayList<>(); + private List t = new ArrayList<>(); private int[] nums; public List> subsetsWithDup(int[] nums) { - ans = new ArrayList<>(); Arrays.sort(nums); this.nums = nums; - dfs(0, new ArrayList<>()); + dfs(0); return ans; } - private void dfs(int u, List t) { - ans.add(new ArrayList<>(t)); - for (int i = u; i < nums.length; ++i) { - if (i != u && nums[i] == nums[i - 1]) { - continue; + private void dfs(int i) { + if (i >= nums.length) { + ans.add(new ArrayList<>(t)); + return; + } + t.add(nums[i]); + dfs(i + 1); + int x = t.remove(t.size() - 1); + while (i + 1 < nums.length && nums[i + 1] == x) { + ++i; + } + dfs(i + 1); + } +} +``` + +```java +class Solution { + public List> subsetsWithDup(int[] nums) { + Arrays.sort(nums); + int n = nums.length; + List> ans = new ArrayList<>(); + for (int mask = 0; mask < 1 << n; ++mask) { + List t = new ArrayList<>(); + boolean ok = true; + for (int i = 0; i < n; ++i) { + if ((mask >> i & 1) == 1) { + if (i > 0 && (mask >> (i - 1) & 1) == 0 && nums[i] == nums[i - 1]) { + ok = false; + break; + } + t.add(nums[i]); + } + } + if (ok) { + ans.add(t); } - t.add(nums[i]); - dfs(i + 1, t); - t.remove(t.size() - 1); } + return ans; } } ``` @@ -86,18 +162,50 @@ public: sort(nums.begin(), nums.end()); vector> ans; vector t; - dfs(0, t, nums, ans); + int n = nums.size(); + function dfs = [&](int i) { + if (i >= n) { + ans.push_back(t); + return; + } + t.push_back(nums[i]); + dfs(i + 1); + t.pop_back(); + while (i + 1 < n && nums[i + 1] == nums[i]) { + ++i; + } + dfs(i + 1); + }; + dfs(0); return ans; } +}; +``` - void dfs(int u, vector& t, vector& nums, vector>& ans) { - ans.push_back(t); - for (int i = u; i < nums.size(); ++i) { - if (i != u && nums[i] == nums[i - 1]) continue; - t.push_back(nums[i]); - dfs(i + 1, t, nums, ans); - t.pop_back(); +```cpp +class Solution { +public: + vector> subsetsWithDup(vector& nums) { + sort(nums.begin(), nums.end()); + int n = nums.size(); + vector> ans; + for (int mask = 0; mask < 1 << n; ++mask) { + vector t; + bool ok = true; + for (int i = 0; i < n; ++i) { + if ((mask >> i & 1) == 1) { + if (i > 0 && (mask >> (i - 1) & 1) == 0 && nums[i] == nums[i - 1]) { + ok = false; + break; + } + t.push_back(nums[i]); + } + } + if (ok) { + ans.push_back(t); + } } + return ans; } }; ``` @@ -105,24 +213,50 @@ public: ### **Go** ```go -func subsetsWithDup(nums []int) [][]int { +func subsetsWithDup(nums []int) (ans [][]int) { sort.Ints(nums) - var ans [][]int - var dfs func(u int, t []int) - dfs = func(u int, t []int) { - ans = append(ans, append([]int(nil), t...)) - for i := u; i < len(nums); i++ { - if i != u && nums[i] == nums[i-1] { - continue + n := len(nums) + t := []int{} + var dfs func(int) + dfs = func(i int) { + if i >= n { + ans = append(ans, slices.Clone(t)) + return + } + t = append(t, nums[i]) + dfs(i + 1) + t = t[:len(t)-1] + for i+1 < n && nums[i+1] == nums[i] { + i++ + } + dfs(i + 1) + } + dfs(0) + return +} +``` + +```go +func subsetsWithDup(nums []int) (ans [][]int) { + sort.Ints(nums) + n := len(nums) + for mask := 0; mask < 1<>i&1 == 1 { + if i > 0 && mask>>(i-1)&1 == 0 && nums[i] == nums[i-1] { + ok = false + break + } + t = append(t, nums[i]) } - t = append(t, nums[i]) - dfs(i+1, t) - t = t[:len(t)-1] + } + if ok { + ans = append(ans, t) } } - var t []int - dfs(0, t) - return ans + return } ``` @@ -133,22 +267,47 @@ function subsetsWithDup(nums: number[]): number[][] { nums.sort((a, b) => a - b); const n = nums.length; const t: number[] = []; - const res: number[][] = []; - const dfs = (i: number) => { - if (i === n) { - res.push([...t]); + const ans: number[][] = []; + const dfs = (i: number): void => { + if (i >= n) { + ans.push([...t]); return; } t.push(nums[i]); dfs(i + 1); - const num = t.pop(); - while (i < n && nums[i] == num) { + t.pop(); + while (i + 1 < n && nums[i] === nums[i + 1]) { i++; } - dfs(i); + dfs(i + 1); }; dfs(0); - return res; + return ans; +} +``` + +```ts +function subsetsWithDup(nums: number[]): number[][] { + nums.sort((a, b) => a - b); + const n = nums.length; + const ans: number[][] = []; + for (let mask = 0; mask < 1 << n; ++mask) { + const t: number[] = []; + let ok: boolean = true; + for (let i = 0; i < n; ++i) { + if (((mask >> i) & 1) === 1) { + if (i && ((mask >> (i - 1)) & 1) === 0 && nums[i] === nums[i - 1]) { + ok = false; + break; + } + t.push(nums[i]); + } + } + if (ok) { + ans.push(t); + } + } + return ans; } ``` @@ -156,26 +315,57 @@ function subsetsWithDup(nums: number[]): number[][] { ```rust impl Solution { - fn dfs(mut i: usize, t: &mut Vec, res: &mut Vec>, nums: &Vec) { - let n = nums.len(); - if i == n { - res.push(t.clone()); - return; - } - t.push(nums[i]); - Self::dfs(i + 1, t, res, nums); - let num = t.pop().unwrap(); - while i < n && num == nums[i] { - i += 1; + pub fn subsets_with_dup(nums: Vec) -> Vec> { + let mut nums = nums; + nums.sort(); + let mut ans = Vec::new(); + let mut t = Vec::new(); + + fn dfs(i: usize, nums: &Vec, t: &mut Vec, ans: &mut Vec>) { + if i >= nums.len() { + ans.push(t.clone()); + return; + } + t.push(nums[i]); + dfs(i + 1, nums, t, ans); + t.pop(); + let mut i = i; + while i + 1 < nums.len() && nums[i + 1] == nums[i] { + i += 1; + } + dfs(i + 1, nums, t, ans); } - Self::dfs(i, t, res, nums); + + dfs(0, &nums, &mut t, &mut ans); + ans } +} +``` - pub fn subsets_with_dup(mut nums: Vec) -> Vec> { +```rust +impl Solution { + pub fn subsets_with_dup(nums: Vec) -> Vec> { + let mut nums = nums; nums.sort(); - let mut res = Vec::new(); - Self::dfs(0, &mut Vec::new(), &mut res, &nums); - res + let n = nums.len(); + let mut ans = Vec::new(); + for mask in 0..1 << n { + let mut t = Vec::new(); + let mut ok = true; + for i in 0..n { + if ((mask >> i) & 1) == 1 { + if i > 0 && ((mask >> (i - 1)) & 1) == 0 && nums[i] == nums[i - 1] { + ok = false; + break; + } + t.push(nums[i]); + } + } + if ok { + ans.push(t); + } + } + ans } } ``` diff --git a/solution/0000-0099/0090.Subsets II/Solution.cpp b/solution/0000-0099/0090.Subsets II/Solution.cpp index 0e6912965a5ff..58c1ad52fb29a 100644 --- a/solution/0000-0099/0090.Subsets II/Solution.cpp +++ b/solution/0000-0099/0090.Subsets II/Solution.cpp @@ -1,20 +1,25 @@ -class Solution { -public: - vector> subsetsWithDup(vector& nums) { - sort(nums.begin(), nums.end()); - vector> ans; - vector t; - dfs(0, t, nums, ans); - return ans; - } - - void dfs(int u, vector& t, vector& nums, vector>& ans) { - ans.push_back(t); - for (int i = u; i < nums.size(); ++i) { - if (i != u && nums[i] == nums[i - 1]) continue; - t.push_back(nums[i]); - dfs(i + 1, t, nums, ans); - t.pop_back(); - } - } +class Solution { +public: + vector> subsetsWithDup(vector& nums) { + sort(nums.begin(), nums.end()); + int n = nums.size(); + vector> ans; + for (int mask = 0; mask < 1 << n; ++mask) { + vector t; + bool ok = true; + for (int i = 0; i < n; ++i) { + if ((mask >> i & 1) == 1) { + if (i > 0 && (mask >> (i - 1) & 1) == 0 && nums[i] == nums[i - 1]) { + ok = false; + break; + } + t.push_back(nums[i]); + } + } + if (ok) { + ans.push_back(t); + } + } + return ans; + } }; \ No newline at end of file diff --git a/solution/0000-0099/0090.Subsets II/Solution.go b/solution/0000-0099/0090.Subsets II/Solution.go index 003cdcd8b87ca..cec1dc4a9d090 100644 --- a/solution/0000-0099/0090.Subsets II/Solution.go +++ b/solution/0000-0099/0090.Subsets II/Solution.go @@ -1,19 +1,21 @@ -func subsetsWithDup(nums []int) [][]int { +func subsetsWithDup(nums []int) (ans [][]int) { sort.Ints(nums) - var ans [][]int - var dfs func(u int, t []int) - dfs = func(u int, t []int) { - ans = append(ans, append([]int(nil), t...)) - for i := u; i < len(nums); i++ { - if i != u && nums[i] == nums[i-1] { - continue + n := len(nums) + for mask := 0; mask < 1<>i&1 == 1 { + if i > 0 && mask>>(i-1)&1 == 0 && nums[i] == nums[i-1] { + ok = false + break + } + t = append(t, nums[i]) } - t = append(t, nums[i]) - dfs(i+1, t) - t = t[:len(t)-1] + } + if ok { + ans = append(ans, t) } } - var t []int - dfs(0, t) - return ans + return } \ No newline at end of file diff --git a/solution/0000-0099/0090.Subsets II/Solution.java b/solution/0000-0099/0090.Subsets II/Solution.java index 3dabfa9029db1..53c9c7d4c7194 100644 --- a/solution/0000-0099/0090.Subsets II/Solution.java +++ b/solution/0000-0099/0090.Subsets II/Solution.java @@ -1,24 +1,24 @@ -class Solution { - private List> ans; - private int[] nums; - - public List> subsetsWithDup(int[] nums) { - ans = new ArrayList<>(); - Arrays.sort(nums); - this.nums = nums; - dfs(0, new ArrayList<>()); - return ans; - } - - private void dfs(int u, List t) { - ans.add(new ArrayList<>(t)); - for (int i = u; i < nums.length; ++i) { - if (i != u && nums[i] == nums[i - 1]) { - continue; - } - t.add(nums[i]); - dfs(i + 1, t); - t.remove(t.size() - 1); - } - } +class Solution { + public List> subsetsWithDup(int[] nums) { + Arrays.sort(nums); + int n = nums.length; + List> ans = new ArrayList<>(); + for (int mask = 0; mask < 1 << n; ++mask) { + List t = new ArrayList<>(); + boolean ok = true; + for (int i = 0; i < n; ++i) { + if ((mask >> i & 1) == 1) { + if (i > 0 && (mask >> (i - 1) & 1) == 0 && nums[i] == nums[i - 1]) { + ok = false; + break; + } + t.add(nums[i]); + } + } + if (ok) { + ans.add(t); + } + } + return ans; + } } \ No newline at end of file diff --git a/solution/0000-0099/0090.Subsets II/Solution.py b/solution/0000-0099/0090.Subsets II/Solution.py index d15f8a7584fd4..c0aa8d12289f2 100644 --- a/solution/0000-0099/0090.Subsets II/Solution.py +++ b/solution/0000-0099/0090.Subsets II/Solution.py @@ -1,15 +1,17 @@ -class Solution: - def subsetsWithDup(self, nums: List[int]) -> List[List[int]]: - def dfs(u, t): - ans.append(t[:]) - for i in range(u, len(nums)): - if i != u and nums[i] == nums[i - 1]: - continue - t.append(nums[i]) - dfs(i + 1, t) - t.pop() - - ans = [] - nums.sort() - dfs(0, []) - return ans +class Solution: + def subsetsWithDup(self, nums: List[int]) -> List[List[int]]: + nums.sort() + n = len(nums) + ans = [] + for mask in range(1 << n): + ok = True + t = [] + for i in range(n): + if mask >> i & 1: + if i and (mask >> (i - 1) & 1) == 0 and nums[i] == nums[i - 1]: + ok = False + break + t.append(nums[i]) + if ok: + ans.append(t) + return ans diff --git a/solution/0000-0099/0090.Subsets II/Solution.rs b/solution/0000-0099/0090.Subsets II/Solution.rs index 7f3534e995464..6f272559d3d46 100644 --- a/solution/0000-0099/0090.Subsets II/Solution.rs +++ b/solution/0000-0099/0090.Subsets II/Solution.rs @@ -1,23 +1,25 @@ impl Solution { - fn dfs(mut i: usize, t: &mut Vec, res: &mut Vec>, nums: &Vec) { + pub fn subsets_with_dup(nums: Vec) -> Vec> { + let mut nums = nums; + nums.sort(); let n = nums.len(); - if i == n { - res.push(t.clone()); - return; - } - t.push(nums[i]); - Self::dfs(i + 1, t, res, nums); - let num = t.pop().unwrap(); - while i < n && num == nums[i] { - i += 1; + let mut ans = Vec::new(); + for mask in 0..1 << n { + let mut t = Vec::new(); + let mut ok = true; + for i in 0..n { + if ((mask >> i) & 1) == 1 { + if i > 0 && ((mask >> (i - 1)) & 1) == 0 && nums[i] == nums[i - 1] { + ok = false; + break; + } + t.push(nums[i]); + } + } + if ok { + ans.push(t); + } } - Self::dfs(i, t, res, nums); - } - - pub fn subsets_with_dup(mut nums: Vec) -> Vec> { - nums.sort(); - let mut res = Vec::new(); - Self::dfs(0, &mut Vec::new(), &mut res, &nums); - res + ans } } diff --git a/solution/0000-0099/0090.Subsets II/Solution.ts b/solution/0000-0099/0090.Subsets II/Solution.ts index 640eb0f062c2c..9ac9ba3681a87 100644 --- a/solution/0000-0099/0090.Subsets II/Solution.ts +++ b/solution/0000-0099/0090.Subsets II/Solution.ts @@ -1,21 +1,22 @@ function subsetsWithDup(nums: number[]): number[][] { nums.sort((a, b) => a - b); const n = nums.length; - const t: number[] = []; - const res: number[][] = []; - const dfs = (i: number) => { - if (i === n) { - res.push([...t]); - return; + const ans: number[][] = []; + for (let mask = 0; mask < 1 << n; ++mask) { + const t: number[] = []; + let ok: boolean = true; + for (let i = 0; i < n; ++i) { + if (((mask >> i) & 1) === 1) { + if (i && ((mask >> (i - 1)) & 1) === 0 && nums[i] === nums[i - 1]) { + ok = false; + break; + } + t.push(nums[i]); + } } - t.push(nums[i]); - dfs(i + 1); - const num = t.pop(); - while (i < n && nums[i] == num) { - i++; + if (ok) { + ans.push(t); } - dfs(i); - }; - dfs(0); - return res; + } + return ans; }