当青训营遇上码上掘金
前言
第一次加入字节的青训营,我十分的开心,希望自己不仅能通过这次的青训营之旅丰富自己的阅历之余,还能够认识到更多的学习伙伴。最后通过快乐写码分享讲解我创作灵感和过程的同时,也希望大家可以及时纠正我的错误,伴我学习。
题目介绍
主题 3:寻友之旅
小青要找小码去玩,他们的家在一条直线上,当前小青在地点 N ,小码在地点 K (0≤N , K≤100 000),并且小码在自己家原地不动等待小青。小青有两种交通方式可选:步行和公交。
步行:小青可以在一分钟内从任意节点 X 移动到节点 X-1 或 X+1
公交:小青可以在一分钟内从任意节点 X 移动到节点 2×X (公交不可以向后走)
请帮助小青通知小码,小青最快到达时间是多久?
输入: 两个整数 N 和 K
输出: 小青到小码家所需的最短时间(以分钟为单位)
题目分析
做这道题目时,我联想到生活中一个场景,并且发现了这道题目的解就是找离自己所在位置最近的一个公交站,为什么这样想呢?看我下面分析!
- 我们将终点K除以2,直到K=0,并且将每次的值放到一个数组,得到一个公交车站所在的位置表,
- 因为只要在前面的公交车站上车,就一定能到达终点,并且所花费时间一定是最短的。
- 然后根据起点所在位置去距离最近的公交车站即可。
代码
package main
import (
"fmt"
)
func main() {
var N, K int64 // 因为N K的数据范围为 0 到 1000000 所以得用 int64 类型
// fmt.Scan(&N, &K) //输入N,K
N, K = 2, 4096
var time int64 = 0
if N >= K { //此时代表小青在小码家的前面 只能步行
time = N - K
} else { //形象为一个等公交问题 在一路上每k/2距离有个公交站
before, after := K/2, K
for { //在Golang里面没有while关键字
if N >= before && N < after {
time += Min(N-before+1, after-N) //这里需要比较N与两个边界的距离值 并且左边界需要加1 因为还要算上坐公交的1分钟
break
} else {
time += 1
before = before / 2
after = after / 2
}
}
}
fmt.Println(time)
}
func Min(x, y int64) int64 {
if x < y {
return x
}
return y
}
灵感,心得与体会
第一次写这道算法题的时候,纯按自己想到那就做到那,都没想到BFS,就硬暴力,后面联想到这题有点想找公交站(后面看其他大佬写的代码其实归根到底还是BFS的思想),就做出来了,因为题目本身其实并不难,所以后面我又去恶补了BFS,以及DFS的知识