[Java] Backtracking solution passed with pruning
Idea:\n Having k buckets and using recursion to try every buckets.\n Using TreeSet to be the bucket data structure so that we can get minimum and maximum value 
Idea:\n* Having `k` buckets and using recursion to try every buckets.\n* Using `TreeSet` to be the bucket data structure so that we can get minimum and maximum value in the bucket quickly.\n\nThe original solution without pruning cannot pass because of TLE. So two pruning ideas to improve the performance:\n1. If the current accumulated incompatibility has been over the known global minimum incompatibility, then prune this branch.\n2. The current number should be placed into empty buckets only for once.\n\n```\nclass Solution {\n    private int global = Integer.MAX_VALUE;\n    public int minimumIncompatibility(int[] nums, int k) {\n        int n = nums.length;\n        if (n % k != 0) {\n            return -1;\n        }\n        int s = n / k;\n        List<TreeSet<Integer>> buckets = new ArrayList<>();\n        for (int i = 0; i < k; i++) {\n            buckets.add(new TreeSet<>());\n        }\n        return helper(nums, 0, buckets, s, k);\n    }\n    \n    // TLE without pruning.\n    private int helper(int[] nums, int pos, List<TreeSet<Integer>> subsets, int s, int k) {\n        int n = nums.length;\n        if (pos == n) {\n            int res = 0;\n            for (TreeSet<Integer> subset : subsets) {\n                res += subset.last() - subset.first();\n            }\n            global = Math.min(global, res);\n            return res;\n        }\n        int ans = Integer.MAX_VALUE;\n        int current = 0;\n        for (int i = 0; i < subsets.size(); i++) {\n            TreeSet<Integer> subset = subsets.get(i);\n            if (subset.size() == s) {\n                current += subset.last() - subset.first();\n            }\n            // Prune 1: if the current approach have already passed the known minimum, then break;\n            if (current > global) {\n                break;\n            }\n            // Prune 2: number will only try one empty bucket.\n            if (i - 1 >= 0 && subsets.get(i - 1).isEmpty()) {\n                break;\n            }\n            if (!subset.contains(nums[pos]) && subset.size() < s) {\n                subset.add(nums[pos]);\n                int res = helper(nums, pos + 1, subsets, s, k);\n                if (res != -1) {\n                    ans = Math.min(ans, res);\n                }\n                subset.remove(nums[pos]);\n            }\n        }\n        if (ans == Integer.MAX_VALUE) {\n            return -1;\n        }\n        return ans;\n    }\n}\n```
[]