LeetCode筆記——77組合
題目:
給定兩個整數 n 和 k,返回 1 ... n 中所有可能的 k 個數的組合。
示例:
輸入: n = 4, k = 2 輸出: [ [2,4], [3,4], [2,3], [1,2], [1,3], [1,4], ]
思路:以下參考了網上大神的程式碼,原文連結:https://blog.csdn.net/happyaaaaaaaaaaa/article/details/51564160
是一個遞迴實現的問題,有一點深度優先搜尋的意思。遞迴的返回條件是k==0,即找到了長度為K的一個組合,將其加入到結果集中,並且在temp中刪除。
程式碼:
class Solution { public List<List<Integer>> combine(int n, int k) { List<List<Integer>> res = new ArrayList<List<Integer>>(); List<Integer> temp = new ArrayList<Integer>(); dfs(res, temp, n, k, 1); return res; } private void dfs(List<List<Integer>> res, List<Integer> temp, int n, int k, int m) { if(k == 0) { //遞迴結束條件 res.add(new ArrayList<Integer>(temp)); return; } for(int i=m; i<=n; i++) { temp.add(i); //將第一個元素新增進temp dfs(res, temp, n, k-1, i+1); //遞迴呼叫,從i+1開始,避免重複 temp.remove(temp.size()-1); //取出原先儲存的組合,重新開始 }
} }
以下這兩個思路一致,只不過多加了一個判斷條件。
提交最多的程式碼:
class Solution { public List<List<Integer>> combine(int n, int k) { List<List<Integer>> res = new ArrayList<List<Integer>>(); if(k>n) return res; List<Integer> list = new ArrayList<Integer>(); getPass(n, k, list, res, 1); return res; } public void getPass(int n, int k, List<Integer> list, List<List<Integer>> res, int start){ if(list.size() == k){ res.add(new ArrayList<Integer>(list)); return; } int len = list.size(); for(int i=start;i<=n;i++){ if(n-i<(k-len-1)) return; list.add(i); getPass(n, k, list, res, i+1); list.remove(list.size()-1); } } }
執行最快的程式碼:
class Solution { public List<List<Integer>> combine(int n, int k) { List<List<Integer>> res = new ArrayList<List<Integer>>(); if(k>n) return res; List<Integer> list = new ArrayList<Integer>(); getPass(n, k, list, res, 1); return res; } public void getPass(int n, int k, List<Integer> list, List<List<Integer>> res, int start){ if(list.size() == k){ res.add(new ArrayList<Integer>(list)); return; } int len = list.size(); for(int i=start;i<=n;i++){ if(n-i<(k-len-1)) return; list.add(i); getPass(n, k, list, res, i+1); list.remove(list.size()-1); } } }