JAVA recursion with memoization
\nclass Solution {\n    char[][] map;\n    public int minimumDistance(String word) {\n        map = new char[][] {\n            {\'A\', \'B\', \'C\', \'D\', \'E
```\nclass Solution {\n    char[][] map;\n    public int minimumDistance(String word) {\n        map = new char[][] {\n            {\'A\', \'B\', \'C\', \'D\', \'E\', \'F\'},\n            {\'G\', \'H\', \'I\', \'J\', \'K\', \'L\'},\n            {\'M\', \'N\', \'O\', \'P\', \'Q\', \'R\'},\n            {\'S\', \'T\', \'U\', \'V\', \'W\', \'X\'},\n            {\'Y\', \'Z\'}\n        };\n        return dfs(word, 0, null, null);\n    }\n    \n    Map<String, Integer> res = new HashMap();\n    \n    int dfs(String word, int start, int[] L, int[] R) {\n        if (start >= word.length()) return 0;\n        String key = getKey(start, L, R);\n        if (res.containsKey(key)) return res.get(key);\n        char curr = word.charAt(start);\n        int currI = (curr-\'A\')/6;\n        int currJ = (curr-\'A\')%6;\n        \n        int useLeft = dfs(word, start+1, new int[]{currI, currJ}, R) + distance(L, currI, currJ);\n        int useRight = dfs(word, start+1, L, new int[]{currI, currJ}) + distance(R, currI, currJ);\n        int ans = Math.min(useLeft, useRight);\n        res.put(key, ans);\n        return ans;\n    }\n    \n    String getKey(int start, int[] L, int[] R) {\n        return start+"#"+Arrays.toString(L)+Arrays.toString(R);\n    }\n    \n    int distance(int[] finger, int i, int j) {\n        if (finger == null) return 0;\n        return Math.abs(finger[0]-i) + Math.abs(finger[1]-j);\n    }\n}\n```
[]