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.

思路:记忆化搜索,top down dp,两个手指move,可以写一个cost function计算两个点的cost,这个没有问题,那么问题转换成下一个move由谁来完成,cost分别是多少。top down就是最后一步,如果由左边完成,cost + dfs(左边), 由右边完成,cost + dfs(右边)建立一个三维的dp,[leftindex][rightindex][pos in word]来标记计算过的结果;Time ( n * 27 ^ 2); Space ( n * 27 ^ 2);

class Solution {
    public int minimumDistance(String word) {
        if(word == null || word.length() == 0) {
            return 0;
        }
        int n = word.length();
        int[][][] dp = new int[27][27][n]; // 27,只是为了char为null的时候,index可以包含null的情况,设置为0;
        return dfs(word, 0, dp, null, null);// 刚开始设置为null,这样两个指头走上第一char的时候,cost 会return 0;
    }
    
    private int dfs(String word, int index, int[][][] dp, Character c1, Character c2) {
        if(index == word.length()) {
            return 0;
        }
        int index1 = c1 == null ? 0 : c1 - 'A' + 1;
        int index2 = c2 == null ? 0 : c2 - 'A' + 1;
        if(dp[index1][index2][index] != 0) {
            return dp[index1][index2][index];
        } 
        
        char next = word.charAt(index);
        dp[index1][index2][index] = Math.min(cost(c1, next) + dfs(word, index+1, dp, next, c2),
                                            cost(c2, next) + dfs(word, index+1, dp, c1, next));
        return dp[index1][index2][index];
    }
    
    private int cost(Character c1, Character c2) {
        if(c1 == null || c2 == null) {
            return 0;
        }
        int len1 = c1 - 'A'; int len2 = c2 - 'A';
        int x1 = len1 / 6; int x2 = len2 / 6;
        int y1 = len1 % 6; int y2 = len2 % 6;
        return Math.abs(x1 - x2) + Math.abs(y1 - y2);
    }
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
手指姿势是一种非语言的身体语言,通过手指的动作,可以传达出一系列不同的含义和信息。手指姿势作为一种非语言交流方式,被广泛应用于各个领域。以下是手指姿势的几个主要应用领域: 首先,手指姿势在日常生活中具有重要意义。我们常常用手指做出各种姿势,例如通过做“OK”的手势表示“没问题”,或者用两个食指指向自己的眼睛,表示“看吧”。这些手势在日常生活中非常常见,帮助我们进行简单的交流和沟通。 其次,手指姿势在一些特定领域具有专业用途。例如,在音乐领域,指挥家通过手指姿势来指示乐团的演奏和节奏。在体育比赛中,裁判员通过特定的手势来传达出各种不同的判罚和比赛指示,这样运动员和观众就能够清楚地理解他们的意图。 此外,手指姿势在一些文化中也具有重要的象征意义。例如,在西方国家,竖起大拇指表示“赞成”或“顶”,而在东方国家,这个手势却可能被视为不礼貌或侮辱。在一些文化中,手指姿势还可以用来表示祝福、宣誓或祈祷等特定的含义。 总的来说,手指姿势是一种非常有力和灵活的交流方式,可以在不同的场景中传达各种不同的意义和信息。通过学习和理解手指姿势的含义,我们可以更好地与他人进行交流,并且更顺畅地融入到不同的文化和环境中。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值