Python | 81% speed | Intuitive | O(676 * |word|) | Recursion + Memo
```\nclass Solution:\n    def minimumDistance(self, word: str) -> int:\n        locations = {}\n        x, y = 0, 0\n        for i in range(65, 91):\n          
```\nclass Solution:\n    def minimumDistance(self, word: str) -> int:\n        locations = {}\n        x, y = 0, 0\n        for i in range(65, 91):\n            locations[chr(i)] = (x, y)\n            y += 1\n            if y > 5:\n                x += 1\n                y = 0\n        \n        #print(locations)\n        @lru_cache(None)\n        def func(idx, f1, f2):\n            if idx == len(word):\n                return 0\n            \n            # use f1\n            if f1 == \'\':\n                x1, y1 = locations[word[idx]]\n            else:\n                x1, y1 = locations[f1]\n                \n            x, y = locations[word[idx]]\n            dist1 = abs(x1 - x) + abs(y1 - y)\n            useF1 = dist1 + func(idx + 1, word[idx], f2)\n            \n            if f2 == \'\':\n                x2, y2 = locations[word[idx]]\n            else:\n                x2, y2 = locations[f2]\n                \n            dist2 = abs(x2 - x) + abs(y2 - y)\n            useF2 = dist2 + func(idx + 1, f1, word[idx])\n            \n            return min(useF1, useF2)\n        \n        return func(0, \'\', \'\')
['Recursion', 'Memoization', 'Python', 'Python3']