LeetCode 1320. Minimum Distance to Type a Word Using Two Fingers - DP

36 篇文章 0 订阅
30 篇文章 1 订阅

题目链接: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).@pfdvnah

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.

题解

输入一个字符有两种情况:左指输入,右指输入。@wowpH
每次输入时的两指有 26×26 种情况当要输入一个字符时,遍历这 26×26 种情况,在加上当前移动的距离即可得到当前情况的总距离。以此推出所有字符的总距离。

用一个三维数组 dp[i][L][R] 表示输入第 i 个字符后,左指在键位 L 的位置,右指在键位 R 的位置时的已经移动的总距离。

例如:输入的字符串为 CAKE
dp[1][2][R] 表示左指输入 C ,右指在键位 R 时的总距离。在左指输入 C 之前,左指有26种情况,右指也有26种情况,由于是左指输入,所以右指位置不影响此次结果,显然当左指在 C 键位时输入 C 是最小距离为0(dp[1][2][R] = dp[0][2][R] + distance(2, 2)

状态转移方程:
左指: d p [ i ] [ v ] [ R ] = d p [ i − 1 ] [ L ] [ R ] + d i s t a n c e ( L , v ) dp[i][v][R] = dp[i - 1][L][R] + distance(L, v) dp[i][v][R]=dp[i1][L][R]+distance(L,v)
右指: d p [ i ] [ L ] [ v ] = d p [ i − 1 ] [ L ] [ R ] + d i s t a n c e ( R , v ) dp[i][L][v] = dp[i - 1][L][R] + distance(R, v) dp[i][L][v]=dp[i1][L][R]+distance(R,v)

v v v 表示当前字符, d i s t a n c e ( a , b ) distance(a, b) distance(a,b) 表示从键位 a a a 到键位 b b b 移动的距离。

时间复杂度:三层for循环, O ( N ∗ 26 ∗ 26 ) O(N*26*26) O(N2626)
空间复杂度 O ( 1 ) O(1) O(1)

Java代码

// 2020-1-15 12:14:33
class Solution {
	public int minimumDistance(String word) {
		int[][][] dp = new int[300][26][26];
		// 输入0个字符的时候距离为0,不用赋值为Integer.MAX_VALUE
		for (int i = 1; i < 300; ++i) {
			for (int L = 0; L < 26; ++L) {
				for (int R = 0; R < 26; ++R) {
					dp[i][L][R] = Integer.MAX_VALUE;// 初始化为最大值
				}
			}
		}

		char[] arr = word.toCharArray();// 转成数组
        int v = 0;
		// 遍历所有字符
		for (int i = 1; i <= arr.length; ++i) {
			v = arr[i - 1] - 'A';
			// 遍历左指所在的键位
			for (int L = 0; L < 26; ++L) {
				// 遍历右指所在的键位
				for (int R = 0; R < 26; ++R) {
					// 检查手指的这种情况是否存在
					if (dp[i - 1][L][R] != Integer.MAX_VALUE) {
						// 移动左指
						dp[i][v][R] = Math.min(dp[i][v][R],
								dp[i - 1][L][R] + distance(L, v));
						// 移动右指
						dp[i][L][v] = Math.min(dp[i][L][v],
								dp[i - 1][L][R] + distance(R, v));
					}
				}
			}
		}
        
		int res = Integer.MAX_VALUE;
        for (int L = 0; L < 26; ++L) {
            for (int R = 0; R < 26; ++R) {
            	// 最后一个字符由左指输入
                res = Math.min(res, dp[arr.length][v][R]);
                // 最后一个字符由右指输入
                res = Math.min(res, dp[arr.length][L][v]);
            }
        }

		return res;
	}

	// 计算距离
	private int distance(int a, int b) {
		return Math.abs(a / 6 - b / 6) + Math.abs(a % 6 - b % 6);
	}
}

原文链接:https://blog.csdn.net/pfdvnah/article/details/103984775

- End - wowpH - pfdvnah -
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值