九日集训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;
}
...全文
45 回复 打赏 收藏 转发到动态 举报
写回复
用AI写文章
回复
切换为时间正序
请发表友善的回复…
发表回复
RubyonRails九日学习计划(含相关软件及书籍)时间 内容 目的
第一天 学习oracle 基本工具掌握 plsql ,sql语言,范式,索引,数据库安全,数据备份,导入导出。 熟练掌握SQL语言
第二天 1. ruby 语言历史和特性介绍,rails框架历史和特性介绍。参考资料《Ruby on Rails 实践.pdf》。
2. 搭建ruby on rails 开发环境并熟悉开发环境。用到的软件在《软件工具》目录。
3. 给学生展示《Ruby on Rails 实践.pdf》中的示例快速建立简单应用。
4. 指导学生完成《Ruby on Rails 实践.pdf》中的内容。 使学生对ruby和rails产生感性认识。
第三天 完成《Ruby语言入门教程》,并上机调试 熟悉Ruby语言基本语法和常用函数
第四天 完成《Ruby语言进阶教程》,并上机调试
第五天 按照《应用Rails进行敏捷Web开发.pdf》学习第二部分购物车示例。
教学第五章节到第七章节内容。 灌输学生敏捷开发方法。
第六天 继续完成第八章到第九章内容。
第七天 继续完成第十章到第11章内容。
第八天 回顾前几天内容。
如果前面几天任务量没有完成那么 继续完成前面几天的内容。 交流总结。
第九天 完成新闻系统需求分析和设计,并有相关文档。主要功能点是:
1. 新闻发布(标题、内容(1000个汉字即可)、新闻分类、有效期)
2. 新闻的分类
3. 新闻列表显示(能翻页)
4. 新闻的详细内容显示 实践和个人能力的展示。
不拘一格尽量让学生自己发挥。
考察学生编程思想、代码规范、设计思想、功能完善、人性化设计、以及界面等方面。

64,075

社区成员

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

QQ群:480072171

英雄算法交流 8 群

 

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