Given two integers n and k, return all possible combinations of k numbers out of 1 ... n. For example, If n = 4 and k = 2, a solution is: [ [2,4], [3,4], [2,3], [1,2], [1,3], [1,4], ]
有整数从1到n,问从中任选两个数有多少排列组合的结果(顺序无关)面试
这题实际上是动态编码的一个题目,能够经过链表实现队列存储前一种状况。再在前一种状况下继续下一轮的遍历,并将结果添加到队列末尾。代码以下:数组
public List<List<Integer>> combine(int n, int k) { List<List<Integer>> result = new LinkedList<List<Integer>>(); if(k==0){ return result; } for(int i = 0 ; i+k<=n ; i++){ result.add(Arrays.asList(i+1)); } while(result.get(0).size() != k){ List<Integer> currentList = result.remove(0); for(int i = currentList.get(currentList.size()-1) + 1 ; i<=n ; i++){ List<Integer> temp = new ArrayList<Integer>(currentList); temp.add(i); result.add(temp); } } return result; }
可是在这里存在超时问题,归根结底在于每一次都要建立新的数组用来保存临时结果,既占用内存又影响效率。微信
其实,经过递归的方法咱们也能够在前一轮的基础上进行下一轮的计算。递归代码以下:编码
public List<List<Integer>> combine2(int n, int k){ List<List<Integer>> result = new ArrayList<List<Integer>>(); if(k==0) return result; combine2(result, new ArrayList<Integer>(), 1, n, k); return result; } public void combine2(List<List<Integer>> currentResult, List<Integer> list, int start, int n, int k){ if(k==0){ currentResult.add(new ArrayList<Integer>(list)); return; } while(start+k-1<=n){ list.add(start++); combine2(currentResult, list, start, n, k-1); list.remove(list.size()-1); } }
想要了解更多开发技术,面试教程以及互联网公司内推,欢迎关注个人微信公众号!将会不按期的发放福利哦~spa