【每日刷题】Day42

【每日刷题】Day42

🥕个人主页:开敲🍉

🔥所属专栏:每日刷题🍍

🌼文章目录🌼

1. 826. 安排工作以达到最大收益 - 力扣(LeetCode)

2. 2099. 找到和最大的长度为 K 的子序列 - 力扣(LeetCode)

3. 2335. 装满杯子需要的最短总时长 - 力扣(LeetCode)

1. 826. 安排工作以达到最大收益 - 力扣(LeetCode)

//思路:本题主体思路为排序,但是有个问题需要解决——排序后难度对应的利润会发生变化。我们可以将难度数组中的元素全部按照如下规则变化:×数组长度后+自身下标,当我们需要知道其对应的利润时可以直接 % 上数组长度,当我们需要求得其原本的长度时,可以直接 - 下标再 ÷ 数组长度即可。

int compare(const void* a,const void* b)

{

    return (*(int*)a-*(int*)b);

}


 

int maxProfitAssignment(int* difficulty, int difficultySize, int* profit, int profitSize, int* worker, int workerSize)  

{

    for(int i = 0;i<difficultySize;i++)

    {

        difficulty[i] = difficulty[i]*difficultySize+i;//将难度数组元素变化

    }

    qsort(difficulty,difficultySize,sizeof(int),compare);//对难度数组排序

    qsort(worker,workerSize,sizeof(int),compare);//对工人数组排序

    int w = 0;

    int ans = 0;

    int i = 0;

    int flag = 0;

    int max = 0;

    while(w<workerSize)

    {

        if(flag==0&&((difficulty[i]-i)/difficultySize)>worker[w])//用于处理工人数组中所有工人都没有能力处理工作的情况

        {

            w++;

            flag = 0;

        }

        else if(i<difficultySize&&((difficulty[i]-i)/difficultySize)<=worker[w])//找到当前工人所能处理的工作中的最大利润的工作,记录最大利润

        {

            max = max>profit[difficulty[i]%difficultySize]?max:profit[difficulty[i]%difficultySize];

            i++;

            flag = 1;

        }

        if(i==difficultySize||(flag==1&&((difficulty[i]-i)/difficultySize)>worker[w]))//到遍历到当前工人的能力范围之外的工作时,将结果+上所记录的最大利润,向后继续遍历工人数组

        {

            ans+=max;

            w++;

        }

    }

    return ans;

}

2. 2099. 找到和最大的长度为 K 的子序列 - 力扣(LeetCode)

//思路:本题思路还是排序,难点还是在于题目要求最后返回的元素顺序不能改变,也就是下标顺序不能改变,因此我们如法炮制通过元素的变换使得后面还能够找到下标。这里我们将题目原数组中的元素进行变换,随后对其进行降序排序(元素大小由高到低)。再使用一个数组记录排序后的原数组的前k个元素原来的下标,随后再对这个数组进行升序排序(使得下标由低到高),这样就既能够找到原数组最大的k个元素,又能够保证下标顺序不会改变。然后我们需要使用一个数组存储最初的没有做任何操作的原数组,通过前面存储的排好序的下标数组,找到原数组中满足题目要求的子序列。

int compare1(const void* a,const void* b)

{

    return (*(int*)b-*(int*)a);

}

int compare2(const void* a,const void* b)

{

    return (*(int*)a-*(int*)b);

}


 

int* maxSubsequence(int* nums, int numsSize, int k, int* returnSize)

{

    int tmp[1000] = {0};

    memcpy(tmp,nums,sizeof(int)*numsSize);

    int flag[numsSize];

    int* ans = (int*)malloc(sizeof(int)*numsSize);

    for(int i = 0;i<numsSize;i++)//对题目所给数组中的元素进行变换

    {

        if(nums[i]<0)

        {

            nums[i] = nums[i]*numsSize-i;

        }

        else

        {

            nums[i] = nums[i]*numsSize+i;

        }

    }

    qsort(nums,numsSize,sizeof(int),compare1);//进行降序排序(为了找到最大的k个元素)

    for(int i = 0;i<k;i++)

    {

        int tmp = 0;

        if(nums[i]<0)//获取最大的k个元素原本的下标

        {

            tmp = (nums[i]*-1)%numsSize;

        }

        else

        {

            tmp = nums[i]%numsSize;

        }

        flag[i] = tmp;

    }

    qsort(flag,k,sizeof(int),compare2);//对最大的k个元素原本的下标进行升序排序

    for(int i = 0;i<k;i++)

    {

        ans[i] = tmp[flag[i]];//通过下标找到元素,构成满足题目要求的子序列

    }

    *returnSize = k;

    return ans;

}

3. 2335. 装满杯子需要的最短总时长 - 力扣(LeetCode)

//思路:堆。将数组用大堆存储。每次将堆中最大的两个元素-1,直到堆顶的元素为0。 

typedef int HPDataType;

//交换

void Swap(HPDataType* child, HPDataType* parents)

{

    HPDataType tmp = *child;

    *child = *parents;

    *parents = tmp;

}


 

//向上调整

void HPAdjustUp(HPDataType* arr,int child)

{

    int parents = (child - 1) / 2;

    while (child > 0&&arr[child]>arr[parents])

    {

        Swap(&arr[child], &arr[parents]);

        child = parents;

        parents = (child - 1) / 2;

    }

}


 

//向下调整

void HPAdjustDown(HPDataType* arr, int parents,int size)

{

    int child = parents * 2 + 1;

    while (child < size)

    {

        if (child+1<size&&arr[child + 1] > arr[child])

        {

            child++;

        }

        if (arr[child] > arr[parents])

        {

            Swap(&arr[child], &arr[parents]);

            parents = child;

            child = parents * 2 + 1;

        }

        else

        {

            break;

        }

    }

}


 

int fillCups(int* amount, int amountSize)

{

    int count = 0;

    for(int i = 0;i<amountSize;i++)

    {

        HPAdjustUp(amount,i);//将数据用大堆的形式存储

    }

    while(amount[0]>0)

    {

        amount[0]--;//由于是大堆存储,因此堆顶数据一定是最大的

        if(amount[1]>amount[2])//找到堆中第二大的元素

        {

            amount[1]--;

        }

        else

        {

            amount[2]--;

        }

        HPAdjustDown(amount,0,amountSize);//将堆中最大的元素-1后需要更新堆,确保堆依然是大堆

        count++;//计算总时长

    }

    return count;

}

  • 33
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值