|
112 | 112 | //! ## 扩展 - 单调函数
|
113 | 113 | //!
|
114 | 114 | //! 前面 对`nums[mid]`和`target`判大小, 其实用数学描述即为
|
115 |
| -//! |
| 115 | +//! |
116 | 116 | //! ```math
|
117 | 117 | //! f(i) = nums_{i} >= target
|
118 | 118 | //! = \begin{cases}
|
|
137 | 137 | //! * [2226. 每个小孩最多能分到多少糖果](maximum_candies)
|
138 | 138 | //! * [436. 寻找右区间](find_right_interval)
|
139 | 139 | //! * [33. 搜索旋转排序数组](search_2)
|
| 140 | +//! * [2560. 打家劫舍 IV](min_capability) |
140 | 141 | //! * 困难
|
141 | 142 | //! * [668. 乘法表中第k小的数](find_kth_number)
|
142 | 143 | //!
|
@@ -589,10 +590,71 @@ where
|
589 | 590 | left.checked_sub(1).unwrap_or(0)
|
590 | 591 | }
|
591 | 592 |
|
| 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 | + |
592 | 626 | #[cfg(test)]
|
593 | 627 | mod tests {
|
594 | 628 | use super::*;
|
595 | 629 |
|
| 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 | + |
596 | 658 | #[test]
|
597 | 659 | fn test_peak_index_in_mountain_array() {
|
598 | 660 | struct TestCase {
|
|
0 commit comments