754. Reach a Number

本文介绍了一种寻找从数轴起点0移动到任意目标位置所需最小移动次数的算法。通过数学推导,发现移动总步数与目标数之间的差值必须为偶数才能实现最短路径,提供了一个实用的解决方案。

问题描述:给你一个范围在[-10^9, 10^9]的数字,从数轴上0开始,你可以选择向左或者向右移动,第n次移动的长度等于n。找出移动到目标数字所需要的最小移动次数。
思路:首先把负数全部转化为正数以简化问题,一开始的想法是先尽可能的向这个数字移动,然后通过来回的左右移动到达目标数字。然而,4需要移动次数为[-1,2,3],这与想法不符。随后我发现,如果以4为例,总移动步数为1+2+3=6步。6-4=2,2%2=0。以5为例移动次数为[-1,2,3,-4,5]或者[1,-2,-3,4,5]总移动步数为1+2+3+4+5=15,15-5=10;10%2=0。似乎最小移动数就是找出一个最小的移动步数总和使的(移动数总和-目标数)%2=0;
原答案:

    public int reachNumber(int target) {
        target=Math.abs(target);
        if(target==1)
            return 1;
        if(target==0)
            return 3;
        int prevMove=new Double((-1+Math.sqrt(1+8*target))/2).intValue();
        for(int i=prevMove;;i++){
            int totalSum=i*(i+1)/2-target;
            if(totalSum<0)
                continue;
            if(totalSum%2==0)
                return i;
        }
    }

直觉上的解释如下:首先,累加的移动步数一定要大于目标步数。而累加的移动步数与目标步数之间会有个差值。这个差值需要反方向的移动来弥补。假设是第i次反方向移动了,那么正向移动数将为移动总步数-2i。因此,移动总步数与目标数的差值必须是个偶数才可以。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值