当青训营遇上码上掘金,开寻友之旅。
寻友之旅
小青要找小码去玩,他们的家在一条直线上,当前小青在地点 N ,小码在地点 K (0≤N , K≤100 000),并且小码在自己家原地不动等待小青。
小青有两种交通方式可选:步行和公交。
步行:小青可以在一分钟内从任意节点 X 移动到节点 X-1 或 X+1
公交:小青可以在一分钟内从任意节点 X 移动到节点 2×X (公交不可以向后走)
请帮助小青通知小码,小青最快到达时间是多久?
输入: 两个整数 N 和 K
输出: 小青到小码家所需的最短时间(以分钟为单位)
题解
看到这道题,首先其实考虑的就是BFS 和动态规划,考虑到这个深度有10万,所以尽可能向动态规划去考虑,此外该题还可以用dijsktra和BFS解决: juejin.cn/post/718837…,同时我验证了我们两个的输出是一样的。
主要思路:
首先,考虑特殊情况,就是如果小青在小码的右边(也就是前面),则只能步行,因为公交乘不能往后走。
其次,我们用 arr 一维数组记录值,arr[x] 表示从N到x的最短时间。在遍历循环的时候,对于 的情况 刚刚说过只能走路,因此最短时间就是 ,直接可以计算。
在这里还要知道在什么情况下要往回走,肯定是做公交下车往回步行走,如果单纯的走路来回会浪费时间
-
初始化数组,对于 ,
-
对于 开始,的最短路径可以考虑以下情况:(从左边步行走异步过来,从上一站坐车过来,从右边往回走一步)
- 对于从左边步行走异步过来,就是接着在上个时候继续步行
- 对于从上一站坐车过来,能够坐车必须满足为偶数,此外
- 在 的时候步行,但是按照我们的遍历规则还没轮到记录,因此,我们就要研究的上一个状态。如果 的值比的时间还短,说明的上一个状态肯定是坐了公交车,于是,能够坐车必须满足为偶数,
if i == N {
arr[i] = 0
} else if i == N+1 {
arr[i] = 1
} else {
if arr[i] == 0 {
arr[i] = arr[i-1] + 1
} else {
arr[i] = min(arr[i], arr[i-1]+1)
}
if i%2 == 0 {
arr[i] = min(arr[i], arr[i/2]+1)
} else {
arr[i] = min3(arr[i], arr[i/2]+2, arr[(i+1)/2]+2)
}
}
此外,在解决这道题的时候,我又实现了任意两点之间的最短时间,不过对于大数字时间很长。
这是我参与「第五届青训营 」笔记创作活动的第5天.