主题3——寻友之旅

58 阅读3分钟

当青训营遇上码上掘金

前言

第一次加入字节的青训营,我十分的开心,希望自己不仅能通过这次的青训营之旅丰富自己的阅历之余,还能够认识到更多的学习伙伴。最后通过快乐写码分享讲解我创作灵感和过程的同时,也希望大家可以及时纠正我的错误,伴我学习。

题目介绍

主题 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的知识