LeetCode 1320. 二指输入的的最小距离

这篇博客探讨了如何解决LeetCode上的1320题,即在二指输入的情况下,输入一个单词所需的最小移动距离。博主介绍了动态规划(dp)的思路,其中dp状态表示已输入字符后的两手手指最小移动距离,并说明了初始状态设定为dp[-1][所有位置1][所有位置2]=0,表示未输入任何字符的情况。
摘要由CSDN通过智能技术生成

https://leetcode-cn.com/problems/minimum-distance-to-type-a-word-using-two-fingers/

dp【位置】【手指1 x】【手指1 y】【手指2 x】【手指2 y】,表示已输入该位置后的字符后两只手指所在的位置所用最小的移动距离。由于最开始的时候手指可以位于任何地方,所以dp[-1][所有位置1][所有位置2]=0,未输入任何字符,所以是-1。

由于每次都可以由左手或右手输入。

 

class Solution {
public:
    vector<string> keyboard;
    
    map<char,pair<int,int>> charpos_map;
    
    int dp[305][5][6][5][6];
    
    const int INF=0x3f3f3f3f;
    
    void init(){
        keyboard.push_back("ABCDEF");
        keyboard.push_back("GHIJKL");
        keyboard.push_back("MNOPQR");
        keyboard.push_back("STUVWX");
        keyboard.push_back("YZ");
        
        for(int i=0;i<keyboard.size();i++){
            for(int j=0;j<keyboard[i].size();j++){
                charpos_map[keyboard[i][j]]=make_pair(i,j);
            }
        }
        
        memset(dp,0x3f,sizeof(dp));
    }
    
    int dist(int x1,int y1,int x2,int y2){
        return abs(x1-x2)+abs(y1-y2);
    }
    
    int minimumDistance(string word) {
        init();
        int n_row=5;
        int n_col=6;
        
        for(int i=0;i<word.size();i++){
            for(int x1=0;x1<n_row;x1++){
                for(int y1=0;y1<n_col;y1++){
                    for(int x2=0;x2<n_row;x2++){
                        for(int y2=0;y2<n_col;y2++){
                            auto new_pos=charpos_map[word[i]];
                            int new_x=new_pos.first;
                            int new_y=new_pos.second;
                            if(i-1<0){
                                dp[i][new_x][new_y][x2][y2]=min(dp[i][new_x][new_y][x2][y2],dist(new_x,new_y,x1,y1));
                                dp[i][x1][y1][new_x][new_y]=min(dp[i][x1][y1][new_x][new_y],dist(new_x,new_y,x2,y2));
                            }
                            else{
                                dp[i][new_x][new_y][x2][y2]=min(dp[i][new_x][new_y][x2][y2],dp[i-1][x1][y1][x2][y2]+dist(new_x,new_y,x1,y1));
                                dp[i][x1][y1][new_x][new_y]=min(dp[i][x1][y1][new_x][new_y],dp[i-1][x1][y1][x2][y2]+dist(new_x,new_y,x2,y2));
                            }
                        }
                    }
                }
            }
        }
        
        int ans=INT_MAX;
        auto pos=charpos_map[word[word.size()-1]];
        int end_x=pos.first;
        int end_y=pos.second;
        for(int x=0;x<n_row;x++){
            for(int y=0;y<n_col;y++){
                ans=min(ans,dp[word.size()-1][x][y][end_x][end_y]);
                ans=min(ans,dp[word.size()-1][end_x][end_y][x][y]);
            }
        }
        return ans;
    }
};

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值