题目链接
6346. 打家劫舍 IV
题目描述
沿街有一排连续的房屋。每间房屋内都藏有一定的现金。现在有一位小偷计划从这些房屋中窃取现金。
由于相邻的房屋装有相互连通的防盗系统,所以小偷 不会窃取相邻的房屋 。
小偷的 窃取能力 定义为他在窃取过程中能从单间房屋中窃取的 最大金额 。
给你一个整数数组 nums 表示每间房屋存放的现金金额。形式上,从左起第 i 间房屋中放有 nums[i] 美元。
另给你一个整数数组 k ,表示窃贼将会窃取的 最少 房屋数。小偷总能窃取至少 k 间房屋。
返回小偷的 最小 窃取能力。
题解
/**
* @param {number[]} nums
* @param {number} k
* @return {number}
*/
var minCapability = function (nums, k) {
// 最小窃取能力显然是与房屋金额有关
// 对窃取能力值去重 从小到大排序
const arr = Array.from(new Set(nums)).sort((x, y) => x - y);
// 二分
let left = 0, right = arr.length - 1
while (left <= right) {
const mid = ((left + right) >> 1)
const cap = arr[mid]; // 当前能力值
let dp_2 = 0, dp_1 = 0 // 当前-2最多偷几家 当前-1最多偷几家
for (let i = 0; i < nums.length; i++) {
let dp_0 // 当前最多偷几家
if (nums[i] <= cap) { // 可以偷
dp_0 = Math.max(dp_2 + 1, dp_1);
} else { // 不能偷
dp_0 = Math.max(dp_2, dp_1)
}
[dp_2, dp_1] = [dp_1, dp_0]
}
if (Math.max(dp_2, dp_1) < k) left = mid + 1 // 需要加强窃取能力才能达到要求
else right = mid - 1 // 当前窃取能力已经达到要求 尝试减少点能力
}
return arr[left]
};