LeetCode 514. 自由之路

1 篇文章 0 订阅

514.自由之路

目录

思路

代码

复杂度分析


思路

构建一个映射表,记录ring中每个下标向前向后到达每个字母的距离。然后BFS枚举,只枚举当前位置向前向后的到达目标字符,并记录。

枚举的时候采用了一些小优化,map的重复使用,以及只记录需要遍历的pos等等。

代码

func findRotateSteps(ring string, key string) int {
	dist := make([][][]int, len(ring))
	nRing := len(ring)
	nKey := len(key)
	for i := 0; i < nRing; i++ {
		dist[i] = make([][]int, 2)
		dist[i][0] = make([]int, 26)
		dist[i][1] = make([]int, 26)
		for k := 0; k < 26; k++ {
			dist[i][0][k] = -1
			dist[i][1][k] = -1
		}
		dist[i][0][int(ring[i]-'a')] = 0
		dist[i][1][int(ring[i]-'a')] = 0
		for j := i + 1; j < nRing; j++ {
			if dist[i][0][int(ring[j]-'a')] == -1 || dist[i][0][int(ring[j]-'a')] > j-i {
				dist[i][0][int(ring[j]-'a')] = j - i
			}
			if dist[i][1][int(ring[j]-'a')] == -1 || dist[i][1][int(ring[j]-'a')] > i+nRing-j {
				dist[i][1][int(ring[j]-'a')] = i + nRing - j
			}
		}
		for j := 0; j < i; j++ {
			if dist[i][0][int(ring[j]-'a')] == -1 || dist[i][0][int(ring[j]-'a')] > nRing+j-i {
				dist[i][0][int(ring[j]-'a')] = nRing + j - i
			}
			if dist[i][1][int(ring[j]-'a')] == -1 || dist[i][1][int(ring[j]-'a')] > i-j {
				dist[i][1][int(ring[j]-'a')] = i - j
			}
		}
	}

	cnt := 0
	hasM := make([]int, nRing)
	stepM := make([]int, nRing)
	posArr := make([]int, 0, nRing)

	next := func(curPos, curStep, next int) {
		beforStep := curStep + dist[curPos][1][next] + 1
		beforPos := (curPos - dist[curPos][1][next] + nRing) % nRing
		afterStep := curStep + dist[curPos][0][next] + 1
		afterPos := (curPos + dist[curPos][0][next]) % nRing

		if hasM[beforPos] != cnt {
			stepM[beforPos] = beforStep
			posArr = append(posArr, beforPos)
			hasM[beforPos] = cnt
		} else {
			if stepM[beforPos] > beforStep {
				stepM[beforPos] = beforStep
			}
		}

		if hasM[afterPos] != cnt {
			stepM[afterPos] = afterStep
			posArr = append(posArr, afterPos)
			hasM[afterPos] = cnt
		} else {
			if stepM[afterPos] > afterStep {
				stepM[afterPos] = afterStep
			}
		}
	}

	curPosArr := make([]int, 1, nRing)
	for i := 0; i < nKey; i++ {
		cnt++
		for _, curPos := range curPosArr {
			next(curPos, stepM[curPos], int(key[i]-'a'))
		}
		curPosArr, posArr = posArr, curPosArr[:0]
	}

	min := int(0x7fffffff)
	for _, curPos := range curPosArr {
		if stepM[curPos] < min {
			min = stepM[curPos]
		}
	}
	return min
}

复杂度分析

构建距离表,O(len(ring)*len(ring))

BFS到达终点,O(len(key)*len(ring)), posArr 中的点最多也就len(ring)个,实际情况可能比最差的情况好得多,因为我们每次只搜索了向前和向后最近到达目标字符的点

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值