feat(geektime_algo): add 29 heap
get top k, get median, merge sored array
This commit is contained in:
parent
cd90b4caff
commit
34b493b372
56
rust/29_heap/get_median.rs
Normal file
56
rust/29_heap/get_median.rs
Normal file
@ -0,0 +1,56 @@
|
||||
use std::collections::BinaryHeap;
|
||||
|
||||
// 动态数组取位数
|
||||
// 对数组进行从小到大排序,数组下标为 n/2 的数据即为中位数
|
||||
fn get_median(nums: &mut Vec<i32>, x: i32) -> i32 {
|
||||
let nums_len = nums.len();
|
||||
let mid = nums_len >> 1;
|
||||
let mut max_heap = BinaryHeap::new();
|
||||
let mut min_heap = BinaryHeap::new();
|
||||
nums.sort();
|
||||
|
||||
// 将数组前半部分数据放入大顶堆
|
||||
// 数组后半部分数据入入小顶堆
|
||||
for i in 0..nums_len {
|
||||
if i < mid {
|
||||
max_heap.push(nums[i]);
|
||||
} else {
|
||||
min_heap.push(-nums[i]);
|
||||
}
|
||||
}
|
||||
|
||||
nums.push(x);
|
||||
|
||||
// 校验待插入数据
|
||||
// 若此数据小于大顶堆中顶数据,则将此数据插入大顶堆
|
||||
// 若此数据大于大顶堆中顶数据,将此数据插入小顶堆
|
||||
if x <= *max_heap.peek().unwrap() {
|
||||
max_heap.push(x);
|
||||
} else {
|
||||
min_heap.push(-x);
|
||||
}
|
||||
|
||||
// 平衡两个堆
|
||||
// 大顶堆的数据个数一定小于等于小顶堆数据个数
|
||||
// 小顶堆数据个数一定是等于或者比大顶堆数据个数多1个
|
||||
// 不满足上述两个条件,即进行堆平衡
|
||||
if max_heap.len() > min_heap.len() {
|
||||
min_heap.push(-max_heap.pop().unwrap());
|
||||
} else if min_heap.len() - max_heap.len() >= 2 {
|
||||
max_heap.push(-min_heap.pop().unwrap());
|
||||
}
|
||||
|
||||
-*min_heap.peek().unwrap()
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let mut nums = vec![12, 45, 30, 77, 5, 6, 7, 8];
|
||||
let m = get_median(&mut nums, 9);
|
||||
println!("{:?}", m); // 9
|
||||
let n = get_median(&mut nums, 20);
|
||||
println!("{:?}", n); // 12
|
||||
let h = get_median(&mut nums, 11);
|
||||
println!("{:?}", h); // 11
|
||||
let i = get_median(&mut nums, 10);
|
||||
println!("{:?}", i); // 11
|
||||
}
|
42
rust/29_heap/get_top_k.rs
Normal file
42
rust/29_heap/get_top_k.rs
Normal file
@ -0,0 +1,42 @@
|
||||
use std::collections::BinaryHeap;
|
||||
|
||||
// 动态数组取 top k 元素
|
||||
fn get_top_k(nums: &mut Vec<i32>, k: i32, x: i32) -> Vec<i32> {
|
||||
let nums_len = nums.len() as i32;
|
||||
if nums_len <= k { return nums.clone(); }
|
||||
|
||||
let mut heap = BinaryHeap::new();
|
||||
|
||||
// 先将数组的前k个数据放入堆中
|
||||
for _i in 0..k {
|
||||
heap.push(-nums[k as usize]);
|
||||
}
|
||||
|
||||
// 对数组中其它数据进行迭代,若数据大于堆顶元素,将堆顶元素移除,将此数据放入堆中
|
||||
for i in k + 1..nums_len {
|
||||
if -nums[i as usize] < *heap.peek().unwrap() {
|
||||
heap.pop();
|
||||
heap.push(-nums[i as usize]);
|
||||
}
|
||||
}
|
||||
|
||||
// 向数组中插入新数据
|
||||
nums.push(x);
|
||||
|
||||
// 新插入的数据若大于堆顶元素,将堆顶元素移除,将此数据放入堆中
|
||||
if -x < *heap.peek().unwrap() {
|
||||
heap.pop();
|
||||
heap.push(-x);
|
||||
}
|
||||
|
||||
// let m: Vec<i32> = heap.iter().map(|h| h * -1).collect();
|
||||
// m
|
||||
|
||||
heap.iter().map(|h| h * -1).collect::<Vec<i32>>()
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let mut nums = vec![4, 5, 7, 9, 10, 6, 11];
|
||||
let m = get_top_k(&mut nums, 3, 23);
|
||||
println!("{:?}", m);
|
||||
}
|
38
rust/29_heap/merge_sorted_array.rs
Normal file
38
rust/29_heap/merge_sorted_array.rs
Normal file
@ -0,0 +1,38 @@
|
||||
use std::collections::BinaryHeap;
|
||||
|
||||
fn merge_sorted_array(nums1: &mut Vec<i32>, nums2: &mut Vec<i32>, nums3: &mut Vec<i32>) -> Vec<i32> {
|
||||
let mut new_nums = vec![];
|
||||
let mut heap = BinaryHeap::new();
|
||||
|
||||
// Rust heap 是大顶堆,将待入堆的数值取反后再入堆,堆顶即为最小值,即达到小顶堆效果
|
||||
heap.push(-nums1[0]);
|
||||
heap.push(-nums2[0]);
|
||||
heap.push(-nums3[0]);
|
||||
|
||||
while !nums1.is_empty() || !nums2.is_empty() || !nums3.is_empty() {
|
||||
if heap.is_empty() { break; }
|
||||
let num = -heap.pop().unwrap();
|
||||
new_nums.push(num);
|
||||
|
||||
if !nums1.is_empty() && num == nums1[0] {
|
||||
nums1.remove(0);
|
||||
if !nums1.is_empty() { heap.push(-nums1[0]); }
|
||||
} else if !nums2.is_empty() && num == nums2[0] {
|
||||
nums2.remove(0);
|
||||
if !nums2.is_empty() { heap.push(-nums2[0]); }
|
||||
} else if !nums3.is_empty() && num == nums2[0] {
|
||||
nums3.remove(0);
|
||||
if !nums3.is_empty() { heap.push(-nums3[0]); }
|
||||
}
|
||||
}
|
||||
new_nums
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let mut nums1 = vec![4, 5, 20, 90, 95, 100];
|
||||
let mut nums2 = vec![1, 6, 7, 8, 11, 23, 67, 89];
|
||||
let mut nums3 = vec![2, 5, 9, 30, 45];
|
||||
let new_nums = merge_sorted_array(&mut nums1, &mut nums2, &mut nums3);
|
||||
|
||||
println!("{:?}", new_nums);
|
||||
}
|
Loading…
Reference in New Issue
Block a user