For the recursive function, it can be optimized a little. Say that the sorted cand is [1, 1, 2, 5, 6, 7, 10] and the target is 8. The add and remove can be regard as a stack process. In your code, we add 1, 1, 2 and 5 in the path but find target now < 0. So we remove 5 and add 6 in the path. Still we will find target < 0 and we remove 6 and add 7...... Here we can see that once we add cand[i] which makes the target < 0, the numbers behind cand[i], namelycand[i+1 ... n-1] can be just skipped and not added in the path. Hence we can just add a if clause before we add a number to the path. Moreover, since the target can never be negative so we can remove if (target < 0) return;. The code is as below:

void dfs_com(int[] cand, int cur, int target, List<Integer> path, List<List<Integer>> res) { if (target == 0) { res.add(new ArrayList(path)); return ; } for (int i = cur; i < cand.length; i++){ if (i > cur && cand[i] == cand[i-1]) continue; if (target-cand[i] < 0) break; path.add(path.size(), cand[i]); dfs_com(cand, i+1, target - cand[i], path, res); path.remove(path.size()-1); } }Combination Sum II