【leetcode】1320. Minimum Distance to Type a Word Using Two Fingers

题目如下:

You have a keyboard layout as shown above in the XY plane, where each English uppercase letter is located at some coordinate, for example, the letter A is located at coordinate (0,0), the letter B is located at coordinate (0,1), the letter P is located at coordinate (2,3) and the letter Z is located at coordinate (4,1).

Given the string word, return the minimum total distance to type such string using only two fingers. The distance between coordinates (x1,y1) and (x2,y2) is |x1 - x2| + |y1 - y2|.

Note that the initial positions of your two fingers are considered free so don‘t count towards your total distance, also your two fingers do not have to start at the first letter or the first two letters.

Example 1:

Input: word = "CAKE"
Output: 3
Explanation:
Using two fingers, one optimal way to type "CAKE" is:
Finger 1 on letter ‘C‘ -> cost = 0
Finger 1 on letter ‘A‘ -> cost = Distance from letter ‘C‘ to letter ‘A‘ = 2
Finger 2 on letter ‘K‘ -> cost = 0
Finger 2 on letter ‘E‘ -> cost = Distance from letter ‘K‘ to letter ‘E‘ = 1
Total distance = 3

Example 2:

Input: word = "HAPPY"
Output: 6
Explanation:
Using two fingers, one optimal way to type "HAPPY" is:
Finger 1 on letter ‘H‘ -> cost = 0
Finger 1 on letter ‘A‘ -> cost = Distance from letter ‘H‘ to letter ‘A‘ = 2
Finger 2 on letter ‘P‘ -> cost = 0
Finger 2 on letter ‘P‘ -> cost = Distance from letter ‘P‘ to letter ‘P‘ = 0
Finger 1 on letter ‘Y‘ -> cost = Distance from letter ‘A‘ to letter ‘Y‘ = 4
Total distance = 6

Example 3:

Input: word = "NEW"
Output: 3

Example 4:

Input: word = "YEAR"
Output: 7

Constraints:

  • 2 <= word.length <= 300
  • Each word[i] is an English uppercase letter.

解题思路:首先把A-Z分别用0~25下标来代替,记dp[i][j][k] 为输入完第i个字符后左手在第j个位置,右手在第k个位置的时候移动的次数最小。这里只需要和dp[i-1]建立状态转移方程,可以分为以下四种情况:

1. word[i]和word[i-1]都是左手输入的,那么左手一定是从word[i-1]的索引位置移动到word[i]的索引位置,而右手可以处在任意索引位置j上面, 有 dp[i][inx][j] = min(dp[i][inx][j], dp[i-1][pervious_inx][j] + calcDis(pervious_inx,inx)) ; 其中inx为第word[i]个字符的索引,pervious_inx是word[i-1]的索引,calcDis 计算的是从 pervious_inx到 inx需要移动的距离。

2.word[i]是左手输入并且word[i-1]是右手输入,那么右手还处于word[i-1]的索引位置,而左手可能从任意的索引位置j移动到 word[i]索引位置,有 dp[i][inx][pervious_inx] = min(dp[i][inx][pervious_inx], dp[i-1][j][pervious_inx] + calcDis(j, inx)) 。

3.word[i]是右手输入并且word[i-1]是左手输入,有dp[i][pervious_inx][inx] = min(dp[i][pervious_inx][inx], dp[i-1][pervious_inx][j] + calcDis(j, inx)) 。

4.word[i]和word[i-1]都是右手输入的,有 dp[i][j][inx] = min(dp[i][j][inx], dp[i-1][j][pervious_inx] + calcDis(pervious_inx,inx))

代码如下:

class Solution(object):
    def minimumDistance(self, word):
        """
        :type word: str
        :rtype: int
        """
        def getInx(char):
            return ord(char) - ord(‘A‘)

        def calcDis(inx1,inx2):
            if inx1 / 6 == inx2 / 6:
                return abs(inx2 - inx1)
            dis = abs(inx1 / 6 - inx2 / 6)
            min_inx = min(inx1,inx2)
            max_inx = max(inx1,inx2)
            min_inx += dis * 6
            return dis + abs(max_inx - min_inx)

        dp = [[[float(‘inf‘)] * 26 for _ in range(26)] for _ in word]

        for k in range(26):
            # the first letter input by left hand
            dp[0][getInx(word[0])][k] = 0
            # the first letter input by right hand
            #print k,getInx(word[0])
            dp[0][k][getInx(word[0])] = 0

        res = float(‘inf‘)
        for i in range(1,len(word)):
            for j in range(26):
                inx = getInx(word[i])
                pervious_inx = getInx(word[i-1])

                # input via left hand,pervious is left too
                dp[i][inx][j] = min(dp[i][inx][j], dp[i-1][pervious_inx][j] + calcDis(pervious_inx,inx))

                # input via left hand,pervious is right
                dp[i][inx][pervious_inx] = min(dp[i][inx][pervious_inx], dp[i-1][j][pervious_inx] + calcDis(j, inx))

                # input via right hand,pervious is left
                dp[i][pervious_inx][inx] = min(dp[i][pervious_inx][inx], dp[i-1][pervious_inx][j] + calcDis(j, inx))

                # input via right hand,pervious is right too
                dp[i][j][inx] = min(dp[i][j][inx], dp[i-1][j][pervious_inx] + calcDis(pervious_inx,inx))

        last_inx = getInx(word[-1])
        for i in range(26):
            res = min(res,dp[-1][last_inx][i])
            res = min(res,dp[-1][i][last_inx])

        #print dp

        return res

