LeetCode 514. 自由之路

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)個,實際情況可能比最差的情況好得多,因爲我們每次只搜索了向前和向後最近到達目標字符的點

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章