public void dfs(int[] candidates, int begin, List<List<Integer>> result,
            List<Integer> temp, int sum, int target) {
        if (sum > target)
            return;
        if (sum == target) {
            result.add(new ArrayList<Integer>(temp));
            return;
        }
        for (int i = begin; i < candidates.length; ++i) {
            int num = candidates[i];
            temp.add(num);
            // make it much faster
            if (sum + num > target)
                break;
            dfs(candidates, i, result, temp, sum + num, target);
            temp.remove(temp.size() - 1);
        }
    }