總結一下遞迴的幾種列舉方法
1.列舉子集:給定乙個可能包含重複元素的整數陣列 nums,返回該陣列所有可能的子集(冪集).
遞迴思路: 對陣列裡的數依次判斷選或者不選,當所有數判斷完之後就構成一種結果。
如果陣列裡有重複元素怎麼辦?
對同一層中重複的數字取一次就好了,if (i > start && nums[i] == nums[i - 1]) contiue;不要忘了排序.
時間複雜度:2^n * n 一共有2的n次方種狀態,每種狀態遞迴n層.
void dfs(int nums, int start, arraylisttemp, list> ans)
temp.add(nums[i]);
dfs(nums, i + 1, temp, ans);
temp.remove(temp.size() - 1);
}}
2.組合型列舉:n個元素裡選k個
遞迴思路:和列舉子集的思路相同,加上剪枝判斷即可
時間複雜度:n裡面選k種的狀態數*以k
void dfs(int cur, int n, int k)
// 記錄合法的答案
if (temp.size() == k)
for(int i=cur;i<=n;i++)
}
3.全排列
遞迴思路:列舉每個位置能存放哪些數.並用標記陣列標記
如果陣列中有重複數字:加上if(i>0&&nums[i]==nums[i-1]&&!used[i-1])
解釋:當出現重複情況時,兩個相等的數字nums[i]和nums[i-1]在同一遞迴層中,此時 used[i-1]一定為false,但其實已經訪問過這種情況了,只不過回溯的時候又置為false.
如果used[i-1]為true,那肯定不是在同一遞迴層中.
時間複雜度:n*n!
void dfs(int cur,int nums, listpath,boolean used)
for(int i=0;i0&&nums[i]==nums[i-1]&&!used[i-1]) ) continue;
path.add(nums[i]);
used[i]=true;
dfs(cur+1,nums,path,used);
used[i]=false;
path.remove(path.size()-1);
}
}
遞迴 指數列舉 排列列舉
題目描述 從 1 n這 n n 16 個整數中隨機選取任意多個,輸出所有可能的選擇方案。輸入描述 乙個整數n。輸出描述 每行一種方案。同一行內的數必須公升序排列,相鄰兩個數用恰好1個空格隔開。對於沒有選任何數的方案,輸出空行。本題有自定義校驗器 spj 各行 不同方案 之間的順序任意。輸入 輸出3 ...
Swift 遞迴列舉
話不多說,先放上swift 學習得 今天學swift 到了遞迴列舉得 主要記錄一下學到得問題 如下 indirect enum arithmeticexpressionindirect 表示 列舉型別arithmeticexpression 得成員都是可遞迴得 let five arithmetic...
遞迴 92 遞迴實現指數型列舉
從 1 n 這 n 個整數中隨機選取任意多個,輸出所有可能的選擇方案。輸入格式 輸入乙個整數n。輸出格式 每行輸出一種方案。同一行內的數必須公升序排列,相鄰兩個數用恰好1個空格隔開。對於沒有選任何數的方案,輸出空行。本題有自定義校驗器 spj 各行 不同方案 之間的順序任意。資料範圍 1 n 151...