每天一題LeetCode【第34天】

T47. Permutations II【Medium

題目

給出一個可以包含重復(fù)數(shù)字的數(shù)字集隅居,返回所有可能的不重復(fù)排列組合。

例如瞎惫,
[1,1,2] 有如下的排列組合:

[
  [1,1,2],
  [1,2,1],
  [2,1,1]
]

思路

這題的大體想法和上題一樣溜腐,不過除了遞歸译株,這題還要對重復(fù)怎么判斷進行處理,以及防止重復(fù)排列組合的出現(xiàn)挺益。

① 遞歸

思路和上一題差不多歉糜,如下:

排列組合(1 2 3)
= 1 + 排列組合(2 3)∪ 2 + 排列組合(1 3)∪ 3 + 排列組合(1 2)
排列組合(2 3)
= 2 + 排列組合(3)∪ 3 + 排列組合(2)
= 23 ∪ 32 

可以看出在數(shù)字只有一個的時候到了遞歸的終點

② 重復(fù)判別

上一題是直接看這個數(shù)有沒有用過,那是基于這個數(shù)只出現(xiàn)一遍望众,而在這題可以出現(xiàn)重復(fù)的數(shù)字這個方法就不可用了匪补。這個 Solution 用了什么解決方法呢,看下面:

boolean[] used = new boolean[nums.length];

建立了一個 boolean 的數(shù)組和 nums 中的數(shù)一一對應(yīng),然后用

used[i]=true;
used[i]=false;

的設(shè)置來表示這個數(shù)是否用過

然后用在循環(huán)中加入下面的語句來跳過用過的數(shù)字

if(used[i]) continue;

③ 排除重復(fù)排列組合

造成重復(fù)排列組合的原因可以動手寫一下看看~

避免這種重復(fù)的方法在于后面重復(fù)的數(shù)不能排在前面重復(fù)的數(shù)前面(可能有點繞烂翰,最好動手寫寫看)夯缺。

代碼則是很簡單,像下面這樣:

if(i>0 &&nums[i-1]==nums[i] && !used[i-1]) continue;

因為已經(jīng)排好序了刽酱,所以若 nums[i-1]==nums[i] 和 !used[i-1] 則代表它之前的重復(fù)的數(shù)沒有被用到喳逛,這時,跳過這次循環(huán)棵里,因為它也不應(yīng)該被用润文。

另外,不能寫成

if(i>0 &nums[i-1]==nums[i] & !used[i-1]) continue;

可以想一下原因~我在補充里說殿怜!

代碼

代碼取自 Top Solution典蝌,稍作注釋

public List<List<Integer>> permuteUnique(int[] nums) {
        //建立要返回的數(shù)據(jù)形式
        List<List<Integer>> res = new ArrayList<List<Integer>>();
        //若為空,直接返回
        if(nums==null || nums.length==0) return res;
        //建立 used 數(shù)組來判斷這個數(shù)字是否用過
        boolean[] used = new boolean[nums.length];
        List<Integer> list = new ArrayList<Integer>();
        //排序
        Arrays.sort(nums);
        dfs(nums, used, list, res);
        return res;
    }

public void dfs(int[] nums, boolean[] used, List<Integer> list, List<List<Integer>> res){
        //若所有元素都用到了(達到長度)則加到 ArrayList 里面
        if(list.size()==nums.length){
            res.add(new ArrayList<Integer>(list));
            return;
        }
        for(int i=0;i<nums.length;i++){
            //若用到過這個數(shù)字了,則跳過本次循環(huán)
            if(used[i]) continue;
            //用這句來避免重復(fù)
            if(i>0 &&nums[i-1]==nums[i] && !used[i-1]) continue;
            //設(shè)置為true代表已經(jīng)用過
            used[i]=true;
            //下面四行是遞歸,看和上一題差不多,看"思路"里
            list.add(nums[i]);
            dfs(nums,used,list,res);
            used[i]=false;
            list.remove(list.size()-1);
        }
    } 

補充

關(guān)于

if(i>0 &&nums[i-1]==nums[i] && !used[i-1]) continue;

為什么要用 "&&" 而不用 "&"?

我們可以嘗試先把 "&&" 改成 "&",然后發(fā)現(xiàn)會報錯头谜!

為什么呢骏掀?我的編譯器不愛我了嗎?

這要先講一下兩者的區(qū)別:

&&和&都是表示與柱告,區(qū)別是&&只要第一個條件不滿足截驮,后面條件就不再判斷。而&要對所有的條件都進行判斷际度。

