算法日常・每日刷题--<贪心>25

397. 整数替换 - 力扣(LeetCode)397. 整数替换 - 给定一个正整数 n ,你可以做如下操作: 1. 如果 n 是偶数,则用 n / 2替换 n 。 2. 如果 n 是奇数,则可以用 n + 1或n - 1替换 n 。返回 n 变为 1 所需的 最小替换次数 。 示例 1:输入:n = 8输出:3解释:8 -> 4 -> 2 -> 1示例 2:输入:n = 7输出:4解释:7 -> 8 -> 4 -> 2 -> 1或 7 -> 6 -> 3 -> 2 -> 1示例 3:输入:n = 4输出:2 提示: * 1 <= n <= 231 - 1https://leetcode.cn/problems/integer-replacement/

题目描述

给定一个正整数 n,我们可以执行两种操作:

  1. 如果 n 是偶数:n = n / 2
  2. 如果 n 是奇数:可以选择 n = n + 1 或者 n = n - 1

求把 n 变为 1 需要的最少替换次数。

数据范围:1 <= n <= 2^31 - 1,需要注意 int 溢出问题。

核心思路(贪心 + 二进制位运算)

偶数没有选择,只能直接除以 2,对应二进制右移一位,消除末尾的 0。 难点在于奇数 :奇数只能 + 1 或者 - 1,我们贪心选择操作后能产生更多末尾 0的方案,末尾 0 越多,后续可以连续除 2,步数更少。

奇数二进制最后一位一定是 1,我们看最后两位:

  • 末两位 01(n % 4 == 1):执行 n-1,直接消除末尾 1,得到末尾两个 0,可以连续两次除 2。
  • 末两位 11(n % 4 == 3):执行 n+1,发生进位,连续把一串 1 全部变成 0,一次性消除多个低位 1。

⚠️ 特殊特例 n = 3(二进制 11) 按照上面规则,11应该 + 1 变成 4,路径 3→4→2→1 需要 3 步; 但 3-1=2,路径 3→2→1 只需要 2 步,更优。所以必须单独判断 n == 3,强制走n-1。

cpp 复制代码
class Solution {
public:
    int integerReplacement(int n1) {
        int count=0;
        long long n=n1;
        while(n!=1)
        {
            
            if(n%2==0)
                n=n/2;
            else{
                if(n==3)
                    n-=1;
                else if((n & (1 << 1)) != 0)//判断二进制次低位是不是1,末两位11
                    n+=1;
                else
                    n-=1;
            }
            count++;
        }
        return count;
    }
};
相关推荐
Cccp.1234 小时前
【leetcode】(七)前缀树和贪心算法
数据结构·leetcode·贪心算法
千里码aicood5 小时前
基于CART算法的图书分类系统设计与实现
数据库·算法·分类
做cv的小昊5 小时前
【World Model】π0.5:a Vision-Language-Action Model with Open-World Generalization
人工智能·算法·机器学习·大模型·多模态·vla·世界模型
لا معنى له5 小时前
World-In-World: World Models in a Closed-Loop World
算法
Logic1017 小时前
C语言/数据结构位运算题解:异或XOR找出多任务下载器中的“独特下载速度“——只出现一次的数字
c语言·数据结构·数组·位运算·时间复杂度·算法题·异或性质
Discipline10298 小时前
尼泊尔河流流量:天气驱动的预测与高流量风险
人工智能·算法
XuCoder8 小时前
改一个数,右边全得重算,这题怎么扛住两万次查询
算法
小羊没烦恼!8 小时前
在Scrum中实施敏捷建模
java·开发语言·windows·算法·c#