319 · 方阵排队

该算法问题旨在确定一个数组中最多能组成多少个人的方阵,要求方阵内每行人的身高差不超过2。通过排序数组并使用二分查找,找到最大的方阵尺寸。给定的代码实现了一个检查函数`checkCount`和主要的解决方案`MaxPeopleNumber`,用于找到满足条件的最大人数。测试用例展示了不同输入下的输出结果。
摘要由CSDN通过智能技术生成

算法

困难

通过率43%

题目

给定一个长度为N的数组height代表N个人的身高
请你选出一部分人组成方阵(即矩阵的行数与列数相同),并且每一行的人的身高差不超过2。
请问最多能选取多少人参加方阵

1≤N≤1051 \leq N \leq 10^51≤N≤105
1≤height[i]≤1091 \leq height[i] \leq 10^91≤height[i]≤109

样例

输入:[2,5,4,5]
输出:4
解释:可以组成 [[2,4],[5,5]]这样的方阵
输入:[1,4,5,6,7,7,7,10,11,12]
输出:9
解释:可以组成 [[4,5,6],[7,7,7],[10,11,12]]这样的方阵


bool checkCount(vector<int> &height,int target)
{
    int start = 0;
    int countCol = 0;
    int curIndex = 0;

    while (start + target -1 < height.size())
    {
        if (height[start + target -1 ] - height[start] >2)
        {
            start++;
        }
        else
        {
            countCol++;
            start = start+ target;
        }
    }

    if (countCol < target)
    {
        return false;
    }

    return true;
}

int MaxPeopleNumber(vector<int> &height)
{
    int size = height.size();
    sort(height.begin(), height.end());
    int maxLen = sqrt(size);
    
    int start = 1;
    int mid = (maxLen + start) / 2;

    while (mid >= 1 )
    {
        //二分法查找,如果最大满足要求,则返回
        if (checkCount(height, maxLen))
        {
            return maxLen*maxLen;
        }
        else if (checkCount(height, mid)) //向最大值逼近
        {
            start = mid;
            maxLen--;
            mid = (maxLen + start) / 2;
        }
        else
        {
            maxLen = mid;
            mid = (maxLen + start) / 2;
        }

    }

    return 1;
}
void test()
{
    //vector<int> height = { 2, 5, 4, 5 };//4
    //vector<int> height = { 1, 4, 5, 6, 7, 10, 10, 10, 11, 12 };// //4
    //vector<int> height = { 1, 4, 5, 6, 7, 7, 7, 10, 11, 12 };// //9
    vector<int> height = { 3,6,3,9,1,3,4,3,4 };//4
    //vector<int> height = { 1, 4, 5, 6, 7, 7, 7, 10, 11, 12 };//9

    int ret = MaxPeopleNumber(height);
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值