[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;
}
相关推荐
续亮~1 小时前
6、Redis系统-数据结构-05-整数
java·前端·数据结构·redis·算法
逆水寻舟4 小时前
算法学习记录2
python·学习·算法
羞儿4 小时前
【读点论文】基于二维伽马函数的光照不均匀图像自适应校正算法
人工智能·算法·计算机视觉
青衫酒1455 小时前
中国剩余定理
算法
鸽鸽程序猿6 小时前
【数据结构】顺序表
java·开发语言·数据结构·学习·算法·intellij idea
Chris-zz6 小时前
C++:继承
开发语言·c++·算法·学习方法
硕风和炜6 小时前
【LeetCode:3033. 修改矩阵 + 模拟】
java·算法·leetcode·矩阵·模拟
取加若则_7 小时前
C++入门(C语言过渡)
c语言·开发语言·数据结构·c++·算法
真果粒wrdms7 小时前
【在线词典】项目实现
linux·c语言·嵌入式硬件·算法·udp·sqlite3
YangZheng@7 小时前
23种设计模式
c++·算法·设计模式