Skip to content

Commit d5b6b9f

Browse files
committed
feat: add solutions to lc problem: No.3748
1 parent 19569f0 commit d5b6b9f

File tree

7 files changed

+562
-8
lines changed

7 files changed

+562
-8
lines changed

solution/3700-3799/3748.Count Stable Subarrays/README.md

Lines changed: 192 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -109,32 +109,220 @@ edit_url: https://github.com/doocs/leetcode/edit/main/solution/3700-3799/3748.Co
109109

110110
<!-- solution:start -->
111111

112-
### 方法一
112+
### 方法一: 分段计数
113+
114+
根据题目描述,稳定子数组的定义是不存在逆序对的子数组,即子数组中的元素是非降序排列的。因此,我们可以将数组划分为若干个非降序的段,用一个数组 $\text{seg}$ 来记录每个段的起始位置。同时,我们还需要一个前缀和数组 $\text{text{s}}$ 来记录每个段内稳定子数组的数量。
115+
116+
然后,对于每个查询 $[l, r]$,可能存在 $3$ 种情况:
117+
118+
1. 查询区间 $[l, r]$ 完全包含在某个段内,此时稳定子数组的数量可以直接通过公式计算得到,数量为 $\frac{(k + 1) \cdot k}{2}$,其中 $k = r - l + 1$。
119+
2. 查询区间 $[l, r]$ 跨越了多个段,此时我们需要分别计算左侧不完整段、右侧不完整段和中间完整段的稳定子数组数量,然后将它们相加得到最终结果。
120+
121+
时间复杂度为 $O((n + q) \log n)$,其中 $n$ 是数组的长度,$q$ 是查询的数量。空间复杂度为 $O(n)$。
113122

114123
<!-- tabs:start -->
115124

116125
#### Python3
117126

118127
```python
119-
128+
class Solution:
129+
def countStableSubarrays(
130+
self, nums: List[int], queries: List[List[int]]
131+
) -> List[int]:
132+
s = [0]
133+
l, n = 0, len(nums)
134+
seg = []
135+
for r, x in enumerate(nums):
136+
if r == n - 1 or x > nums[r + 1]:
137+
seg.append(l)
138+
k = r - l + 1
139+
s.append(s[-1] + (1 + k) * k // 2)
140+
l = r + 1
141+
ans = []
142+
for l, r in queries:
143+
i = bisect_right(seg, l)
144+
j = bisect_right(seg, r) - 1
145+
if i > j:
146+
k = r - l + 1
147+
ans.append((1 + k) * k // 2)
148+
else:
149+
a = seg[i] - l
150+
b = r - seg[j] + 1
151+
ans.append((1 + a) * a // 2 + s[j] - s[i] + (1 + b) * b // 2)
152+
return ans
120153
```
121154

122155
#### Java
123156

124157
```java
125-
158+
class Solution {
159+
public long[] countStableSubarrays(int[] nums, int[][] queries) {
160+
List<Integer> seg = new ArrayList<>();
161+
List<Long> s = new ArrayList<>();
162+
s.add(0L);
163+
164+
int l = 0;
165+
int n = nums.length;
166+
for (int r = 0; r < n; r++) {
167+
if (r == n - 1 || nums[r] > nums[r + 1]) {
168+
seg.add(l);
169+
int k = r - l + 1;
170+
s.add(s.getLast() + (long) k * (k + 1) / 2);
171+
l = r + 1;
172+
}
173+
}
174+
175+
long[] ans = new long[queries.length];
176+
for (int q = 0; q < queries.length; q++) {
177+
int left = queries[q][0];
178+
int right = queries[q][1];
179+
180+
int i = upperBound(seg, left);
181+
int j = upperBound(seg, right) - 1;
182+
183+
if (i > j) {
184+
int k = right - left + 1;
185+
ans[q] = (long) k * (k + 1) / 2;
186+
} else {
187+
int a = seg.get(i) - left;
188+
int b = right - seg.get(j) + 1;
189+
ans[q] = (long) a * (a + 1) / 2 + s.get(j) - s.get(i) + (long) b * (b + 1) / 2;
190+
}
191+
}
192+
return ans;
193+
}
194+
195+
private int upperBound(List<Integer> list, int target) {
196+
int l = 0, r = list.size();
197+
while (l < r) {
198+
int mid = (l + r) >> 1;
199+
if (list.get(mid) > target) {
200+
r = mid;
201+
} else {
202+
l = mid + 1;
203+
}
204+
}
205+
return l;
206+
}
207+
}
126208
```
127209

