持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第15天,点击查看活动详情
最多能完成排序的块
给定一个长度为 n 的整数数组 arr ,它表示在 [0, n - 1] 范围内的整数的排列。
我们将 arr 分割成若干 块 (即分区),并对每个块单独排序。将它们连接起来后,使得连接的结果和按升序排序后的原数组相同。
返回数组能分成的最多块数量。
n == arr.length1 <= n <= 100 <= arr[i] < narr中每个元素都 不同
思路
对于本题
最后对每一个可以分割的为计数一下即可,时间复杂度
代码
use std::cmp::{max, min};
impl Solution {
pub fn max_chunks_to_sorted(arr: Vec<i32>) -> i32 {
let mut cur = -1;
let mut ans = 0;
for (i, &x) in arr.iter().enumerate() {
cur = max(cur, x);
if cur <= i as i32 {
ans += 1;
}
}
ans
}
}
本题拓展
和“最多能完成排序的块”相似,但给定数组中的元素可以重复,输入数组最大长度为,其中的元素最大为
思路
与上题不同的是,本题的要求中,数字元素可以重复,且元素范围并不在[0, n-1]中,这个就给我们带来了麻烦!
意味着我们并不能像简化版那样去做
真的吗?
总体时间复杂度
有没有更快的方式呢?
我想把这个 优化掉
排序是不可能优化了,但是瓶颈也在排序此处!
我们换一种思路:
这种做法的时间复杂度为
代码
use std::cmp::{max, min};
impl Solution {
pub fn max_chunks_to_sorted_help(arr: Vec<i32>) -> i32 {
let mut cur = -1;
let mut ans = 0;
for (i, &x) in arr.iter().enumerate() {
cur = max(cur, x);
if cur <= i as i32 {
ans += 1;
}
}
ans
}
pub fn max_chunks_to_sorted(arr: Vec<i32>) -> i32 {
let mut q: Vec<(i32, usize)> = Vec::new();
let mut arr = arr;
for (i, &x) in arr.iter().enumerate() {
q.push((x, i));
}
q.sort();
for (i, &x) in q.iter().enumerate() {
arr[x.1] = i as i32;
}
return Self::max_chunks_to_sorted_help(arr);
}
}
利用栈
use std::collections::{VecDeque};
impl Solution {
pub fn max_chunks_to_sorted(arr: Vec<i32>) -> i32 {
let mut st = VecDeque::new();
for v in arr {
if st.len() == 0 || Some(&v) >= st.back() {
st.push_back(v);
} else {
let now = st.pop_back().unwrap();
while let Some(&t) = st.back() {
match t > v {
true => {
st.pop_back();
}
false => break,
}
}
st.push_back(now);
}
}
return st.len() as i32;
}
}