diff --git a/solution/1900-1999/1959.Minimum Total Space Wasted With K Resizing Operations/README.md b/solution/1900-1999/1959.Minimum Total Space Wasted With K Resizing Operations/README.md index 11ce72783a078..c95c86c83c086 100644 --- a/solution/1900-1999/1959.Minimum Total Space Wasted With K Resizing Operations/README.md +++ b/solution/1900-1999/1959.Minimum Total Space Wasted With K Resizing Operations/README.md @@ -74,6 +74,25 @@ tags: ### 方法一:动态规划 +题目等价于我们将数组 $\textit{nums}$ 分成 $k + 1$ 段,那么每一段的浪费空间为该段的最大值乘以该段的长度减去该段的元素之和。我们累加每一段的浪费空间,即可得到总浪费空间。我们将 $k$ 加 $1$,那么就相当于将数组分成 $k$ 段。 + +因此,我们定义数组 $\textit{g}[i][j]$ 表示 $\textit{nums}[i..j]$ 的最大值乘以 $\textit{nums}[i..j]$ 的长度减去 $\textit{nums}[i..j]$ 的元素之和。我们在 $[0, n)$ 的范围内枚举 $i$,在 $[i, n)$ 的范围内枚举 $j$,用一个变量 $s$ 维护 $\textit{nums}[i..j]$ 的元素之和,用一个变量 $\textit{mx}$ 维护 $\textit{nums}[i..j]$ 的最大值,那么我们可以得到: + +$$ +\textit{g}[i][j] = \textit{mx} \times (j - i + 1) - s +$$ + +接下来,我们定义 $\textit{f}[i][j]$ 表示前 $i$ 个元素分成 $j$ 段的最小浪费空间。我们初始化 $\textit{f}[0][0] = 0$,其余位置初始化为无穷大。我们在 $[1, n]$ 的范围内枚举 $i$,在 $[1, k]$ 的范围内枚举 $j$,然后我们枚举前 $j - 1$ 段的最后一个元素 $h$,那么有: + +$$ +\textit{f}[i][j] = \min(\textit{f}[i][j], \ +\textit{f}[h][j - 1] + \textit{g}[h][i - 1]) +$$ + +最终答案为 $\textit{f}[n][k]$。 + +时间复杂度 $O(n^2 \times k)$,空间复杂度 $O(n \times (n + k))$。其中 $n$ 为数组 $\textit{nums}$ 的长度。 + #### Python3 @@ -203,6 +222,75 @@ func minSpaceWastedKResizing(nums []int, k int) int { } ``` +#### TypeScript + +```ts +function minSpaceWastedKResizing(nums: number[], k: number): number { + k += 1; + const n = nums.length; + const g: number[][] = Array.from({ length: n }, () => Array(n).fill(0)); + + for (let i = 0; i < n; i++) { + let s = 0, + mx = 0; + for (let j = i; j < n; j++) { + s += nums[j]; + mx = Math.max(mx, nums[j]); + g[i][j] = mx * (j - i + 1) - s; + } + } + + const inf = Number.POSITIVE_INFINITY; + const f: number[][] = Array.from({ length: n + 1 }, () => Array(k + 1).fill(inf)); + f[0][0] = 0; + + for (let i = 1; i <= n; i++) { + for (let j = 1; j <= k; j++) { + for (let h = 0; h < i; h++) { + f[i][j] = Math.min(f[i][j], f[h][j - 1] + g[h][i - 1]); + } + } + } + + return f[n][k]; +} +``` + +#### Rust + +```rust +impl Solution { + pub fn min_space_wasted_k_resizing(nums: Vec, k: i32) -> i32 { + let mut k = k + 1; + let n = nums.len(); + let mut g = vec![vec![0; n]; n]; + + for i in 0..n { + let (mut s, mut mx) = (0, 0); + for j in i..n { + s += nums[j]; + mx = mx.max(nums[j]); + g[i][j] = mx * (j as i32 - i as i32 + 1) - s; + } + } + + let inf = 0x3f3f3f3f; + let mut f = vec![vec![inf; (k + 1) as usize]; n + 1]; + f[0][0] = 0; + + for i in 1..=n { + for j in 1..=k as usize { + for h in 0..i { + f[i][j] = f[i][j].min(f[h][j - 1] + g[h][i - 1]); + } + } + } + + f[n][k as usize] + } +} +``` + diff --git a/solution/1900-1999/1959.Minimum Total Space Wasted With K Resizing Operations/README_EN.md b/solution/1900-1999/1959.Minimum Total Space Wasted With K Resizing Operations/README_EN.md index 90fc97567380f..eb664610b9299 100644 --- a/solution/1900-1999/1959.Minimum Total Space Wasted With K Resizing Operations/README_EN.md +++ b/solution/1900-1999/1959.Minimum Total Space Wasted With K Resizing Operations/README_EN.md @@ -44,7 +44,7 @@ The total wasted space is (20 - 10) + (20 - 20) = 10. Input: nums = [10,20,30], k = 1 Output: 10 Explanation: size = [20,20,30]. -We can set the initial size to be 20 and resize to 30 at time 2. +We can set the initial size to be 20 and resize to 30 at time 2. The total wasted space is (20 - 10) + (20 - 20) + (30 - 30) = 10. @@ -73,7 +73,20 @@ The total wasted space is (10 - 10) + (20 - 20) + (20 - 15) + (30 - 30) + (30 - -### Solution 1 +Solution 1: Dynamic Programming +The problem is equivalent to dividing the array $\textit{nums}$ into $k + 1$ segments. The wasted space for each segment is the maximum value of that segment multiplied by the length of the segment minus the sum of the elements in that segment. By summing the wasted space of each segment, we get the total wasted space. By adding 1 to $k$, we are effectively dividing the array into $k$ segments. + +Therefore, we define an array $\textit{g}[i][j]$ to represent the wasted space for the segment $\textit{nums}[i..j]$, which is the maximum value of $\textit{nums}[i..j]$ multiplied by the length of $\textit{nums}[i..j]$ minus the sum of the elements in $\textit{nums}[i..j]$. We iterate over $i$ in the range $[0, n)$ and $j$ in the range $[i, n)$, using a variable $s$ to maintain the sum of the elements in $\textit{nums}[i..j]$ and a variable $\textit{mx}$ to maintain the maximum value of $\textit{nums}[i..j]$. Then we can get: + +$$ \textit{g}[i][j] = \textit{mx} \times (j - i + 1) - s $$ + +Next, we define $\textit{f}[i][j]$ to represent the minimum wasted space for dividing the first $i$ elements into $j$ segments. We initialize $\textit{f}[0][0] = 0$ and the other positions to infinity. We iterate over $i$ in the range $[1, n]$ and $j$ in the range $[1, k]$, then we iterate over the last element $h$ of the previous $j - 1$ segments. Then we have: + +$$ \textit{f}[i][j] = \min(\textit{f}[i][j], \textit{f}[h][j - 1] + \textit{g}[h][i - 1]) $$ + +The final answer is $\textit{f}[n][k]$. + +The time complexity is $O(n^2 \times k)$, and the space complexity is $O(n \times (n + k))$. Where $n$ is the length of the array $\textit{nums}$. @@ -204,6 +217,75 @@ func minSpaceWastedKResizing(nums []int, k int) int { } ``` +#### TypeScript + +```ts +function minSpaceWastedKResizing(nums: number[], k: number): number { + k += 1; + const n = nums.length; + const g: number[][] = Array.from({ length: n }, () => Array(n).fill(0)); + + for (let i = 0; i < n; i++) { + let s = 0, + mx = 0; + for (let j = i; j < n; j++) { + s += nums[j]; + mx = Math.max(mx, nums[j]); + g[i][j] = mx * (j - i + 1) - s; + } + } + + const inf = Number.POSITIVE_INFINITY; + const f: number[][] = Array.from({ length: n + 1 }, () => Array(k + 1).fill(inf)); + f[0][0] = 0; + + for (let i = 1; i <= n; i++) { + for (let j = 1; j <= k; j++) { + for (let h = 0; h < i; h++) { + f[i][j] = Math.min(f[i][j], f[h][j - 1] + g[h][i - 1]); + } + } + } + + return f[n][k]; +} +``` + +#### Rust + +```rust +impl Solution { + pub fn min_space_wasted_k_resizing(nums: Vec, k: i32) -> i32 { + let mut k = k + 1; + let n = nums.len(); + let mut g = vec![vec![0; n]; n]; + + for i in 0..n { + let (mut s, mut mx) = (0, 0); + for j in i..n { + s += nums[j]; + mx = mx.max(nums[j]); + g[i][j] = mx * (j as i32 - i as i32 + 1) - s; + } + } + + let inf = 0x3f3f3f3f; + let mut f = vec![vec![inf; (k + 1) as usize]; n + 1]; + f[0][0] = 0; + + for i in 1..=n { + for j in 1..=k as usize { + for h in 0..i { + f[i][j] = f[i][j].min(f[h][j - 1] + g[h][i - 1]); + } + } + } + + f[n][k as usize] + } +} +``` + diff --git a/solution/1900-1999/1959.Minimum Total Space Wasted With K Resizing Operations/Solution.rs b/solution/1900-1999/1959.Minimum Total Space Wasted With K Resizing Operations/Solution.rs new file mode 100644 index 0000000000000..b6d7f132938be --- /dev/null +++ b/solution/1900-1999/1959.Minimum Total Space Wasted With K Resizing Operations/Solution.rs @@ -0,0 +1,30 @@ +impl Solution { + pub fn min_space_wasted_k_resizing(nums: Vec, k: i32) -> i32 { + let mut k = k + 1; + let n = nums.len(); + let mut g = vec![vec![0; n]; n]; + + for i in 0..n { + let (mut s, mut mx) = (0, 0); + for j in i..n { + s += nums[j]; + mx = mx.max(nums[j]); + g[i][j] = mx * (j as i32 - i as i32 + 1) - s; + } + } + + let inf = 0x3f3f3f3f; + let mut f = vec![vec![inf; (k + 1) as usize]; n + 1]; + f[0][0] = 0; + + for i in 1..=n { + for j in 1..=k as usize { + for h in 0..i { + f[i][j] = f[i][j].min(f[h][j - 1] + g[h][i - 1]); + } + } + } + + f[n][k as usize] + } +} diff --git a/solution/1900-1999/1959.Minimum Total Space Wasted With K Resizing Operations/Solution.ts b/solution/1900-1999/1959.Minimum Total Space Wasted With K Resizing Operations/Solution.ts new file mode 100644 index 0000000000000..68a578a0e67d9 --- /dev/null +++ b/solution/1900-1999/1959.Minimum Total Space Wasted With K Resizing Operations/Solution.ts @@ -0,0 +1,29 @@ +function minSpaceWastedKResizing(nums: number[], k: number): number { + k += 1; + const n = nums.length; + const g: number[][] = Array.from({ length: n }, () => Array(n).fill(0)); + + for (let i = 0; i < n; i++) { + let s = 0, + mx = 0; + for (let j = i; j < n; j++) { + s += nums[j]; + mx = Math.max(mx, nums[j]); + g[i][j] = mx * (j - i + 1) - s; + } + } + + const inf = Number.POSITIVE_INFINITY; + const f: number[][] = Array.from({ length: n + 1 }, () => Array(k + 1).fill(inf)); + f[0][0] = 0; + + for (let i = 1; i <= n; i++) { + for (let j = 1; j <= k; j++) { + for (let h = 0; h < i; h++) { + f[i][j] = Math.min(f[i][j], f[h][j - 1] + g[h][i - 1]); + } + } + } + + return f[n][k]; +}