Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 463b37c

Browse files
authored
feat: add rust solution to lc problem: No.0907 (doocs#1128)
1 parent 2ae1906 commit 463b37c

File tree

3 files changed

+192
-0
lines changed

3 files changed

+192
-0
lines changed

‎solution/0900-0999/0907.Sum of Subarray Minimums/README.md‎

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -183,6 +183,57 @@ public:
183183
};
184184
```
185185
186+
### **Rust**
187+
188+
```rust
189+
const MOD: i64 = 1e9 as i64 + 7;
190+
191+
impl Solution {
192+
pub fn sum_subarray_mins(arr: Vec<i32>) -> i32 {
193+
let n: usize = arr.len();
194+
let mut ret: i64 = 0;
195+
let mut left: Vec<i32> = vec![-1; n];
196+
let mut right: Vec<i32> = vec![n as i32; n];
197+
// Index stack, store the index of the value in the given array
198+
let mut stack: Vec<i32> = Vec::new();
199+
200+
// Find the first element that's less than the current value for the left side
201+
// The default value of which is -1
202+
for i in 0..n {
203+
while !stack.is_empty() && arr[*stack.last().unwrap() as usize] >= arr[i] {
204+
stack.pop();
205+
}
206+
if !stack.is_empty() {
207+
left[i] = *stack.last().unwrap();
208+
}
209+
stack.push(i as i32);
210+
}
211+
212+
stack.clear();
213+
214+
// Find the first element that's less or equal than the current value for the right side
215+
// The default value of which is n
216+
for i in (0..n).rev() {
217+
while !stack.is_empty() && arr[*stack.last().unwrap() as usize] > arr[i] {
218+
stack.pop();
219+
}
220+
if !stack.is_empty() {
221+
right[i] = *stack.last().unwrap();
222+
}
223+
stack.push(i as i32);
224+
}
225+
226+
// Traverse the array, to find the sum
227+
for i in 0..n {
228+
ret += ((right[i] - i as i32) * (i as i32 - left[i])) as i64 * arr[i] as i64 % MOD;
229+
ret %= MOD;
230+
}
231+
232+
(ret % MOD as i64) as i32
233+
}
234+
}
235+
```
236+
186237
### **Go**
187238

188239
```go

‎solution/0900-0999/0907.Sum of Subarray Minimums/README_EN.md‎

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,50 @@ Sum is 17.
3535

3636
## Solutions
3737

38+
The problem asks for the sum of the minimum values of each subarray, which is actually equivalent to finding the number of subarrays for each element $arr[i]$ where $arr[i]$ is the minimum, multiplying each by $arr[i],ドル and then summing these products.
39+
40+
Thus, the focus of the problem is translated to finding the number of subarrays for which $arr[i]$ is the minimum.
41+
42+
For each $arr[i],ドル we identify the first position $left[i]$ to its left that is smaller than $arr[i]$ and the first position $right[i]$ to its right that is less than or equal to $arr[i]$.
43+
44+
The number of subarrays where $arr[i]$ is the minimum can then be given by $(i - left[i]) \times (right[i] - i)$.
45+
46+
It's important to note why we are looking for the first position $right[i]$ that is less than or equal to $arr[i]$ and not less than $arr[i]$.
47+
48+
If we were to look for the first position less than $arr[i],ドル we would end up double-counting.
49+
50+
For instance, consider the following array:
51+
52+
The element at index 3ドル$ is 2ドル,ドル and the first element less than 2ドル$ to its left is at index 0ドル$. If we find the first element less than 2ドル$ to its right, we would end up at index 7ドル$. That means the subarray interval is $(0, 7)$. Note that this is an open interval.
53+
54+
```
55+
0 4 3 2 5 3 2 1
56+
* ^ *
57+
```
58+
59+
If we calculate the subarray interval for the element at index 6ドル$ using the same method, we would find that its interval is also $(0, 7)$.
60+
61+
```
62+
0 4 3 2 5 3 2 1
63+
* ^ *
64+
```
65+
66+
Therefore, the subarray intervals of the elements at index 3ドル$ and 6ドル$ are overlapping, leading to double-counting.
67+
68+
If we were to find the first element less than or equal to $arr[i]$ to its right, we wouldn't have this problem.
69+
70+
The subarray interval for the element at index 3ドル$ would become $(0, 6)$ and for the element at index 6ドル$ it would be $(0, 7),ドル and these two are not overlapping.
71+
72+
To solve this problem, we just need to traverse the array.
73+
74+
For each element $arr[i],ドル we use a monotonic stack to find its $left[i]$ and $right[i]$.
75+
76+
Then the number of subarrays where $arr[i]$ is the minimum can be calculated by $(i - left[i]) \times (right[i] - i)$. Multiply this by $arr[i]$ and sum these values for all $i$ to get the final answer.
77+
78+
Remember to take care of data overflow and modulus operation.
79+
80+
The time complexity is $O(n),ドル where $n$ represents the length of the array $arr$.
81+
3882
<!-- tabs:start -->
3983

