【力扣每日一题】2023.9.10 打家劫舍Ⅳ

目录

题目:

示例:

分析:

代码:


题目:

示例:

分析:

题目翻译有些烂,我来二次翻译一下,找出数组中k个两两互不相邻的数,求出它们的最大值。要求最大值尽可能小。

我们换个看法来解题,实际上我们要找出一个数,在数组中小于等于这个数并且两两不相邻的元素需要大于等于k。

这下子就让我想到了九月七号的每日一题修车的最少时间和LeetCode75的第五十六题爱吃香蕉的珂珂,可以使用二分查找来解题。

我们用二分查找,首先需要确认左右范围,我们要找的数是数组中长度为k的子数组的最大值,所以范围就是整个数组的最小值和最大值,我们一次遍历就可以获取(用api调用获取也可以)。

接着就是判断缩小范围的条件。

我们去数组中寻找数组中符合要求的小于等于范围中位数的数有几个。如果数量大于等于k,那么缩小右范围,反之缩小左范围,直到范围缩小到一个数,那么这个数就是我们要求的答案。

寻找的话我们可以直接遍历整个数组,遇到不比范围中位数大的数我们就记录下来,然后把用于遍历的下标再加个1,表示不取相邻的元素。

具体可以参考代码。

代码:

cpp 复制代码
class Solution {
public:
    //查看数组中是否有不相邻的k个小于等于窃取能力的房屋
    bool check(vector<int>&nums,int k,int mid){
        int n=0;
        for(int i=0;i<nums.size();i++){
            if(nums[i]<=mid){
                n++;i++;//因为需要不相邻,所以i++多一次
            }
        }
        return n>=k;
    }
    int minCapability(vector<int>& nums, int k) {
        int l=INT_MAX,r=INT_MIN;
        //获取最小值和最大值来作为二分查找的左右边界
        for(int num:nums){
            l=min(l,num);
            r=max(r,num);
        }
        while(l<r){
            int mid=l+(r-l)/2;
            if(check(nums,k,mid)) r=mid;
            else l=mid+1;
        }
        return l;
    }
};
相关推荐
aichitang202425 分钟前
矩阵详解:从基础概念到实际应用
线性代数·算法·矩阵
small_wh1te_coder1 小时前
c语言超详细知识点总结 1500行手写源码 持续更新中ing 从25年5月到6月5日
c++·c
OpenCSG1 小时前
电子行业AI赋能软件开发经典案例——某金融软件公司
人工智能·算法·金融·开源
witton2 小时前
美化显示LLDB调试的数据结构
数据结构·python·lldb·美化·debugger·mupdf·pretty printer
chao_7892 小时前
链表题解——环形链表 II【LeetCode】
数据结构·leetcode·链表
dfsj660112 小时前
LLMs 系列科普文(14)
人工智能·深度学习·算法
SteveDraw2 小时前
C++动态链接库封装,供C#/C++ 等编程语言使用——C++动态链接库概述(总)
开发语言·c++·c#·封装·动态链接库
薛定谔的算法2 小时前
《盗梦空间》与JavaScript中的递归
算法
十五年专注C++开发3 小时前
设计模式之单例模式(二): 心得体会
开发语言·c++·单例模式·设计模式
kaiaaaa3 小时前
算法训练第十一天
数据结构·算法