Python | 2 solutions | 1 Brute force | 1 Memoization (AC)
In the first solution, we calculate all possible parition combinations, then we calculating all combinations of the parition combinations, calculate the agreeme
In the first solution, we calculate all possible parition combinations, then we calculating *all combinations of the parition combinations*, calculate the agreement, and update result to be the minimum of all our calculations.\n\nIn the second solution, we re-frame the problem as a tree search. Our recursive function contains this line,`for combo in itertools.combinations(nums, partition_len)`, which essentially loops over each possible parition, removes the parition from the array, and calls itself again to calculate a new parition. This is pretty much the same idea as before, except we do it recursively instead of iteratively. Furthermore, we add the `@functools.lru_cache(maxsize=None)` decorator to automatically add memoization to our solution.  One small note is we have to cast `nums` to a `tuple` as `lru_cache` requires functions to have immutable input.\n\n\n**Brute force**\n```\nclass Solution:\n    def minimumIncompatibility(self, nums: List[int], k: int) -> int:\n        \n        nums.sort()\n        \n        x = len(nums)//k\n        \n        combos = []\n        \n        for i in itertools.combinations(nums, x):\n            if len(set(i)) == x:\n                combos.append(i)\n                \n        result = float(\'inf\')\n                \n        for i in itertools.combinations(combos, k):                                          \n            if sorted([y for x in i for y in x]) == nums:                \n                score = sum([max(x) - min(x) for x in i])                \n                result = min(score, result)\n        \n        return result if result != float("inf") else -1\n```\n\n\n**Memoization**\n```\nclass Solution:\n    def minimumIncompatibility(self, nums: List[int], k: int) -> int:\n                        \n        partition_len = len(nums) // k        \n                \n        @functools.lru_cache(maxsize=None)\n        def recurse(nums):            \n            if not nums: return 0      \n            \n            result = float(\'inf\')\n            \n            for combo in itertools.combinations(nums, partition_len):                \n                \n                if len(set(combo)) < partition_len: continue\n                                                 \n                updated_nums = list(nums) \n                for i in combo:\n                    updated_nums.remove(i)\n                                    \n                result = min(\n                    result,\n                    max(combo) - min(combo) + recurse(tuple(updated_nums))\n                )\n                \n            return result\n        \n        result = recurse(tuple(nums))\n        \n        return result if result != float(\'inf\') else -1\n```
['Python', 'Python3']