Skip to content

Commit 18901d9

Browse files
committed
binary
1 parent f47323a commit 18901d9

File tree

2 files changed

+64
-1
lines changed

2 files changed

+64
-1
lines changed

src/array/ser/binary_search.rs

+63-1
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,7 @@
112112
//! ## 扩展 - 单调函数
113113
//!
114114
//! 前面 对`nums[mid]`和`target`判大小, 其实用数学描述即为
115-
//!
115+
//!
116116
//! ```math
117117
//! f(i) = nums_{i} >= target
118118
//! = \begin{cases}
@@ -137,6 +137,7 @@
137137
//! * [2226. 每个小孩最多能分到多少糖果](maximum_candies)
138138
//! * [436. 寻找右区间](find_right_interval)
139139
//! * [33. 搜索旋转排序数组](search_2)
140+
//! * [2560. 打家劫舍 IV](min_capability)
140141
//! * 困难
141142
//! * [668. 乘法表中第k小的数](find_kth_number)
142143
//!
@@ -589,10 +590,71 @@ where
589590
left.checked_sub(1).unwrap_or(0)
590591
}
591592

593+
/// [2560. 打家劫舍 IV](https://leetcode.cn/problems/house-robber-iv/description/)
594+
///
595+
/// 即`f(y)`为最大偷取金额为`y`的情况下, 可以偷取的房屋最大数量
596+
/// 显然`f(y)`是非递减函数(y越大, 可以选择的节点越多?)
597+
///
598+
/// 由于`f(y)`是非递减函数, 因此可以使用二分查找
599+
pub fn min_capability(nums: Vec<i32>, k: i32) -> i32 {
600+
let (mut min, mut max) = (nums.iter().min().copied().unwrap(), nums.iter().max().copied().unwrap());
601+
while min <= max{
602+
let mid = min + (max - min) / 2;
603+
604+
let mut count = 0;
605+
let mut visited = false;
606+
for &num in nums.iter() {
607+
if num <= mid && !visited{
608+
count += 1;
609+
visited = true;
610+
} else {
611+
visited = false;
612+
}
613+
}
614+
615+
// 非递减, 找最小
616+
// 因此等号在这里
617+
if count >= k{
618+
max = mid - 1;
619+
} else {
620+
min = mid + 1;
621+
}
622+
}
623+
return min;
624+
}
625+
592626
#[cfg(test)]
593627
mod tests {
594628
use super::*;
595629

630+
#[test]
631+
fn test_min_capability() {
632+
struct TestCase {
633+
nums: Vec<i32>,
634+
k: i32,
635+
expect: i32,
636+
}
637+
638+
vec![
639+
TestCase {
640+
nums: vec![2, 3, 5, 9],
641+
k: 2,
642+
expect: 5,
643+
},
644+
TestCase {
645+
nums: vec![2, 7, 9, 3, 1],
646+
k: 2,
647+
expect: 2,
648+
},
649+
]
650+
.into_iter()
651+
.enumerate()
652+
.for_each(|(idc, TestCase { nums, k, expect })| {
653+
let acutal = min_capability(nums, k);
654+
assert_eq!(expect, acutal, "case {} failed", idc);
655+
});
656+
}
657+
596658
#[test]
597659
fn test_peak_index_in_mountain_array() {
598660
struct TestCase {

src/dp/ser/rob.rs

+1
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
//! * [198. 打家劫舍](rob_1)
55
//! * [213. 打家劫舍 II](rob_2)
66
//! * [337. 打家劫舍 III](rob_3)
7+
//! * [2560. 打家劫舍 IV](crate::array::ser::binary_search::min_capability)
78
//!
89
910
use datastructure::TreeNode;

0 commit comments

Comments
 (0)