leetcode77. Combinations

題目要求

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);
         }
     }

clipboard.png
想要了解更多開發技術,面試教程以及互聯網公司內推,歡迎關注個人微信公衆號!將會不按期的發放福利哦~spa

相關文章
相關標籤/搜索