算法日常・每日刷题--<贪心>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;
    }
};
相关推荐
地平线开发者5 小时前
点云算法整理与常用计算模块:从数据到模型,再到工程与量化
算法·自动驾驶
Severus_black6 小时前
【C++初阶】list使用及相关实现,思路顺滑流畅!
c语言·数据结构·c++·stl·list
武子康7 小时前
H3-World 为何在加载 LoRA 前,先检查导入的代码?
人工智能·深度学习·算法
秋天的怀念_David8 小时前
算法一千零一夜 · 第二十八夜 注册
java·程序人生·算法
二本咕咕-机械转码8 小时前
FreeRTOS深入解析(八)IPC机制之FromISR详解
数据结构·单片机·链表
NEFU_Jyj10 小时前
贝尔数(组合数学)
算法
1-1=010 小时前
C# 数据结构和特殊类型
数据结构·c#·.net·.netcore
希和202710 小时前
C语言程序设计题|有序数组插入数字冒泡排序
c语言·数据结构·算法
Pniubi10 小时前
力扣73 矩阵置零
算法·leetcode·矩阵
布莱克60521 小时前
C++ 中 map 的 insert 与 emplace:key 已存在时会覆盖吗?
开发语言·数据结构·c++·算法·map