diff --git a/rust/29_heap/get_median.rs b/rust/29_heap/get_median.rs new file mode 100644 index 0000000..f2db2eb --- /dev/null +++ b/rust/29_heap/get_median.rs @@ -0,0 +1,56 @@ +use std::collections::BinaryHeap; + +// 动态数组取位数 +// 对数组进行从小到大排序,数组下标为 n/2 的数据即为中位数 +fn get_median(nums: &mut Vec, 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 +} diff --git a/rust/29_heap/get_top_k.rs b/rust/29_heap/get_top_k.rs new file mode 100644 index 0000000..f96e99b --- /dev/null +++ b/rust/29_heap/get_top_k.rs @@ -0,0 +1,42 @@ +use std::collections::BinaryHeap; + +// 动态数组取 top k 元素 +fn get_top_k(nums: &mut Vec, k: i32, x: i32) -> Vec { + 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 = heap.iter().map(|h| h * -1).collect(); + // m + + heap.iter().map(|h| h * -1).collect::>() +} + +fn main() { + let mut nums = vec![4, 5, 7, 9, 10, 6, 11]; + let m = get_top_k(&mut nums, 3, 23); + println!("{:?}", m); +} diff --git a/rust/29_heap/merge_sorted_array.rs b/rust/29_heap/merge_sorted_array.rs new file mode 100644 index 0000000..fa220da --- /dev/null +++ b/rust/29_heap/merge_sorted_array.rs @@ -0,0 +1,38 @@ +use std::collections::BinaryHeap; + +fn merge_sorted_array(nums1: &mut Vec, nums2: &mut Vec, nums3: &mut Vec) -> Vec { + 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); +}