I posted my recursive solution here, which took 232ms. The thought is straightforward: combinationSum of n = [19] + combinationSum of n1, where [19] means one element between 1 and 9.
Step by step:

The base case is when k = 1, if n is within [19] then we could directly return this n. Otherwise return an empty list.

Find maximum value used so far, which is stored in param "usedInt". I call it max.

Start from max till 9, for each element we get a list of combinations. Add this element to each combination, then return result.

IMPORTANT: I used HashSet here to eliminate possible duplicates. Before that, we need to sort each combination, i.e. insert element into its appropriate position. You can refer to the code below commented by "sort each list" and "remove duplicate".

I AM NOT SATISFIED WITH MY CODE in terms of its length and thought. It is too long, and might be optimized by backtracking. However I am not sure how to do that. If anybody could help me figure out how to implement backtracking, or give a brief explanation, I will very appreciate it. Thank you:)
public class Solution {
public List<List<Integer>> combinationSum3(int k, int n) {
List<List<Integer>> sets = new ArrayList<List<Integer>>();
if (k <= 0  n < 1  n > 45)
return sets;
HashSet<Integer> usedInt = new HashSet<Integer>();
List<List<Integer>> hasRepeat = combinationSum3(k, n, usedInt);
// remove duplicate
HashSet<List<Integer>> noRepeat = new HashSet<List<Integer>>();
noRepeat.addAll(hasRepeat);
sets.addAll(noRepeat);
return sets;
}
private List<List<Integer>> combinationSum3(int k, int n,
HashSet<Integer> usedInt) {
List<List<Integer>> sets = new ArrayList<List<Integer>>();
// base case
if (k == 1 && n >= 1 && n <= 9 && !usedInt.contains(n)) {
List<Integer> set = new ArrayList<Integer>();
set.add(n);
sets.add(set);
return sets;
}
if (k == 1  n < 1) return sets;
// find maximum value used so far
int max = 0;
Iterator<Integer> it = usedInt.iterator();
while (it.hasNext()) {
int val = it.next();
if (val > max) max = val;
}
// recursion
for (int i = max + 1; i <= 9; i++) {
HashSet<Integer> copy = (HashSet<Integer>) usedInt.clone();
copy.add(i);
List<List<Integer>> temp = combinationSum3(k  1, n  i, copy);
for (int j = 0; j < temp.size(); j++) {
// sort each list
int index = 0;
for (; index < temp.get(j).size(); index++)
if (temp.get(j).get(index) > i) break;
temp.get(j).add(index, i);
}
// remove duplicate
if (!temp.isEmpty()) {
HashSet<List<Integer>> noRepeat = new HashSet<List<Integer>>();
noRepeat.addAll(temp);
sets.addAll(noRepeat);
}
}
return sets;
}
}