当青训营遇上码上掘金
题目
小青要找小码去玩,他们的家在一条直线上,当前小青在地点 N ,小码在地点 K (0≤N , K≤100 000),并且小码在自己家原地不动等待小青。小青有两种交通方式可选:步行和公交。
步行:小青可以在一分钟内从任意节点 X 移动到节点 X-1 或 X+1
公交:小青可以在一分钟内从任意节点 X 移动到节点 2×X (公交不可以向后走) 请帮助小青通知小码,小青最快到达时间是多久? 输入: 两个整数 N 和 K 输出: 小青到小码家所需的最短时间(以分钟为单位)
[题目](「青训营 X 码上掘金」主题创作活动入营版 开启! - 掘金 (juejin.cn))
分析
每次能够走N+1,N-1,或者N*2 可以将本题目看做是一系列选择+1,-1,x2的选择的组合,众所周知,组合问题可以回溯法,因为回溯的本质是穷举,穷举所有可能,然后选出我们想要的答案 回溯法的最深的深度是abs(N-k)
回溯三部曲
参数
N当前位置,K目标位置
终止条件
- 走到了终点也就是N==K
- 达到了最大深度,最大深度以后虽然能走但是肯定不是最优,终止搜索
if(N == K) {
if(step < min) {
min = step;
}
return;
}
if(step >= max) {
return;
}
如果走到位置,终止搜索 如果当前走的步数小于,abs(N-k) 认为是有效的答案
当前层的逻辑
在每一层,都有三个选择,向前向后或者坐公交,因此需要搜索的有 N+1, N-1, 2*N
backTracking(N+1, K, step+1 );
backTracking(N-1, K, step+1 );
backTracking(N*2, K, step+1 );
处理完当前层, 回溯,搜索下一种可能
代码
剪枝优化
如果,N>k,因为公交不能后退那么只能选择一步步走,所以当前的 step = step + ( K- N )