当青训营遇上码上掘金
今天解决的是青训营活动中的一道算法题,算法题目如下:
小青要找小码去玩,他们的家在一条直线上,当前小青在地点 N ,小码在地点 K (0≤N , K≤100 000),并且小码在自己家原地不动等待小青。小青有两种交通方式可选:步行和公交。
步行:小青可以在一分钟内从任意节点 X 移动到节点 X-1 或 X+1
公交:小青可以在一分钟内从任意节点 X 移动到节点 2×X (公交不可以向后走)
请帮助小青通知小码,小青最快到达时间是多久?
输入: 两个整数 N 和 K
输出: 小青到小码家所需的最短时间(以分钟为单位)
阅读完这道题之后,我们有了一个大致的思路:可能是考虑使用广搜(BFS)算法对小青的移动进行模拟,计算出最短时间。使用队列维护每个地点的时间,从初始位置开始,每次扩展两种移动方式,直到到达小码的家。最终,取得时间最小的地点即为小青最快到达的时间。
因此,从初始点开始扩展,向两个方向(步行和公交)进行拓展,累加距离,将每一步移动到的新点入队,并且更新该点的距离。当搜到终点时,即可得到最短路径。
const maxUint = ^uint(0)
const maxInt = int(maxUint >> 1)
func shortestTime(N int, K int) int {
queue := []int{N}
visited := make([]bool, 100001)
visited[N] = true
steps := 0
for len(queue) > 0 {
size := len(queue)
for i := 0; i < size; i++ {
current := queue[i]
if current == K {
return steps
}
if current-1 >= 0 && !visited[current-1] {
queue = append(queue, current-1)
visited[current-1] = true
}
if current+1 <= maxInt && !visited[current+1] {
queue = append(queue, current+1)
visited[current+1] = true
}
if current*2 <= maxInt && !visited[current*2] {
queue = append(queue, current*2)
visited[current*2] = true
}
}
steps++
queue = queue[size:]
}
return -1
}
func main() {
N := 5
K := 7
fmt.Println(shortestTime(N, K))
}
这段代码是一个求小青最快到达小码家的时间的程序,它的思路是使用 BFS 算法对每个节点进行搜索,并将其分为步行和公交两种情况。
- 首先声明了两个变量 N 和 K 分别表示小青当前位置和小码位置。
- 队列 q 作为 BFS 搜索的队列,并初始化其值为 N 。
- 变量 dist 记录小青到达每个节点的时间,初始化为 0 。
- 在循环中,对队列的每一个元素进行判断,如果是小码的位置则返回答案,否则进行步行和公交两种情况的搜索。
- 步行的情况是当前节点减一或加一,公交情况是当前节点乘二,并将新的节点加入队列。
- 如果队列为空,说明没有找到答案,则返回 -1。
整个程序以 BFS 算法为核心,对每个节点进行搜索,找到最快到达小码家的路线,最后返回答案。
以上就是我对于这道题的思路以及答案,如果有更好的思路或者代码可以再次优化的欢迎指点。