二指輸入法定製鍵盤在 XY 平面上的佈局如上圖所示,其中每一個大寫英文字母都位於某個座標處,例如字母 A 位於座標 (0,0),字母 B 位於座標 (0,1),字母 P 位於座標 (2,3) 且字母 Z 位於座標 (4,1)。數組
給你一個待輸入字符串 word
,請你計算並返回在僅使用兩根手指的狀況下,鍵入該字符串須要的最小移動總距離。座標 (x1,y1) 和 (x2,y2) 之間的距離是 |x1 - x2| + |y1 - y2|。函數
注意,兩根手指的起始位置是零代價的,不計入移動總距離。你的兩根手指的起始位置也沒必要從首字母或者前兩個字母開始。佈局
示例 1:學習
輸入:word = "CAKE"
輸出:3
解釋:
使用兩根手指輸入 "CAKE" 的最佳方案之一是:
手指 1 在字母 'C' 上 -> 移動距離 = 0
手指 1 在字母 'A' 上 -> 移動距離 = 從字母 'C' 到字母 'A' 的距離 = 2
手指 2 在字母 'K' 上 -> 移動距離 = 0
手指 2 在字母 'E' 上 -> 移動距離 = 從字母 'K' 到字母 'E' 的距離 = 1
總距離 = 3ui
示例 2:spa
輸入:word = "HAPPY"
輸出:6
解釋:
使用兩根手指輸入 "HAPPY" 的最佳方案之一是:
手指 1 在字母 'H' 上 -> 移動距離 = 0
手指 1 在字母 'A' 上 -> 移動距離 = 從字母 'H' 到字母 'A' 的距離 = 2
手指 2 在字母 'P' 上 -> 移動距離 = 0
手指 2 在字母 'P' 上 -> 移動距離 = 從字母 'P' 到字母 'P' 的距離 = 0
手指 1 在字母 'Y' 上 -> 移動距離 = 從字母 'A' 到字母 'Y' 的距離 = 4
總距離 = 6code
示例 3:blog
輸入:word = "NEW"
輸出:3leetcode
示例 4:
輸入:word = "YEAR"
輸出:7
提示:
2 <= word.length <= 300
word[i]
都是一個大寫英文字母。我本身沒作出來,學習了比賽排行榜上第一頁的 suibianfahui 的代碼。這個代碼是我理解之後本身寫的。原來和原代碼相同。
定義一個字母位置表,再定義一個函數 find_distance 查找任意兩個字母間距離
mapx[f1, f2] = setp
mapx 是一個字典,
f1 表明當前狀態第一個手指的位置,f2 是第二個手指的位置, None 表明這個手指還沒用過
setp 是如今一共移動了多少距離。
mapx[單詞第一個字母,None] = 0 表明我用第一個手打了第一個字母,第二個手沒動,一共移動 0 步
從第二個字母開始遍歷單詞,
對每個字母要檢查**上一步**全部的狀態(由於只須要上一步,因此不用 dp 數組,每次都覆蓋上一次的結果就能夠了)
對每一個狀態,嘗試用第一個手指打當前字母和用第二個手指打當前字母
最後返回 map 中最小值就能夠了。
歡迎來[個人博客](https://codeplot.top/),看我刷的其餘題目:[刷題記錄](https://codeplot.top/categori...
class Solution: def minimumDistance(self, word: str) -> int: if len(word) == 2: # 若是隻有兩個字母,不須要移動 return 0 # 字母位置表 pos = {} ch = ord('A') for i in range(5): for j in range(6): pos[chr(ch)] = (i, j) if ch == ord('Z'): break ch += 1 #print(pos) # {'A': (0, 0), 'B': (0, 1), 'C': (0, 2), 'D': (0, 3), 'E': (0, 4), 'F': (0, 5), 'G': (1, 0), 'H': (1, 1), 'I': (1, 2), 'J': (1, 3), 'K': (1, 4), 'L': (1, 5), 'M': (2, 0), 'N': (2, 1), 'O': (2, 2), 'P': (2, 3), 'Q': (2, 4), 'R': (2, 5), 'S': (3, 0), 'T': (3, 1), 'U': (3, 2), 'V': (3, 3), 'W': (3, 4), 'X': (3, 5), 'Y': (4, 0), 'Z': (4, 1)} def find_distance(a, b): # 求 a, b 兩個字母距離 if a == None: return 0 return abs(pos[a][0] - pos[b][0]) + abs(pos[a][1] - pos[b][1]) mapx = {} mapx[(word[0], None)] = 0 # map[(a, b)] = setp 表明 第一個手指目前在 a 上, 第二個手指在 b 上, 步數爲 setp # None 表明這個手指還沒用過 for cur in word[1:]: next_map = {} for finger1, finger2 in mapx: f1_dis = find_distance(finger1, cur) # 手指 1 到當前字母的距離 f2_dis = find_distance(finger2, cur) # 手指 2 到當前字母的距離 new_state1 = (cur, finger2) # 第一個手指按當前字母(固然第二個手指的狀態不變) new_state2 = (finger1, cur) # 第二個手指按當前字母 for new_state, dis in ((new_state1, f1_dis), (new_state2, f2_dis)): if new_state in next_map: next_map[new_state] = min(mapx[(finger1, finger2)] + dis, next_map[new_state]) else: next_map[new_state] = mapx[(finger1, finger2)] + dis mapx = next_map return min(mapx.values())