算法日常・每日刷题--<贪心>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;
    }
};
相关推荐
zyl76519 小时前
FlashAttention 详解:从 GPU 硬件、普通 Attention 到分块计算与 Online Softmax
算法
爱读书的小胖1 天前
LeetCode 122:买卖股票的最佳时机 II(C)解题分析
算法
结局无敌1 天前
React Native for OpenHarmony 实战:三方库 react-native-modal-dialog 的鸿蒙化适配指南
深度学习·算法·react native·react.js·harmonyos
OPEN-F1 天前
ROS2系列教程:上位机建图与导航(原理综合)
算法·机器人
weixin_307779131 天前
C++代码实现MATLAB中的fitrtree函数功能
开发语言·c++·算法·matlab
tomwang03221 天前
路径优化建模、优化算法分类及工程化小结
算法·数学建模·分类
小羊没烦恼!1 天前
Ajax与JSON的一些总结
android·java·前端·数据库·mysql·算法·okhttp
by209991 天前
哈希表——快速找到数据:冲突、删除与扩容的实现
数据结构·c++·哈希算法·散列表
2501_926978331 天前
人机通信协议--人和机器之间的交互想象
人工智能·经验分享·算法·ai写作
行者全栈架构师1 天前
【鸿蒙心迹】互动卡片全链路——把核心功能放到桌面(FormKit 实战)(HarmonyOS 7.x)
前端·算法·架构