2139. 得到目标值的最少行动次数

题目

你正在玩一个整数游戏。从整数 1 开始,期望得到整数 target 。

在一次行动中,你可以做下述两种操作之一:

递增,将当前整数的值加 1(即, x = x + 1)。
加倍,使当前整数的值翻倍(即,x = 2 * x)。
在整个游戏过程中,你可以使用 递增 操作 任意 次数。但是只能使用 加倍 操作 至多 maxDoubles 次。

给你两个整数 target 和 maxDoubles ,返回从 1 开始得到 target 需要的最少行动次数。

题解

  1. 循环写法
class Solution {
    public int minMoves(int target, int maxDoubles) {
        int ans = 0;
        
        while(target != 1){
            //若target是双数,且还能够除以2,除以2,递归一次
            if(target %2 == 0 && maxDoubles != 0){
                target = target/2;
                maxDoubles--;
                ans++;
            }
            else{
                if(maxDoubles ==0)      //如果maxDouble为零,后面就不循环了,直接得到答案。
                    return ans+target-1;
                target--;
                ans++;
            }
        }
        return ans;
            
    }
}
  1. 递归写法
class Solution {
    public int minMoves(int target, int maxDoubles) {
        //递归终止条件
        if(target ==1 || maxDoubles ==0)
            return target-1;
        //当target为双数时,除以2,maxDouble次数减一,然后递归调用1次
        //当target为单数时,减1,然后递归调用1次
        return target %2 == 0 ? minMoves(target/2,maxDoubles-1)+1:minMoves(target-1,maxDoubles)+1;
    }
}

思路

  • 这是非递归的写法
  • 反向推导法,用到了类似贪婪算法的规则?只要能除以2,就除以2,因为越晚除,数字target下降得越慢。
  • 当target变成1的时候,终止循环。
  • 还可以用递归写法。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

yaomian99

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值