原文地址:https://www.cnblogs.com/seyjs/p/12204923.html

时间: 2024-08-29 15:15:11

【leetcode】1320. Minimum Distance to Type a Word Using Two Fingers的相关文章

动态规划-Minimum Distance to Type a Word Using Two Fingers

2020-01-12 18:28:13 问题描述: 问题求解: 本题还是非常困难的,至少我在看到这个题目的时候是没有想到怎么解决的.我当时联想到的题目是那条grid走两遍的题目,那条题目也很麻烦,使用的是dp. 本题最终的解决方式其实是和那条题目是类似的,也是使用dp的方式去做. 最大的类似在于,这两题都可以使用dfs + me来进行解决,dfs和dp任何一个都是解决问题的大杀器,他们的结合就更是非常的厉害.很多的题目直接使用自底向上的dp是不容易写的,但是结合dfs使用me的dp则非常的直观并

【LeetCode】Find Minimum in Rotated Sorted Array 解题报告

今天看到LeetCode OJ题目下方多了"Show Tags"功能.我觉着挺好,方便刚開始学习的人分类练习.同一时候也是解题时的思路提示. [题目] Suppose a sorted array is rotated at some pivot unknown to you beforehand. (i.e., 0 1 2 4 5 6 7 might become 4 5 6 7 0 1 2). Find the minimum element. You may assume no

【leetcode】1347. Minimum Number of Steps to Make Two Strings Anagram

题目如下: Given two equal-size strings s and t. In one step you can choose any character of t and replace it with another character. Return the minimum number of steps to make t an anagram of s. An Anagram of a string is a string that contains the same c

【LeetCode】462. Minimum Moves to Equal Array Elements II

Given a non-empty integer array, find the minimum number of moves required to make all array elements equal, where a move is incrementing a selected element by 1 or decrementing a selected element by 1. You may assume the array's length is at most 10

【leetcode】Find Minimum in Rotated Sorted Array JAVA实现

一.题目描述 Suppose a sorted array is rotated at some pivot unknown to you beforehand. (i.e., 0 1 2 4 5 6 7 might become 4 5 6 7 0 1 2). Find the minimum element. You may assume no duplicate exists in the array. 二.分析 这题难度有,因为他默认的是数组中所有的元素是不同的.只有分为两种情况: 1.

【LeetCode】Find Minimum in Rotated Sorted Array 在旋转数组中找最小数

Add Date 2014-10-15 Find Minimum in Rotated Sorted Array Suppose a sorted array is rotated at some pivot unknown to you beforehand. (i.e., 0 1 2 4 5 6 7 might become 4 5 6 7 0 1 2). Find the minimum element. You may assume no duplicate exists in the

【leetcode】Find Minimum in Rotated Sorted Array II JAVA实现

一.题目描述 Follow up for "Find Minimum in Rotated Sorted Array":What if duplicates are allowed? Would this affect the run-time complexity? How and why? Suppose a sorted array is rotated at some pivot unknown to you beforehand. (i.e., 0 1 2 4 5 6 7 m

【leetcode】939. Minimum Area Rectangle

题目如下: Given a set of points in the xy-plane, determine the minimum area of a rectangle formed from these points, with sides parallel to the x and y axes. If there isn't any rectangle, return 0. Example 1: Input: [[1,1],[1,3],[3,1],[3,3],[2,2]] Output

【leetcode】995. Minimum Number of K Consecutive Bit Flips

题目如下: In an array A containing only 0s and 1s, a K-bit flip consists of choosing a (contiguous) subarray of length K and simultaneously changing every 0 in the subarray to 1, and every 1 in the subarray to 0. Return the minimum number of K-bit flips