[LeetCode]Reach a Number

题目描述:

LeetCode 755. Reach a Number

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

On each move, you can either go left or right. During the n-th move (starting from 1), you take n steps.

Return the minimum number of steps required to reach the destination.

Example 1:

Input: target = 3
Output: 2
Explanation:
On the first move we step from 0 to 1.
On the second step we step from 1 to 3.

Example 2:

Input: target = 2
Output: 3
Explanation:
On the first move we step from 0 to 1.
On the second move we step  from 1 to -1.
On the third move we step from -1 to 2.

Note:

  • target will be a non-zero integer in the range [-10^9, 10^9].

题目大意:

从x轴原点开始,每次可以向左或者向右走n步(n为移动的次数),求到达位置target的最少移动次数

解题思路:

打表找规律

打表Python代码:

class SolutionBFS(object):
    def reachNumber(self, target):
        """
        :type target: int
        :rtype: int
        """
        dp = {}
        queue = [0]
        step = 0
        while queue:
            step += 1
            queue0 = set()
            for loc in queue:
                for delta in (-step, step):
                    nloc = loc + delta
                    dp[nloc] = min(step, dp.get(nloc, 0x7FFFFFFF))
                    queue0.add(nloc)
                    if nloc == target:
                        return dp[nloc]
            print list(queue0)
            queue = queue0

print SolutionBFS().reachNumber(40)

利用BFS输出前N步可以到达的位置:

[1, -1]
[1, 3, -3, -1]
[0, 2, 4, 6, -6, -4, -2]
[0, 2, 4, 6, 8, 10, -10, -8, -6, -4, -2]
[1, 3, 5, 7, 9, 11, 13, 15, -15, -13, -11, -9, -7, -5, -3, -1]
[1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, -21, -19, -17, -15, -13, -11, -9, -7, -5, -3, -1]

观察上表可知:

  1. 负数位置与正数位置对称
  2. 当(N - 1) % 4 <= 1时,第N步(N从1开始)可以到达的位置为奇数,否则为偶数
  3. 第N步可以到达的最大绝对值位置为:首项为1,公差为1的等差数列前N项和 S(n) = n * (n + 1) / 2
  4. 令X为target,解方程S(n) = X得:n = (sqrt(1 + 8*x) - 1) / 2

Python代码:

class Solution(object):
    def reachNumber(self, target):
        """
        :type target: int
        :rtype: int
        """
        sumn = lambda x: (1 + x) * x / 2
        target = abs(target)
        ans = int((math.sqrt( 1 + 8 * target) - 1) / 2)
        maxn = sumn(ans)
        if maxn < target:
            ans += 1
            maxn = sumn(ans)
        if target % 2 != maxn % 2:
            ans += 1 + ans % 2
        return ans

本文链接:http://bookshadow.com/weblog/2018/01/01/leetcode-reach-a-number/
请尊重作者的劳动成果,转载请注明出处!书影博客保留对文章的所有权利。

如果您喜欢这篇博文,欢迎您捐赠书影博客: ,查看支付宝二维码

Pingbacks已关闭。

暂无评论

张贴您的评论