[Algorithm][贪心][跳跃游戏][加油站][单调递增的数字][坏了的计算器]详细讲解

目录


1.跳跃游戏

1.题目链接


2.算法思路详解

  • 贪心 :类似层序遍历的过程

3.代码实现

cpp 复制代码
bool canJump(vector<int>& nums) 
{
    int left = 0, right = 0, maxPos = 0, n = nums.size();
    while(left <= right)
    {
        if(maxPos >= n - 1)
        {
            return true;
        }

        for(int i = left; i <= right; i++)
        {
            maxPos = max(maxPos, nums[i] + i);
        }
        left = right + 1;
        right = maxPos;
    }

    return false;
}

2.加油站

1.题目链接


2.算法原理详解

  • 思路一 :暴力解 ---> 枚举 ---> 会超时:P
    • 依次枚举所有的起点
    • 从起点开始,模拟一遍加油的流程即可
  • 思路二 :优化暴力解法 ---> 找规律(贪心)

3.代码实现

cpp 复制代码
// v1.0 暴力解
int canCompleteCircuit(vector<int>& gas, vector<int>& cost) 
{
    int n = gas.size();
    for(int i = 0; i < n; i++) // 枚举起点
    {
        int rest = 0;
        for(int step = 0; step < n; step++) // 枚举向后走的步数
        {
            int index = (i + step) % n; // 求出走step步之后的下标
            rest = rest + gas[index] - cost[index];

            if(rest < 0)
            {
                break;
            }
        }

        if(rest >= 0)
        {
            return i;
        }
    }

    return -1;
}
--------------------------------------------------------------------
// v2.0 贪心
int canCompleteCircuit(vector<int>& gas, vector<int>& cost) 
{
    int n = gas.size();
    for(int i = 0; i < n; i++) // 枚举起点
    {
        int rest = 0, step = 0;
        for(; step < n; step++) // 枚举向后走的步数
        {
            int index = (i + step) % n; // 求出走step步之后的下标
            rest = rest + gas[index] - cost[index];

            if(rest < 0)
            {
                break;
            }
        }

        if(rest >= 0)
        {
            return i;
        }

        i = i + step; // 优化
    }

    return -1;
}

3.单调递增的数字

1.题目链接


2.算法原理详解

  • 思路一 :暴力枚举
    • 从大到小的顺序,枚举[n, 0]区间内的数字
    • 判断数字是否是"单调递增的"
  • 思路二 :贪心
    • 如果高位单调递增,就不去修改
      • 因为高位如果修改了,那么该数大小会小非常多,影响较大
    • 从左往右,找到第一个递减的位置
      • 从这个位置向前推,推到相同区域的最左端
      • 使其减1,后面的数全部修改成9

3.代码实现

cpp 复制代码
int monotoneIncreasingDigits(int n) 
{
    string str = to_string(n); // 把数字转化为字符串,以便逐位操作

    int i = 0, m = str.size();

    // 找到第一个递减的位置
    while(i + 1 < m && str[i] <= str[i + 1])
    {
        i++;
    }

    // 特判
    if(i == m - 1)
    {
        return n;
    }

    // 回推
    while(i - 1 >= 0 && str[i] == str[i - 1])
    {
        i--;
    }

    // 操作
    str[i]--;
    for(int j = i + 1; j < m; j++)
    {
        str[j] = '9';
    }

    return stoi(str);
}

4.坏了的计算器

1.代码实现


2.算法原理详解

  • 思路一 :正向推导,可用DFS解决

  • 思路二:贪心 --> 正难则反

    • 从目标出发,执行/2+1操作

3.代码实现

cpp 复制代码
int brokenCalc(int startValue, int target) 
{
    int ret = 0;
    while(target > startValue)
    {
        if(target % 2 == 0)
        {
            target /= 2;
        }
        else
        {
            target += 1;
        }

        ret++;
    }

    return ret + startValue - target;
}
相关推荐
SkyMaths10 天前
AGC007F 题解
贪心·性质·好题·后效性
UestcXiye13 天前
Leetcode3256. 放三个车的价值之和最大 I
c++·leetcode·贪心·数据结构与算法
DieSnowK14 天前
[Algorithm][综合训练][循环汉诺塔][kotori和素因子][dd爱科学]详细讲解
c++·算法·algorithm·综合训练·循环汉诺塔·kotori和素因子·dd爱科学
DieSnowK18 天前
[Algorithm][综合训练][过桥][最大差值][兑换零钱]详细讲解
c++·算法·algorithm·综合训练·过桥·最大差值·兑换零钱
DieSnowK19 天前
[Algorithm][综合训练][字符编码][最少的完全平方数][游游的字母串]详细讲解
c++·字符编码·算法·algorithm·综合训练·最少的完全平方数·游游的字母串
DieSnowK21 天前
[Algorithm][综合训练][合唱团][跳台阶扩展问题][矩阵最长递增路径]详细讲解
c++·算法·algorithm·综合训练·合唱团·跳台阶扩展问题·矩阵最长递增路径
闻缺陷则喜何志丹1 个月前
【C++贪心】2498. 青蛙过河 II
c++·算法·leetcode·贪心·最小·最大·青蛙
逝去的秋风1 个月前
【代码随想录训练营第42期 Day26打卡 贪心Part1 - LeetCode 455.分发饼干 376. 摆动序列 53. 最大子序和
leetcode·贪心
Aurora_th1 个月前
贪心算法的初涉(双指针 + “过山车思想”)
算法·leetcode·codeforces·贪心·双指针·“过山车”思想