4084
### **Python3**
@@ -139,6 +183,57 @@ public:
139183
};
140184
```
141185
186+
### **Rust**
187+
188+
```rust
189+
const MOD: i64 = 1e9 as i64 + 7;
190+
191+
impl Solution {
192+
pub fn sum_subarray_mins(arr: Vec<i32>) -> i32 {
193+
let n: usize = arr.len();
194+
let mut ret: i64 = 0;
195+
let mut left: Vec<i32> = vec![-1; n];
196+
let mut right: Vec<i32> = vec![n as i32; n];
197+
// Index stack, store the index of the value in the given array
198+
let mut stack: Vec<i32> = Vec::new();
199+
200+
// Find the first element that's less than the current value for the left side
201+
// The default value of which is -1
202+
for i in 0..n {
203+
while !stack.is_empty() && arr[*stack.last().unwrap() as usize] >= arr[i] {
204+
stack.pop();
205+
}
206+
if !stack.is_empty() {
207+
left[i] = *stack.last().unwrap();
208+
}
209+
stack.push(i as i32);
210+
}
211+
212+
stack.clear();
213+
214+
// Find the first element that's less or equal than the current value for the right side
215+
// The default value of which is n
216+
for i in (0..n).rev() {
217+
while !stack.is_empty() && arr[*stack.last().unwrap() as usize] > arr[i] {
218+
stack.pop();
219+
}
220+
if !stack.is_empty() {
221+
right[i] = *stack.last().unwrap();
222+
}
223+
stack.push(i as i32);
224+
}
225+
226+
// Traverse the array, to find the sum
227+
for i in 0..n {
228+
ret += ((right[i] - i as i32) * (i as i32 - left[i])) as i64 * arr[i] as i64 % MOD;
229+
ret %= MOD;
230+
}
231+
232+
(ret % MOD as i64) as i32
233+
}
234+
}
235+
```
236+
142237
### **Go**
143238

144239
```go
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
const MOD: i64 = 1e9 as i64 + 7;
2+
3+
impl Solution {
4+
pub fn sum_subarray_mins(arr: Vec<i32>) -> i32 {
5+
let n: usize = arr.len();
6+
let mut ret: i64 = 0;
7+
let mut left: Vec<i32> = vec![-1; n];
8+
let mut right: Vec<i32> = vec![n as i32; n];
9+
// Index stack, store the index of the value in the given array
10+
let mut stack: Vec<i32> = Vec::new();
11+
12+
// Find the first element that's less than the current value for the left side
13+
// The default value of which is -1
14+
for i in 0..n {
15+
while !stack.is_empty() && arr[*stack.last().unwrap() as usize] >= arr[i] {
16+
stack.pop();
17+
}
18+
if !stack.is_empty() {
19+
left[i] = *stack.last().unwrap();
20+
}
21+
stack.push(i as i32);
22+
}
23+
24+
stack.clear();
25+
26+
// Find the first element that's less or equal than the current value for the right side
27+
// The default value of which is n
28+
for i in (0..n).rev() {
29+
while !stack.is_empty() && arr[*stack.last().unwrap() as usize] > arr[i] {
30+
stack.pop();
31+
}
32+
if !stack.is_empty() {
33+
right[i] = *stack.last().unwrap();
34+
}
35+
stack.push(i as i32);
36+
}
37+
38+
// Traverse the array, to find the sum
39+
for i in 0..n {
40+
ret += ((right[i] - i as i32) * (i as i32 - left[i])) as i64 * arr[i] as i64 % MOD;
41+
ret %= MOD;
42+
}
43+
44+
(ret % MOD as i64) as i32
45+
}
46+
}

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /