九日集训Day6贪心算法

我不是很喜欢聊天 2022-05-20 23:49:42

今天要学习的内容是贪心思想,贪心思想就是每次都是选取局部最优解,最后就可能得到全局最优解。

第一题

1913. 两个数对之间的最大乘积差

思路1:排序之后选最大和最小的两组数据之差

int cmp(const void* str1,const void* str2)
{
    return *(int*)str1-*(int*)str2;
}

int maxProductDifference(int* nums, int numsSize){

    qsort(nums,numsSize,sizeof(int),cmp);
    return (nums[numsSize-1]*nums[numsSize-2])-(nums[0]*nums[1]);
}

第二题

976. 三角形的最大周长

思路1:先排序数组,然后从大到小开始枚举,看最后三条边是不是满足两条小边相加>大边,如果不满足,则i--,减小最大边,继续判断,如果遍历完了数组都没有,那么数组元素都不构成三角形返回0即可。


int cmp(const void* str1,const void* str2)
{
    return *(int*)str1 - *(int*)str2;
}

int largestPerimeter(int* nums, int numsSize){

    qsort(nums,numsSize,sizeof(int),cmp);
    for(int i =numsSize-1;i>=2;i--)
    {
        if(nums[i]<nums[i-1]+nums[i-2])
        {
            return nums[i]+nums[i-1]+nums[i-2];
        }
    }
    return 0;

}

第三题

  1. 数组拆分 I

    思路:排序后,将相邻数进行分组,因为相邻两个数取最小值,可以保证砍掉的数字是相比较其他元素更小的,让最大的和次最大的成组,可以保证留下次最大的数字。

int cmp(const void* str1,const void* str2)
{
    return *(int*)str1 - *(int*)str2;
}


int arrayPairSum(int* nums, int numsSize){

    qsort(nums,numsSize,sizeof(int),cmp);
    int sum = 0;
    for(int i =0;i<numsSize;i+=2)
    {
        sum+=nums[i];
    }
    return sum;
}

第四题

881. 救生艇

思路:排序数组,从后向前,如果最后一个人的体重达到了limit就让他自己坐船走,如果小于limit就要判断,这个局部最重的和局部最轻的加在一起有没有超过limit,如果超过了,就让最重的走,如果没超过,就一起走。

int cmp(const void* str1,const void* str2)
{
    return *(int*)str1-*(int*)str2;
}

int numRescueBoats(int* people, int peopleSize, int limit){

    qsort(people,peopleSize,sizeof(int),cmp);
    int left = 0;
    int right = peopleSize-1;
    int count = 0;
    while(left<=right)
    {
        if(people[right]==limit)
        {
            right--;
            count++;
        }
        else
        {
            if(people[left]+people[right]<=limit)
            {
                left++;
                right--;
                count++;
            }
            else
            {
                right--;
                count++;
            }
        }
    }
    return count;
}

第五题

324. 摆动排序 II

思路:将数组拷贝一份然后排序,对原来数组的奇偶位进行插入,观察可以发现,偶数位插入最大值,所以定义一个指针从后向前遍历,排序好的数组,将最大值依次递减插入,
然后将插入完偶数位剩下的数组从后向前插入,这样可以保证,最大值对应小的那一半数字的最大值,完成贪心思想。

int cmp(const void* str1,const void* str2)
{
    return *(int*)str1-*(int*)str2;
}

void wiggleSort(int* nums, int numsSize){

    int arr[numsSize];
    memcpy(arr,nums,sizeof(int)*numsSize);
    qsort(arr,numsSize,sizeof(int),cmp);

    int arrsize = numsSize-1;
    for(int j =1;j<numsSize;j+=2)
    {
        nums[j] = arr[arrsize];
        arrsize--;
    }
    for(int i =0;i<numsSize;i+=2)
    {
        nums[i] = arr[arrsize];
        arrsize--;
    }   
}

第六题

455. 分发饼干

思路:将饼干和小孩都排序,先拿最小的饼干给最容易饱的小孩,如果饱了,计数器++,不饱就换一块更大的。直到饼干没了或者小孩子都饱了,循环结束

int cmp(const void* str1,const void* str2)
{
    return *(int*)str1-*(int*)str2;
}

int findContentChildren(int* g, int gSize, int* s, int sSize){
    qsort(g,gSize,sizeof(int),cmp);
    qsort(s,sSize,sizeof(int),cmp);
    int cookie = 0;
    int ans = 0;
    int i = 0;
    while(cookie<sSize&&i<gSize)
    {
        if(g[i]>s[cookie])//没吃饱
        {
            cookie++;
        }
        else//吃饱了
        {
            i++;
            cookie++;
            ans++;
        }
    }
    return ans;
}

第七题

1827. 最少操作使数组递增

思路是:遍历每个数组元素,如果数组元素前一个大于该元素,就把数组元素递增至nums[i-1]+1;然后计数器增加nums[i-1]+1-nums[i]即可(也就是记录从nums[i]到nums[i]+1要加多少个1即可)

int minOperations(int* nums, int numsSize){
    if(numsSize==1)
    return 0;
    
    int cnt = 0;
    int i = 1;
    while(i<numsSize)
    {
        if(nums[i]<=nums[i-1])
        {
            cnt+=nums[i-1]-nums[i]+1;
            nums[i]=nums[i-1]+1;
        }
        else
        {
            i++;
        }
    }
    return cnt;
}

第八题

945. 使数组唯一的最小增量

思路:先排序数组,然后判断数组的每个元素和前一个元素相比是不是比前一个大,如果不是就递增到nums[i]+1;记录递增次数,最后返回即可。

int cmp(const void* str1,const void* str2)
{
    return *(int*)str1-*(int*)str2;
}

int minIncrementForUnique(int* nums, int numsSize){
    qsort(nums,numsSize,sizeof(int),cmp);
    int ans = 0;
    int i = 1;
    while(i<numsSize)
    {
        if(nums[i]<=nums[i-1])
        {
            ans+=nums[i-1]-nums[i]+1;
            nums[i] = nums[i-1]+1;         
            i++;
        }
        else
        i++;
    }
    return ans;
}

第九题

611. 有效三角形的个数

思路是:先排序,然后枚举第一条和第二条第三条边,判断如果第三条边>前两边之和,就结束第三层循环,用计数器记录第二条和第三条之间,有效的有几条,加到计数器上。然后将第二条进行++。继续枚举第三条。如果第二条和第三条重合了就自增第三条。

    
int cmp(const void* str1,const void* str2)
{
    return *(int*)str1-*(int*)str2;
}


int triangleNumber(int* nums, int numsSize){
    qsort(nums,numsSize,sizeof(int),cmp);
    int one = 0;
    int two = 0;
    int three = 0;
    int count = 0;
    for(one = 0;one<numsSize;one++)
    {
        two = one+1;
        three = two +1;
        while(two<numsSize)
        {
            while(three<numsSize)
            {
                if(nums[one]+nums[two]<=nums[three])
                {
                    break;
                }
                three++;
            }
            count+=three-two-1;
            two++;
            if(two==three)
            three++;
        }
    }
    return count;
}
...全文
117 回复 打赏 收藏 转发到动态 举报
写回复
用AI写文章
回复
切换为时间正序
请发表友善的回复…
发表回复
内容概要:本文围绕【语音增强】领域中的组稀疏信号去噪问题展开研究,提出了一种结合非凸正则化与凸优化理论的去噪方法,旨在提升含噪语音信号的可懂度与质量。文章系统阐述了组稀疏信号模型的构建机制,引入非凸正则项以更精确地逼近理想稀疏性,克服传统凸正则化在稀疏表达上的局限性,并采用高效的凸优化算法保障模型求解的稳定性与收敛性。整个算法流程在Matlab平台上完整实现,涵盖语音信号预处理、稀疏系数求解、去噪重构等关键环节,并配套提供可复现的代码资源,便于研究人员进一步验证与拓展。该方法在保留数学可处理性的同时显著增强了去噪性能,尤其适用于低信噪比环境下的语音恢复任务。; 适合人群:具备一定信号与系统、数字信号处理理论基础,熟悉稀疏表示与最优化方法,且拥有Matlab编程能力的研究生、科研人员及从事语音增强、音频工程、通信系统等相关领域的工程技术人员。; 使用场景及目标:①应用于语音通信、智能助听设备、语音识别前端等对语音质量要求较高的实际系统中;②作为高校课程或科研项目中的教学案例,帮助深入理解稀疏表示、非凸优化与凸优化算法的融合机制;③为后续研究非凸正则化在图像去噪、生物医学信号处理等其他稀疏恢复问题中的性能优势提供理论依据与实现范例。; 阅读建议:建议读者结合所提供的Matlab代码逐模块分析,重点理解非凸正则项的设计动机及其对稀疏性的增强作用,深入掌握优化求解过程中迭代算法的实现细节;同时可通过调整正则化参数、测试不同噪声类型(如白噪声、车间噪声)与强度的语音信号,系统评估算法的鲁棒性、收敛速度与去噪效果,从而全面把握该方法的优势与潜在局限。

64,205

社区成员

发帖
与我相关
我的任务
社区描述
学习「 算法 」的捷径就是 「 题海战略 」,社区由「 夜深人静写算法 」作者创建,三年ACM经验,校集训队队长,亚洲区域赛金牌,世界总决赛选手。社区提供系统的训练,答疑解惑,面试经验,大厂内推等机会
社区管理员
  • 英雄哪里出来
  • 芝麻粒儿
  • Amy卜bo皮
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

QQ群:480072171

英雄算法交流 8 群

 

试试用AI创作助手写篇文章吧