40 組合總和 II

題目:

給定一個數(shù)組 candidates 和一個目標數(shù) target ,找出 candidates 中所有可以使數(shù)字和為 target 的組合。

說明:

  • 所有數(shù)字(包括目標數(shù))都是正整數(shù)。
  • 解集不能包含重復的組合。

示例:

  • 示例1

輸入: candidates = [10,1,2,7,6,1,5], target = 8,
所求解集為:
[
[1, 7],
[1, 2, 5],
[2, 6],
[1, 1, 6]
]

  • 示例2

輸入: candidates = [2,5,2,1,2], target = 5,
所求解集為:
[
[1,2,2],
[5]
]

解題思路

1. 首先組合總和問題想到用遞歸的方式求解,定義遞歸函數(shù)為dfs(pos, rest),其中pos表示我們當前遞歸到了數(shù)組 candidates[]中的第pos個數(shù)缕允,而rest表示我們還需要選擇和為rest的數(shù)放入列表作為一個組合。
?對于數(shù)組candidates[]中的每個元素蹭越,都有兩種選擇方式障本,要么選,要么不選响鹃。如果選擇candidates[pos]驾霜,那么遞歸子過程是dfs(pos + 1, rest - candidates[pos]),當然买置,必須滿足rest >= candidates[pos]粪糙。如果不選,則遞歸子過程是dfs(pos + 1, rest)忿项。
?在每次的遞歸開始前蓉冈,如果rest==0,說明target的組合已經(jīng)找到,將組合放入答案中轩触。每次調用遞歸函數(shù)前寞酿,如果我們選擇了那個數(shù),就需要將其放入到列表的末尾脱柱,該列表存儲了我們選擇的所有的數(shù)伐弹。在回溯時,如果我們選擇了那個數(shù)榨为,就要將其從列表的末尾刪除惨好。
注:本題的解集不能包含重復的組合煌茴,上述算法能去除重復解,比如candidates = [1,1]日川,target = 1蔓腐,那么就會將兩個1放入解集中
2. 因此在求出組合時,要增加去重操作逗鸣。將相同的數(shù)一起處理合住,將從candidates[]中拿數(shù)據(jù)改為從一個map(數(shù)绰精,出現(xiàn)次數(shù))中去拿數(shù)據(jù)撒璧,這樣就不會出現(xiàn)重復的解集。

代碼

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Stack;

/**
 * 組合總和2
 */
public class CombinationSum2 {

    /**
     * candidates中每個數(shù)出現(xiàn)的次數(shù)
     */
    List<int[]> freq = new ArrayList<int[]>();

    List<List<Integer>> ans = new ArrayList<List<Integer>>();

    List<Integer> sequence = new ArrayList<Integer>();

    /**
     * 組合總和2
     * @param candidates
     * @param target
     * @return
     */
    public List<List<Integer>> combinationSum2(int[] candidates, int target) {

        //從小到大排序笨使,遞歸時會選擇小的數(shù)卿樱,再選擇大的數(shù),如果選擇的數(shù)已經(jīng)大于rest硫椰,后面的數(shù)就減掉了
        Arrays.sort(candidates);
        for (int num : candidates){
            int size = freq.size();
            //排序以后 如果是相同的就加次數(shù) 不相同就加數(shù)繁调,次數(shù)為1
            if (freq.isEmpty() || num != freq.get(size - 1)[0]){
                freq.add(new int[]{num, 1});
            }else {
                ++freq.get(size - 1)[1];
            }
        }
        dfs(0, target);
        return ans;
    }

    /**
     * 從0位置開始,看余下的數(shù)
     */
    public void dfs(int pos, int rest){
        //如果余下的數(shù)為0靶草,說明正好湊好
        if (rest == 0){
            ans.add(new ArrayList<Integer>(sequence));
        }
        //如果走到了最后一位蹄胰,或者走到的位置已經(jīng)大于了rest,直接返回
        if (pos == freq.size() || rest < freq.get(pos)[0]){
            return;
        }
        //不選
        dfs(pos+1, rest);

        int most = Math.min(rest / freq.get(pos)[0], freq.get(pos)[1]);
        for (int i=1; i<=most; ++i){

            sequence.add(freq.get(pos)[0]);
            //選
            dfs(pos+1, rest - i * freq.get(pos)[0]);
        }
        //將選擇的數(shù)從列表中刪除
        for (int i=1; i<=most; ++i){
            sequence.remove(sequence.size() - 1);
        }
    }
}
最后編輯于
?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末奕翔,一起剝皮案震驚了整個濱河市裕寨,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌派继,老刑警劉巖宾袜,帶你破解...
    沈念sama閱讀 222,104評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異驾窟,居然都是意外死亡庆猫,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,816評論 3 399
  • 文/潘曉璐 我一進店門绅络,熙熙樓的掌柜王于貴愁眉苦臉地迎上來月培,“玉大人,你說我怎么就攤上這事恩急∩夹螅” “怎么了?”我有些...
    開封第一講書人閱讀 168,697評論 0 360
  • 文/不壞的土叔 我叫張陵假栓,是天一觀的道長寻行。 經(jīng)常有香客問我,道長匾荆,這世上最難降的妖魔是什么拌蜘? 我笑而不...
    開封第一講書人閱讀 59,836評論 1 298
  • 正文 為了忘掉前任杆烁,我火速辦了婚禮,結果婚禮上简卧,老公的妹妹穿的比我還像新娘兔魂。我一直安慰自己,他們只是感情好举娩,可當我...
    茶點故事閱讀 68,851評論 6 397
  • 文/花漫 我一把揭開白布析校。 她就那樣靜靜地躺著,像睡著了一般铜涉。 火紅的嫁衣襯著肌膚如雪智玻。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,441評論 1 310
  • 那天芙代,我揣著相機與錄音吊奢,去河邊找鬼。 笑死纹烹,一個胖子當著我的面吹牛页滚,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播铺呵,決...
    沈念sama閱讀 40,992評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼裹驰,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了片挂?” 一聲冷哼從身側響起幻林,我...
    開封第一講書人閱讀 39,899評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎宴卖,沒想到半個月后滋将,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體瘫析,經(jīng)...
    沈念sama閱讀 46,457評論 1 318
  • 正文 獨居荒郊野嶺守林人離奇死亡徊哑,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,529評論 3 341
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了威彰。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片肝谭。...
    茶點故事閱讀 40,664評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡掘宪,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出攘烛,到底是詐尸還是另有隱情魏滚,我是刑警寧澤,帶...
    沈念sama閱讀 36,346評論 5 350
  • 正文 年R本政府宣布坟漱,位于F島的核電站鼠次,受9級特大地震影響,放射性物質發(fā)生泄漏。R本人自食惡果不足惜腥寇,卻給世界環(huán)境...
    茶點故事閱讀 42,025評論 3 334
  • 文/蒙蒙 一成翩、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧赦役,春花似錦麻敌、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,511評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至乙漓,卻和暖如春级历,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背簇秒。 一陣腳步聲響...
    開封第一講書人閱讀 33,611評論 1 272
  • 我被黑心中介騙來泰國打工鱼喉, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人趋观。 一個月前我還...
    沈念sama閱讀 49,081評論 3 377
  • 正文 我出身青樓,卻偏偏與公主長得像锋边,于是被迫代替她去往敵國和親皱坛。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 45,675評論 2 359