Skip to content

Commit d822759

Browse files
authored
feat: add rust solution to lc problem: No.1354 (doocs#4864)
1 parent f073c05 commit d822759

File tree

3 files changed

+86
-7
lines changed

3 files changed

+86
-7
lines changed

solution/1300-1399/1354.Construct Target Array With Multiple Sums/README.md

Lines changed: 31 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -73,11 +73,11 @@ tags:
7373

7474
### 方法一:逆向构造 + 优先队列(大根堆)
7575

76-
我们发现,如果从数组 $arr$ 开始正向构造目标数组 $target$,每次都不好确定选择哪个下标 $i$,问题比较复杂。而如果我们从数组 $target$ 开始逆向构造,每次构造都一定是选择当前数组中最大的元素,这样就可以保证每次构造都是唯一的,问题比较简单。
76+
我们发现,如果从数组 $\textit{arr}$ 开始正向构造目标数组 $\textit{target}$,每次都不好确定选择哪个下标 $i$,问题比较复杂。而如果我们从数组 $\textit{target}$ 开始逆向构造,每次构造都一定是选择当前数组中最大的元素,这样就可以保证每次构造都是唯一的,问题比较简单。
7777

78-
因此,我们可以使用优先队列(大根堆)来存储数组 $target$ 中的元素,用一个变量 $s$ 记录数组 $target$ 中所有元素的和。每次从优先队列中取出最大的元素 $mx$,计算当前数组中除 $mx$ 以外的所有元素之和 $t$,如果 $t \lt 1$ 或者 $mx - t \lt 1$,则说明无法构造目标数组 $target$,返回 `false`。否则,我们计算 $mx \bmod t$,如果 $mx \bmod t = 0$,则令 $x = t$,否则令 $x = mx \bmod t$,将 $x$ 加入优先队列中,并更新 $s$ 的值,重复上述操作,直到优先队列中的所有元素都变为 $1$,此时返回 `true`
78+
因此,我们可以使用优先队列(大根堆)来存储数组 $\textit{target}$ 中的元素,用一个变量 $s$ 记录数组 $\textit{target}$ 中所有元素的和。每次从优先队列中取出最大的元素 $mx$,计算当前数组中除 $mx$ 以外的所有元素之和 $t$,如果 $t \lt 1$ 或者 $mx - t \lt 1$,则说明无法构造目标数组 $\textit{target}$,返回 `false`。否则,我们计算 $mx \bmod t$,如果 $mx \bmod t = 0$,则令 $x = t$,否则令 $x = mx \bmod t$,将 $x$ 加入优先队列中,并更新 $s$ 的值,重复上述操作,直到优先队列中的所有元素都变为 $1$,此时返回 `true`
7979

80-
时间复杂度 $O(n \log n)$,空间复杂度 $O(n)$。其中 $n$ 为数组 $target$ 的长度。
80+
时间复杂度 $O(n \log n)$,空间复杂度 $O(n)$。其中 $n$ 为数组 $\textit{target}$ 的长度。
8181

8282
<!-- tabs:start -->
8383

@@ -218,6 +218,34 @@ function isPossible(target: number[]): boolean {
218218
}
219219
```
220220

221+
#### Rust
222+
223+
```rust
224+
use std::collections::BinaryHeap;
225+
226+
impl Solution {
227+
pub fn is_possible(target: Vec<i32>) -> bool {
228+
let mut pq = BinaryHeap::from(target.clone());
229+
let mut s: i64 = target.iter().map(|&x| x as i64).sum();
230+
231+
while let Some(&mx) = pq.peek() {
232+
if mx == 1 {
233+
break;
234+
}
235+
let mx = pq.pop().unwrap() as i64;
236+
let t = s - mx;
237+
if t < 1 || mx - t < 1 {
238+
return false;
239+
}
240+
let x = if mx % t == 0 { t } else { mx % t };
241+
pq.push(x as i32);
242+
s = s - mx + x;
243+
}
244+
true
245+
}
246+
}
247+
```
248+
221249
<!-- tabs:end -->
222250

223251
<!-- solution:end -->

solution/1300-1399/1354.Construct Target Array With Multiple Sums/README_EN.md

Lines changed: 32 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ tags:
3535
<pre>
3636
<strong>Input:</strong> target = [9,3,5]
3737
<strong>Output:</strong> true
38-
<strong>Explanation:</strong> Start with arr = [1, 1, 1]
38+
<strong>Explanation:</strong> Start with arr = [1, 1, 1]
3939
[1, 1, 1], sum = 3 choose index 1
4040
[1, 3, 1], sum = 5 choose index 2
4141
[1, 3, 5], sum = 9 choose index 0
@@ -74,11 +74,11 @@ tags:
7474

7575
### Solution 1: Reverse Construction + Priority Queue (Max Heap)
7676

77-
We find that if we start from the array $arr$ and construct the target array $target$ forward, it is not easy to determine which index $i$ to choose each time, and the problem is relatively complex. However, if we start from the array $target$ and construct it in reverse, each construction must choose the largest element in the current array, which can ensure that each construction is unique, and the problem is relatively simple.
77+
We observe that if we start constructing the target array $\textit{target}$ from the array $\textit{arr}$ in a forward manner, it is difficult to determine which index $i$ to choose each time, making the problem quite complex. However, if we construct in reverse starting from the array $\textit{target}$, each construction step must select the largest element in the current array, which ensures that each construction is unique, making the problem relatively simple.
7878

79-
Therefore, we can use a priority queue (max heap) to store the elements in the array $target$, and use a variable $s$ to record the sum of all elements in the array $target$. Each time we take out the largest element $mx$ from the priority queue, calculate the sum $t$ of all elements in the current array except $mx$. If $t < 1$ or $mx - t < 1$, it means that the target array $target$ cannot be constructed, and we return `false`. Otherwise, we calculate $mx \bmod t$. If $mx \bmod t = 0$, let $x = t$, otherwise let $x = mx \bmod t$, add $x$ to the priority queue, and update the value of $s$, repeat the above operations until all elements in the priority queue become $1$, then return `true`.
79+
Therefore, we can use a priority queue (max heap) to store the elements of array $\textit{target}$, and use a variable $s$ to record the sum of all elements in array $\textit{target}$. Each time we extract the maximum element $mx$ from the priority queue and calculate the sum $t$ of all elements in the current array except $mx$. If $t \lt 1$ or $mx - t \lt 1$, it means the target array $\textit{target}$ cannot be constructed, and we return `false`. Otherwise, we calculate $mx \bmod t$. If $mx \bmod t = 0$, we set $x = t$; otherwise, we set $x = mx \bmod t$. We add $x$ to the priority queue and update the value of $s$. We repeat this process until all elements in the priority queue become $1$, at which point we return `true`.
8080

81-
The time complexity is $O(n \log n)$, and the space complexity is $O(n)$. Where $n$ is the length of the array $target$.
81+
The time complexity is $O(n \log n)$ and the space complexity is $O(n)$, where $n$ is the length of array $\textit{target}$.
8282

8383
<!-- tabs:start -->
8484

@@ -219,6 +219,34 @@ function isPossible(target: number[]): boolean {
219219
}
220220
```
221221

222+
#### Rust
223+
224+
```rust
225+
use std::collections::BinaryHeap;
226+
227+
impl Solution {
228+
pub fn is_possible(target: Vec<i32>) -> bool {
229+
let mut pq = BinaryHeap::from(target.clone());
230+
let mut s: i64 = target.iter().map(|&x| x as i64).sum();
231+
232+
while let Some(&mx) = pq.peek() {
233+
if mx == 1 {
234+
break;
235+
}
236+
let mx = pq.pop().unwrap() as i64;
237+
let t = s - mx;
238+
if t < 1 || mx - t < 1 {
239+
return false;
240+
}
241+
let x = if mx % t == 0 { t } else { mx % t };
242+
pq.push(x as i32);
243+
s = s - mx + x;
244+
}
245+
true
246+
}
247+
}
248+
```
249+
222250
<!-- tabs:end -->
223251

224252
<!-- solution:end -->
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
use std::collections::BinaryHeap;
2+
3+
impl Solution {
4+
pub fn is_possible(target: Vec<i32>) -> bool {
5+
let mut pq = BinaryHeap::from(target.clone());
6+
let mut s: i64 = target.iter().map(|&x| x as i64).sum();
7+
8+
while let Some(&mx) = pq.peek() {
9+
if mx == 1 {
10+
break;
11+
}
12+
let mx = pq.pop().unwrap() as i64;
13+
let t = s - mx;
14+
if t < 1 || mx - t < 1 {
15+
return false;
16+
}
17+
let x = if mx % t == 0 { t } else { mx % t };
18+
pq.push(x as i32);
19+
s = s - mx + x;
20+
}
21+
true
22+
}
23+
}

0 commit comments

Comments
 (0)