[Algorithm][贪心][柠檬水找零][将数组和减半的最少操作次数][最大数][摆动序列]详细讲解

目录


1.柠檬水找零

1.题目链接


2.算法原理详解

  • 分情况讨论
    • 如果是5元,只接收下
    • 如果是10元,找零5元之后,收下
    • 如果是20元,则出现贪心策略
      • 先优先考虑10 + 5的组合
      • 如果凑不出来,则拼凑5 + 5 + 5的组合

3.代码实现

cpp 复制代码
bool lemonadeChange(vector<int>& bills) 
{
    int five = 0, ten = 0;
    for(auto& x : bills)
    {
        if(x == 5)
        {
            five++;
        }
        else if(x == 10)
        {
            if(five == 0) 
            {
                return false;
            }
            else
            {
                five--;
                ten++;
            }
        }
        else
        {
            if(ten && five)
            {
                ten--;
                five --;
            }
            else if(five >= 3)
            {
                five -= 3;
            }
            else
            {
                return false;
            }
        }
    }

    return true;
}

2.将数组和减半的最少操作次数

1.题目链接


2.算法原理详解

  • 思路:贪心 + 大根堆
  • 贪心:每次挑选当前数组中,最大的那个数,然后减半,直到数组和减少到至少一半为止

3.代码实现

cpp 复制代码
int halveArray(vector<int>& nums) 
{
    double sum = 0.0;
    priority_queue<double> heap;

    for(const auto& x : nums)
    {
        heap.push(x);
        sum += x;
    }
    sum /= 2.0;

    int count = 0;
    while(sum > 0)
    {
        double tmp = heap.top() / 2;
        heap.pop();

        sum -= tmp;
        count++;
        heap.push(tmp);
    }

    return count;
}

3.最大数

1.题目链接


2.算法原理详解

  • 贪心 :正确的排序顺序,确定谁在前,谁在后
    • ab > baa前,b
    • ab == ba:无所谓
    • ab < bab前,a
  • 优化 :把数转化成字符串,然后拼接字符串,比较字典序
  • 策略 :本题只需要给出排序策略,排序工作可以通过调用sort()完成
  • 返回值 :排除前导0
    • ret[0] == 0 ? 0 : ret

3.代码实现

cpp 复制代码
string largestNumber(vector<int>& nums) 
{
    // 优化:先转化成字符串,再比较字典序
    vector<string> strs;
    for(const auto& x : nums)
    {
        strs.push_back(to_string(x));
    }

    sort(strs.begin(), strs.end(), [](const string& s1, const string& s2)
    {
        return s1 + s2 > s2 + s1;
    });

    string ret;
    for(const auto& str : strs)
    {
        ret += str;
    }

    return ret[0] == '0' ? "0" : ret;
}

4.摆动序列

1.题目链接


2.算法原理详解

  • 贪心 :统计出所有的波峰以及波谷的数量

  • 如何统计出最终的结果?

    • 统计过程中,可能会有下述几种情况

    • 解决方案:无视/挖空中间平的地方即可

      cpp 复制代码
      right = nums[i - 1] - nums[i];
      
      // 如果是平的,跳过该点即可
      if(right == 0) continue;
      
      if(left * right <= 0)
      {
      	ret++;
      }
      
      left = right;

3.代码实现

cpp 复制代码
int wiggleMaxLength(vector<int>& nums) 
{
    int n = nums.size();
    if(n < 2) return n;

    int ret = 0, left = 0;
    for(int i = 0; i < n - 1; i++)
    {
        int right = nums[i + 1] - nums[i];

        // 跳过平的地方
        if(right == 0)
        {
            continue;
        }

        // 寻找波峰/波谷
        if(left * right <= 0)
        {
            ret++;
        }

        left = right;
    }

    return ret + 1;
}
相关推荐
算AI2 小时前
人工智能+牙科:临床应用中的几个问题
人工智能·算法
hyshhhh4 小时前
【算法岗面试题】深度学习中如何防止过拟合?
网络·人工智能·深度学习·神经网络·算法·计算机视觉
杉之4 小时前
选择排序笔记
java·算法·排序算法
烂蜻蜓5 小时前
C 语言中的递归:概念、应用与实例解析
c语言·数据结构·算法
OYangxf5 小时前
图论----拓扑排序
算法·图论
我要昵称干什么5 小时前
基于S函数的simulink仿真
人工智能·算法
AndrewHZ5 小时前
【图像处理基石】什么是tone mapping?
图像处理·人工智能·算法·计算机视觉·hdr
念九_ysl5 小时前
基数排序算法解析与TypeScript实现
前端·算法·typescript·排序算法
守正出琦5 小时前
日期类的实现
数据结构·c++·算法
ChoSeitaku5 小时前
NO.63十六届蓝桥杯备战|基础算法-⼆分答案|木材加工|砍树|跳石头(C++)
c++·算法·蓝桥杯