128210
#### C++
129211

130212
```cpp
131-
213+
class Solution {
214+
public:
215+
vector<long long> countStableSubarrays(vector<int>& nums, vector<vector<int>>& queries) {
216+
int n = nums.size();
217+
vector<int> seg;
218+
vector<long long> s = {0};
219+
220+
int l = 0;
221+
for (int r = 0; r < n; ++r) {
222+
if (r == n - 1 || nums[r] > nums[r + 1]) {
223+
seg.push_back(l);
224+
long long k = r - l + 1;
225+
s.push_back(s.back() + k * (k + 1) / 2);
226+
l = r + 1;
227+
}
228+
}
229+
230+
vector<long long> ans;
231+
for (auto& q : queries) {
232+
int left = q[0], right = q[1];
233+
234+
int i = upper_bound(seg.begin(), seg.end(), left) - seg.begin();
235+
int j = upper_bound(seg.begin(), seg.end(), right) - seg.begin() - 1;
236+
237+
if (i > j) {
238+
long long k = right - left + 1;
239+
ans.push_back(k * (k + 1) / 2);
240+
} else {
241+
long long a = seg[i] - left;
242+
long long b = right - seg[j] + 1;
243+
ans.push_back(a * (a + 1) / 2 + s[j] - s[i] + b * (b + 1) / 2);
244+
}
245+
}
246+
247+
return ans;
248+
}
249+
};
132250
```
133251

134252
#### Go
135253

136254
```go
255+
func countStableSubarrays(nums []int, queries [][]int) []int64 {
256+
n := len(nums)
257+
seg := []int{}
258+
s := []int64{0}
259+
260+
l := 0
261+
for r := 0; r < n; r++ {
262+
if r == n-1 || nums[r] > nums[r+1] {
263+
seg = append(seg, l)
264+
k := int64(r - l + 1)
265+
s = append(s, s[len(s)-1]+k*(k+1)/2)
266+
l = r + 1
267+
}
268+
}
269+
270+
ans := make([]int64, len(queries))
271+
for idx, q := range queries {
272+
left, right := q[0], q[1]
273+
274+
i := sort.SearchInts(seg, left+1)
275+
j := sort.SearchInts(seg, right+1) - 1
276+
277+
if i > j {
278+
k := int64(right - left + 1)
279+
ans[idx] = k * (k + 1) / 2
280+
} else {
281+
a := int64(seg[i] - left)
282+
b := int64(right - seg[j] + 1)
283+
ans[idx] = a*(a+1)/2 + s[j] - s[i] + b*(b+1)/2
284+
}
285+
}
286+
287+
return ans
288+
}
289+
```
137290

291+
#### TypeScript
292+
293+
```ts
294+
function countStableSubarrays(nums: number[], queries: number[][]): number[] {
295+
const n = nums.length;
296+
const seg: number[] = [];
297+
const s: number[] = [0];
298+
299+
let l = 0;
300+
for (let r = 0; r < n; r++) {
301+
if (r === n - 1 || nums[r] > nums[r + 1]) {
302+
seg.push(l);
303+
const k = r - l + 1;
304+
s.push(s[s.length - 1] + (k * (k + 1)) / 2);
305+
l = r + 1;
306+
}
307+
}
308+
309+
const ans: number[] = [];
310+
for (const [left, right] of queries) {
311+
const i = _.sortedIndex(seg, left + 1);
312+
const j = _.sortedIndex(seg, right + 1) - 1;
313+
314+
if (i > j) {
315+
const k = right - left + 1;
316+
ans.push((k * (k + 1)) / 2);
317+
} else {
318+
const a = seg[i] - left;
319+
const b = right - seg[j] + 1;
320+
ans.push((a * (a + 1)) / 2 + s[j] - s[i] + (b * (b + 1)) / 2);
321+
}
322+
}
323+
324+
return ans;
325+
}
138326
```
139327

140328
<!-- tabs:end -->

0 commit comments

Comments
 (0)