因為當(dāng)用了 && 時葵袭,執(zhí)行 i>0 為 false 時就不往下執(zhí)行了,而用 & 時會把這三個都執(zhí)行一遍乖菱,在執(zhí)行

nums[i-1]==nums[i]

的時候 nums[i-1] 是 nums[-1],會報 ArrayIndexOutOfBoundsException 的錯誤坡锡。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市窒所,隨后出現(xiàn)的幾起案子鹉勒,更是在濱河造成了極大的恐慌,老刑警劉巖吵取,帶你破解...
    沈念sama閱讀 211,194評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件禽额,死亡現(xiàn)場離奇詭異,居然都是意外死亡海渊,警方通過查閱死者的電腦和手機绵疲,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,058評論 2 385
  • 文/潘曉璐 我一進店門哲鸳,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人盔憨,你說我怎么就攤上這事徙菠。” “怎么了郁岩?”我有些...
    開封第一講書人閱讀 156,780評論 0 346
  • 文/不壞的土叔 我叫張陵婿奔,是天一觀的道長。 經(jīng)常有香客問我问慎,道長萍摊,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,388評論 1 283
  • 正文 為了忘掉前任如叼,我火速辦了婚禮冰木,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘笼恰。我一直安慰自己踊沸,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 65,430評論 5 384
  • 文/花漫 我一把揭開白布社证。 她就那樣靜靜地躺著逼龟,像睡著了一般。 火紅的嫁衣襯著肌膚如雪追葡。 梳的紋絲不亂的頭發(fā)上腺律,一...
    開封第一講書人閱讀 49,764評論 1 290
  • 那天,我揣著相機與錄音宜肉,去河邊找鬼匀钧。 笑死,一個胖子當(dāng)著我的面吹牛谬返,可吹牛的內(nèi)容都是我干的榴捡。 我是一名探鬼主播,決...
    沈念sama閱讀 38,907評論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼朱浴,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了达椰?” 一聲冷哼從身側(cè)響起翰蠢,我...
    開封第一講書人閱讀 37,679評論 0 266
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎啰劲,沒想到半個月后梁沧,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,122評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡蝇裤,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,459評論 2 325
  • 正文 我和宋清朗相戀三年廷支,在試婚紗的時候發(fā)現(xiàn)自己被綠了频鉴。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,605評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡恋拍,死狀恐怖垛孔,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情施敢,我是刑警寧澤周荐,帶...
    沈念sama閱讀 34,270評論 4 329
  • 正文 年R本政府宣布,位于F島的核電站僵娃,受9級特大地震影響概作,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜默怨,卻給世界環(huán)境...
    茶點故事閱讀 39,867評論 3 312
  • 文/蒙蒙 一讯榕、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧匙睹,春花似錦愚屁、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,734評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至谆棺,卻和暖如春栽燕,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背改淑。 一陣腳步聲響...
    開封第一講書人閱讀 31,961評論 1 265
  • 我被黑心中介騙來泰國打工碍岔, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人朵夏。 一個月前我還...
    沈念sama閱讀 46,297評論 2 360
  • 正文 我出身青樓蔼啦,卻偏偏與公主長得像,于是被迫代替她去往敵國和親仰猖。 傳聞我的和親對象是個殘疾皇子捏肢,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,472評論 2 348

推薦閱讀更多精彩內(nèi)容

  • 背景 一年多以前我在知乎上答了有關(guān)LeetCode的問題, 分享了一些自己做題目的經(jīng)驗。 張土汪:刷leetcod...
    土汪閱讀 12,737評論 0 33
  • LeetCode 刷題隨手記 - 第一部分 前 256 題(非會員)饥侵,僅算法題鸵赫,的吐槽 https://leetc...
    蕾娜漢默閱讀 17,738評論 2 36
  • 1. Java基礎(chǔ)部分 基礎(chǔ)部分的順序:基本語法,類相關(guān)的語法躏升,內(nèi)部類的語法辩棒,繼承相關(guān)的語法,異常的語法,線程的語...
    子非魚_t_閱讀 31,598評論 18 399
  • subset-DFS+Backtracking系列一睁,有模板方法可以記 例1:leetcode 78. Subse...
    暗黑破壞球嘿哈閱讀 5,839評論 1 3
  • "月嶺真是個苦命的女人"钻弄。同為服務(wù)員的老胡一邊擦著玻璃一邊跟我說著。 月嶺者吁,目前的工作是餐廳服務(wù)員窘俺,34歲,兩個孩...
    達文溪閱讀 261評論 0 1