当青训营遇上码上掘金---寻友之旅
题目要求
小青要找小码去玩,他们的家在一条直线上,当前小青在地点 N ,小码在地点 K (0≤N , K≤100 000),并且小码在自己家原地不动等待小青。小青有两种交通方式可选:步行和公交。
步行:小青可以在一分钟内从任意节点 X 移动到节点 X-1 或 X+1
公交:小青可以在一分钟内从任意节点 X 移动到节点 2×X (公交不可以向后走)
请帮助小青通知小码,小青最快到达时间是多久?
输入: 两个整数 N 和 K
输出: 小青到小码家所需的最短时间(以分钟为单位)
package main
import (
"fmt"
)
func main() {
var n, k int
fmt.Scan(&n, &k)
fmt.Println(minSteps(n, k))
}
func minSteps(n, k int) int {
steps := 0
for n != k {
if k > n {
if k%2 == 0 {
k /= 2
steps++
} else {
k++
steps++
}
} else {
k++
steps++
}
}
return steps
}
上面的代码实现了一个名为minSteps的函数,它接受两个整数n和k作为输入,其中n是起点,k是目的地。它使用一个循环来重复直到n和k相等。在每次循环中,它检查k是否大于n。如果k大于n,它检查k是否是偶数。如果是,它将k除以2并增加步骤计数。如果k是奇数,它将k加1并增加步骤计数。如果k不大于n,它将k加1并增加步骤计数。该函数返回到达目的地所需的步骤数。
package main
import (
"fmt"
"queue"
)
func main() {
var n, k int
fmt.Scan(&n, &k)
fmt.Println(minSteps(n, k))
}
func minSteps(n, k int) int {
visited := make(map[int]bool)
q := queue.New()
q.Push(n)
visited[n] = true
steps := 0
for q.Len() > 0 {
size := q.Len()
for i := 0; i < size; i++ {
curr := q.Pop().(int)
if curr == k {
return steps
}
next := curr + 1
if next <= 100000 && !visited[next] {
q.Push(next)
visited[next] = true
}
next = curr * 2
if next <= 100000 && !visited[next] {
q.Push(next)
visited[next] = true
}
}
steps++
}
return -1
}
这种实现使用队列数据结构和广度优先搜索算法来找到从n到k的最短路径。它首先将起点n推入队列并标记为已访问。然后进入一个循环,直到队列为空。在每次迭代中,它从队列中弹出当前位置,将其标记为已访问并增加步骤。然后将下一个可能的位置推入队列并将其标记为已访问。一旦到达目的地,它返回到达它所需要的步骤数。如果无法到达目的地,它返回-1。 这个代码里面用了一个队列,我们用队列来存储所有已经访问过的位置,每次从队列里面取出队首的位置,判断它可以到达的下一个位置,如果下一个位置没有被访问过,就加入队列并标记为已访问。如果下一个位置就是目的地,就返回步数。 这种实现虽然稍微复杂一点,但是它可以避免重复访问,更加高效,所以在复杂度较大的情况下更能适用。