【每日一题Day17】LC754到达终点数字|数学 等差数列

简介: 在一根无限长的数轴上,你站在0的位置。终点在target的位置。

到达终点数字【LC754】


You are standing at position 0 on an infinite number line. There is a destination at position target.


You can make some number of moves numMoves so that:


  • On each move, you can either go left or right.
  • During the ith move (starting from i == 1 to i == numMoves), you take i steps in the chosen direction.


Given the integer target, return the minimum number of moves required (i.e., the minimum numMoves) to reach the destination.


在一根无限长的数轴上,你站在0的位置。终点在target的位置。


你可以做一些数量的移动 numMoves :


  • 每次你可以选择向左或向右移动。
  • 第 i 次移动(从 i == 1 开始,到 i == numMoves ),在选择的方向上走 i 步。


给定整数 target ,返回 到达目标所需的 最小 移动次数(即最小 numMoves ) 。


还好dp、递归写不出来,就直接看题解了,这不是我能想到的方法


  • 思路


1.数轴上的任意点都以起点(0 点)对称,只需要考虑对称点的任意一边


左边所能到达任意一个点,都能通过调整所达路径的方向来将终点调整到右边。


2.先往靠近 target 的方向移动,到达或越过 target 的时候则停止


。若能直接到达 target,此时消耗的必然是最小步数,可直接返回;

。若越过了target,那么需要考虑是否需要增加额外步数到达target


3.我们假设需要调整的步数总和为tot,则有$ dist−2×tot=target,变形可得 ,变形可得,变形可得tot = \frac{dist - target}{2}$


。当tot为整数时,即$ dist−target$为偶数时,不需要引入额外步数,只需要将某些数反向即可

。当tot不为整数时,即$ dist−target$为奇数时,只能引入额外步数,继续往右走,使两者差值为偶数


  • 实现


class Solution {
    public int reachNumber(int target) {
        while (target < 0){
            target = -target;
        }
        int dis = 0;
        int i = 1;
        while (dis < target || (dis > target && (dis - target) % 2 == 1 ) ){
            dis += i;
            i++;
        }       
        return i - 1;
    }
}


  • 复杂度


。时间复杂度:O ( n )


。空间复杂度:O ( 1 )


  • 代码优化:利用等差数列的性质,找到第一个S k > = t a r g e t


。等差数列前n项和计算公式


image.png


。当a 0 = 0 、 a 1 = 1 、当前步数为k、d=1时,


image.png


。首先找到第一个S k > = t a r g e t ,k = s q r t ( 2 ∗ t a r g e t ) ,此时移动的距离为S k


。代码


只需判断是否需要进行额外移动,额外移动最多4次


class Solution {
    public int reachNumber(int target) {
        if (target < 0) target = -target;
        int k = (int) Math.sqrt(2 * target) , dist = k * (k + 1) / 2;
        while (dist < target || (dist - target) % 2 == 1) {
            k++;
            dist = k * (k + 1) / 2;
        }
        return k;
    }
}


。复杂度


  • 时间复杂度:O ( 1 )


  • 空间复杂度:O ( 1 )
目录
相关文章
|
6月前
|
存储 人工智能 算法
【每日一题Day348】LC137只出现一次的数字Ⅱ | 状态转移
【每日一题Day348】LC137只出现一次的数字Ⅱ | 状态转移
48 0
|
6月前
【每日一题Day312】LC2240买钢笔和铅笔的方案数 | 完全背包 数学
【每日一题Day312】LC2240买钢笔和铅笔的方案数 | 完全背包 数学
60 0
|
6月前
【每日一题Day185】LC1027最长等差数列 | dp
【每日一题Day185】LC1027最长等差数列 | dp
44 0
|
6月前
【每日一题Day302】LC849到最近的人的最大距离 | 贪心+分类讨论
【每日一题Day302】LC849到最近的人的最大距离 | 贪心+分类讨论
54 0
|
6月前
|
机器学习/深度学习
【每日一题Day263】LC2544交替数字和 | 数学
【每日一题Day263】LC2544交替数字和 | 数学
49 0
|
6月前
【每日一题Day114】LC1223 掷骰子模拟 | 记忆化搜索+dp
【每日一题Day114】LC1223 掷骰子模拟 | 记忆化搜索+dp
54 0
|
6月前
|
人工智能 BI
【每日一题Day354】LC2316统计无向图中无法互相到达点对数 | 并查集
【每日一题Day354】LC2316统计无向图中无法互相到达点对数 | 并查集
54 0
|
6月前
|
算法 测试技术 C#
【二进制求公约数】【数学】【数论】2543. 判断一个点是否可以到达
【二进制求公约数】【数学】【数论】2543. 判断一个点是否可以到达
|
6月前
|
vr&ar
【每日一题Day166】LC1053交换一次的先前排列 | 贪心
【每日一题Day166】LC1053交换一次的先前排列 | 贪心
72 1
|
6月前
【每日一题Day350】LC2652倍数求和 | 数学+容斥原理
【每日一题Day350】LC2652倍数求和 | 数学+容斥原理
45 0