5.0 KiB
2488. 统计中位数为 K 的子数组
description:
给你一个长度为 n
的数组 nums
,该数组由从 1
到 n
的 不同 整数组成。另给你一个正整数 k
。统计并返回 nums
中的 中位数 等于 k
的非空子数组的数目。
代码:
use std::collections::HashMap;
use std::cmp::Ordering;
fn main() {
let nums = vec![3, 2, 1, 4, 5];
let k = 4;
let nums = vec![2, 3, 1];
let k = 3;
let res = count_subarrays2(&nums, k);
println!(" {} ", res);
}
fn count_subarrays2(nums: &[i32], k:i32)->i32{
// 在 nums 数组中查找元素 k 的位置,使用了 iter() 方法和 position() 方法。
// |&x| 表示闭包接收一个参数,使用 x 来引用这个参数,而 & 表示参数是通过引用传递而不是值传递。| 符号用于表示闭包的开始和结束。
let mut k_index = nums.iter().position(|&x| x== k).unwrap();
let (mut ans, mut sum) = (0, 0);
let mut counts = HashMap::new();
counts.insert(0, 1);
// 使用&num是为了避免拷贝数据。(i32数据)不涉及所有权。。
for (i, &num) in nums.iter().enumerate(){
sum += sign2(num - k);
if i < k_index{
*counts.entry(sum).or_insert(0) += 1;
}else {
let prev_0 = *counts.get(&sum).unwrap_or(&0);
let prev_1 = *counts.get(&(sum-1)).unwrap_or(&0);
ans += prev_0 + prev_1;
}
}
for (i, num) in nums.iter().enumerate(){
println!("i is {} ; num is {}", i, num)
}
ans
}
fn sign2(num:i32)->i32{
match num.cmp(&0) {
Ordering::Equal => 0,
Ordering::Greater => 1,
Ordering::Less => -1,
}
}
fn count_subarrays(nums: &[i32], k:i32)->i32{
let n = nums.len();
let mut k_index:i32 = -1;
for i in 0..n {
if nums[i] == k{
k_index = i as i32;
break;
}
}
// println!(" index is {} ", k_index as usize);
let (mut ans, mut sum) = (0, 0);
let mut counts = HashMap::new();
counts.insert(0, 1);
for i in 0..n {
sum += sign(nums[i] - k);
if i < k_index as usize{
let count = counts.entry(sum).or_insert(0);
*count += 1;
}else {
let prev0 = *counts.get(&sum).unwrap_or(&0);
let prev1 = *counts.get(&(sum-1)).unwrap_or(&0);
ans += prev0 + prev1;
}
}
ans
}
fn sign(num:i32)->i32{
if num == 0{
0
}else {
if num > 0 { 1 } else { -1 }
}
}
// 在 Rust 中,数组的下标访问操作符 [] 已经被实现为语言特性,对于数组和切片类型,可以直接使用下标操作符访问其元素。''
// 在 Rust 中,数组或向量的元素可以通过索引访问,无论是使用 [] 运算符还是 get() 方法。
// 当使用 [] 运算符时,Rust 会自动解引用数组或向量的引用,并将其作为指向第一个元素的指针来处理。
// 因此,无论是 for road in &roads 还是 for road in roads,在使用 road[0] 访问数组或向量的第一个元素时,都将自动解引用指向该元素的指针,返回一个 i32 类型的值。
// 这是 Rust 语言的自动解引用功能的一部分,它使得代码更加简洁和易读。
for (i, &num) in nums.iter().enumerate() 使用&num的好处:
使用&num
是为了避免拷贝数据。当使用迭代是的,这里只涉及空间占用。使用&num
比num
更好,因为在这里我们只是需要引用num
的值,而不需要所有权。
使用引用可以减少副本的创建和内存占用。此外,当nums
向量中的元素是较大的结构体或对象时,使用引用可能会更显著地减少内存使用和复制操作。器nums.iter()
进行遍历时,每个元素都是被不可变地借用了,这意味着在遍历过程中不能修改这个元素。
nums.iter().position(|&x| x== k).unwrap() 作用:
在 nums
数组中查找元素 k
的位置,使用了 iter()
方法和 position()
方法。其中 iter()
方法将数组转换成迭代器,position()
方法会在迭代器上执行一个闭包函数,该闭包函数对每个元素进行检查,如果元素等于 k
,就返回该元素在迭代器中的索引,否则返回 None
。由于 position()
方法返回一个 Option<usize>
类型的值,因此还用了 unwrap()
方法来获取该值的实际值,如果获取失败则会触发 panic。最终返回的 k_index
就是元素 k
在 nums
数组中的位置。
|&x|这个是 Rust 闭包(closure)中的语法,用于表示闭包参数。|&x|
表示闭包接收一个参数,使用 x
来引用这个参数,而 &
表示参数是通过引用传递而不是值传递。|
符号用于表示闭包的开始和结束。在这个例子中,闭包用于在 nums
数组中查找值等于 k
的元素的下标位置。