第六天《贪心》

文章目录

今日知识总结

  1. 贪心的思想:总是作出当前看来最好的选择,不从整体上的最优进行考虑,局部最优解
  2. 例子:对于一个全是正整数的数组,求两数相乘的最大乘积,那么一定是最大的和次大的乘积

题目分析

  1. 题目描述

    1. 题目链接:https://leetcode-cn.com/problems/maximum-product-difference-between-two-pairs/

    2. 思路:最大的两个数的乘积,减去最小的两个数的乘积一定是我们要求的最终解结果,给数组进行排序,找到最大值,次大值,最小值,次小值即可

    3. 代码:

      class Solution {
      public:
          int maxProductDifference(vector<int>& nums) {
              int len = nums.size();
              sort( nums.begin(), nums.end());
              int a = nums[len - 1];
              int b = nums[len - 2];
              int c = nums[0];
              int d = nums[1];
              return a * b - c * d;
      
          }
      };
      
  2. 976. 三角形的最大周长

    1. 题目链接:https://leetcode-cn.com/problems/largest-perimeter-triangle

    2. 思路:首先确定三角形最长的边,再从最长的边反向遍历找比它小的两条边,能构成三角形就一定是最大的三角形周长

    3. 代码:

      class Solution {
      public:
          int largestPerimeter(vector<int>& nums) {
              int len = nums.size();
              int max = 0;
              sort(nums.begin(), nums.end());
              for(int i = len - 1; i - 2 >= 0; i--){
                  if(nums[i] < nums[i - 1] + nums[i - 2]) {
                      //cout << "next";
                      if(max < nums[i] + nums[i - 1] + nums[i - 2]){
                           max = nums[i] + nums[i - 1] + nums[i - 2];
                           break;
                      }
                  }
                  // cout << nums[i]; 
              }
              return max;
          }
      };
      
  3. 561. 数组拆分 I

    1. 题目链接:https://leetcode-cn.com/problems/array-partition-i/

    2. 思路:要想得到最大的min值和,最大的和次大的组队,留下次大的,那么可以先将数组进行从小到大的排序,那么在偶数位上的一定是相对较小的

    3. 代码:

      class Solution {
      public:
          int arrayPairSum(vector<int>& nums) {
              sort(nums.begin(), nums.end());
              int max = 0;
              for(int i = 0; i < nums.size() - 1; i += 2){
                  max += nums[i];
              }
              return max;
      
          }
      };
      
  4. 881. 救生艇

    1. 题目链接:https://leetcode-cn.com/problems/boats-to-save-people/

    2. 思路:判断能否两个人能否同时乘船,可以看最轻的人和最重的人,如果能,就变成了人数每次减二,不能这个人只能自己乘一个船,人数每次减一

    3. 代码:

      class Solution {
      public:
          int numRescueBoats(vector<int>& people, int limit) {
              int ans = 0;
              sort(people.begin(), people.end());
              int r = people.size() - 1;
              int l = 0;
              while(l <= r){
                  if(l == r) {
                      ans++;
                      break;
                  }
                  else if(people[l] + people[r] <= limit){
                      r --;
                      l ++;
                      ans++;
                  }
                  else if(people[l] + people[r] > limit){
                      r --;
                      ans++;
                  }
                  
              }
              return ans;
      
          }
      };
      
  5. 324. 摆动排序 II

    1. 题目链接:https://leetcode-cn.com/problems/wiggle-sort-ii/

    2. 思路:技术位置上从大到小排,偶数位置上也是从大到小排

    3. 代码:

      class Solution {
      public:
          void wiggleSort(vector<int>& nums) {
              int len = nums.size() - 1;
              sort(nums.begin(), nums.end());
              vector<int> ans(len + 1);
              int r = len;
      
              for(int i = 1; i <= len; i += 2){
                  ans[i] = nums[r--];
              }
      
              for(int i = 0; i <= len; i += 2){
                  ans[i] = nums[r--];
              }
      
              for(int i = 0; i < nums.size(); i++){
                  nums[i] = ans[i];
              }
          }
      };
      
  6. 455. 分发饼干

    1. 题目链接:https://leetcode-cn.com/problems/assign-cookies/

    2. 思路:如果最小分量的饼干无法满足胃口最小的孩子,那么这块饼干就直接被丢弃,看看先一块饼干能否满足孩子

    3. 代码:

      class Solution {
      public:
          int findContentChildren(vector<int>& g, vector<int>& s) {
              sort(g.begin(), g.end());
              sort(s.begin(), s.end());
              int cnt = 0;
              int flg = 0, i = 0;
              while(i < g.size()){
                  if(flg == s.size()) break;
                  if(g[i] <= s[flg]) {
                      cnt++;
                      i++;
                  }
                  flg++;
              }
              return cnt;
      
          }
      };
      
  7. 1827. 最少操作使数组递增

    1. 题目链接:https://leetcode-cn.com/problems/minimum-operations-to-make-the-array-increasing/

    2. 思路:判断相邻的两个数是不是递增,如果是,就判断下一组,如果不是就让这个数变成前一个加一,当前这个数的值与之前的值的差就是这两个数之间最小改变次数,如此只需要遍历一遍数组就可以这个数组的最小改变次数了

    3. 代码:

      class Solution {
      public:
          int minOperations(vector<int>& nums) {
              int len = nums.size();
              if(len == 1) return 0;
              int cnt = 0;
      
      
              for(int i = 1; i < len; i++){
                  if(nums[i] > nums[i - 1]) continue;
                  else{
                      cnt += (nums[i - 1] - nums[i] + 1);
                      nums[i] = nums[i - 1]  + 1;
                  }
      
              }
              return cnt;
      
          }
      };
      
  8. 945. 使数组唯一的最小增量

    1. 题目链接:https://leetcode-cn.com/problems/minimum-increment-to-make-array-unique/

    2. 思路:这一题只比上一题多了一个排序的步骤,如果数组严格递增,那么这个数组中的每个值一定是唯一的,如果只是严格递增那无法保证增量最小,那么可以给数组排序,保证数组是递增的,再使递增变成严格递增,这样就可以保证增量最小了

    3. 代码:

      class Solution {
      public:
          int minIncrementForUnique(vector<int>& nums) {
              sort(nums.begin(), nums.end());
              int len = nums.size();
              if(len == 1) return 0;
              int cnt = 0;
      
      
              for(int i = 1; i < len; i++){
                  if(nums[i] > nums[i - 1]) continue;
                  else{
                      cnt += (nums[i - 1] - nums[i] + 1);
                      nums[i] = nums[i - 1]  + 1;
                  }
      
              }
              return cnt;
      
          }
      };
      
  9. 611. 有效三角形的个数

    1. 题目链接:https://leetcode-cn.com/problems/valid-triangle-number/

    2. 思路:

    3. 代码:

      class Solution {
      public:
          int triangleNumber(vector<int>& nums) {
              int len = nums.size();
              sort(nums.begin(), nums.end());
              if(len < 3) return 0;
              int cnt = 0;
              int j = 0, k = 0;
              for(int i = 0; i < len; ++i){
                  j = i + 1;
                  k = j + 1;
                  while(j < len){
                      while( k < len){
                          if(nums[i] + nums[j] <= nums[k]) break;
                          ++k;
                      }
                      cnt += k - j - 1;
                      ++j;
                      if(k == j) k++;
                  }
              }
              return cnt;
      
          }
      };
      

今日收获:

今日疑问:

资料链接

博客链接

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值