摘要:寫這個(gè)系列是因?yàn)榧o(jì)念一下去年的今天,就是年的月號(hào),刷題第一天,今天是一周年紀(jì)念日。排除,就是返回一空的。復(fù)雜度分析算法課講過,這個(gè)復(fù)雜度是指數(shù)次,能實(shí)現(xiàn)出來就行了,沒法優(yōu)化。復(fù)雜度分析不分析了,反正指數(shù)次。
Subsets
寫這個(gè)系列是因?yàn)榧o(jì)念一下去年的今天,就是2015年的9月14號(hào),刷題第一天,今天是一周年紀(jì)念日。當(dāng)時(shí)只敢做easy還得抄答案的我想啥時(shí)候能做上medium啊,事到如今,感覺都不是啥障礙了,這道題也已經(jīng)做了第四遍了,抽出來的DFS遞歸模板放在這里總結(jié)一下。
這題內(nèi)容就是就是給個(gè)數(shù)組,里面的數(shù)字都是獨(dú)一無二的,把它所有的子集都輸出出來。
題目中給了個(gè)例子,比如[1,2,3],第一次抽出1,然后在1的基礎(chǔ)上加2,再加3。加完之后再往回返,去掉3,再去掉2,發(fā)現(xiàn)可以加3,形成[1,3],再到2,以此類推。
思路很容易,但是寫的時(shí)候需要用到遞歸的手法,這個(gè)還是需要點(diǎn)兒思維過程的,推薦用IDE的debug功能一步一步走走看。
public class Subsets { public List復(fù)雜度分析> subsets(int[] nums) { //先把輸出的東西擺上去。 List
> result = new ArrayList<>(); //排除corner case,就是返回一空的。 if(nums == null || nums.length == 0) return result; //這個(gè)就是用來搜集每個(gè)子集的。 List
list = new ArrayList<>(); dfs(result, list, 0, nums); return result; } public void dfs(List > result, List
list, int start, int[] nums){ //先把當(dāng)前的子集加上,這里添加的語法我命名為『照相法』 result.add(new ArrayList<>(list)); //注意這里要從start位置開始循環(huán),否則就是stackoverflow for(int i = start; i < nums.length; i++){ //添加start位置的數(shù)字 list.add(nums[i]); //開始遞歸,比如把1加上去之后,就穩(wěn)住1,找后面比如2. dfs(result, list, i+1, nums); //backtrack,就是把之前加上的去掉,相當(dāng)于往回走,比如之前加到1,2,3 //就把3去掉,然后再找。 list.remove(list.size()-1); } } }
算法課講過,這個(gè)復(fù)雜度是指數(shù)次,能實(shí)現(xiàn)出來就行了,沒法優(yōu)化。
最后再說兩句這題就是模板,DFS的模板,就是一個(gè)容器來回抓,容器的容器每次把這個(gè)容器記錄下來。還有遞歸的debug就是人工模仿IDE,一步一步走。
Subsets II稍有不同,就是數(shù)組里面的數(shù)字可能有重復(fù),同時(shí)要求子集輸出不能用重復(fù)的元素,一個(gè)非常典型的follow up。
解決思路重點(diǎn)在于判斷重復(fù)數(shù)字,把重復(fù)的情況跳過去。模板還是一樣的。
codepublic class SubsetsII { public List復(fù)雜度分析> subsetsWithDup(int[] nums) { List
> result = new ArrayList<>(); if(nums == null || nums.length == 0) return result; //這里就需要排序了,給以后跳過重復(fù)數(shù)字埋下伏筆 Arrays.sort(nums); //剩下都是一樣的 List
list = new ArrayList<>(); dfs(result, list, 0, nums); return result; } public void dfs(List > result, List
list, int start, int[] nums){ result.add(new ArrayList<>(list)); for(int i = start; i < nums.length; i++){ //關(guān)鍵就在這一句,每次循環(huán)起始的數(shù)字不能和之前重復(fù)。 if(i > start && nums[i] == nums[i-1]) continue; list.add(nums[i]); dfs(result, list, i+1, nums); list.remove(list.size()-1); } } }
不分析了,反正指數(shù)次。
最后再說兩句這里注意用好模板,循環(huán)的時(shí)候把起始的start寫成了0,直接就爆了。
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/65155.html
摘要:回溯算法在算法過程中就是類似于枚舉算法,嘗試在搜索過程中找到問題的解。 回溯算法( BackTrack )在算法過程中就是類似于枚舉算法,嘗試在搜索過程中找到問題的解。 使用回溯算法解題的一般步驟 使用回溯算法解題的一般步驟: 針對(duì)所給問題得出一般的解空間 用回溯搜索方法搜索解空間 使用深度優(yōu)先去搜索所有解并包含適當(dāng)?shù)募糁Σ僮? LeetCode 使用回溯算法的題目主要有 36 題,...
摘要:背包問題假設(shè)有個(gè)寶石,只有一個(gè)容量為的背包,且第個(gè)寶石所對(duì)應(yīng)的重量和價(jià)值為和求裝哪些寶石可以獲得最大的價(jià)值收益思路我們將個(gè)寶石進(jìn)行編號(hào),尋找的狀態(tài)和狀態(tài)轉(zhuǎn)移方程。我們用表示將前個(gè)寶石裝到剩余容量為的背包中,那么久很容易得到狀態(tài)轉(zhuǎn)移方程了。 Partition Equal Subset Sum Given a non-empty array containing only posi...
摘要:一集合是什么與它相關(guān)數(shù)學(xué)概念有哪些解題集合定義集合是一種包含不同元素的數(shù)據(jù)結(jié)構(gòu)。集合中的元素稱為成員,集合最重要的兩個(gè)特點(diǎn)集合中的成員是無序集合中不存在相同成員即無序且唯一。 showImg(https://segmentfault.com/img/remote/1460000019005270); 這是第四周的練習(xí)題,五一放假結(jié)束,該收拾好狀態(tài)啦。 下面是之前分享的鏈接: ...
Subsets Problem Given a set of distinct integers, return all possible subsets. Notice Elements in a subset must be in non-descending order.The solution set must not contain duplicate subsets. Example ...
摘要:題目要求類似的題目有可以參考這篇博客可以參考這篇博客思路一遞歸還是利用遞歸的方式,在前一種情況的基礎(chǔ)上遍歷下一輪的組合情況。 題目要求 Given a set of distinct integers, nums, return all possible subsets. Note: The solution set must not contain duplicate subset...
閱讀 3441·2023-04-25 23:25
閱讀 2069·2021-11-12 10:36
閱讀 2816·2019-08-30 12:47
閱讀 2037·2019-08-29 18:45
閱讀 435·2019-08-29 17:28
閱讀 1785·2019-08-29 17:15
閱讀 1707·2019-08-29 16:05
閱讀 1405·2019-08-29 14:17