子集 2 (含重複數字)

2021-09-28 17:27:00 字數 2453 閱讀 3156

給定乙個可能包含重複元素的整數陣列nums,返回該陣列所有可能的子集(冪集)。

說明:解集不能包含重複的子集。

輸入: [1,2,2]

輸出:[

[2],

[1],

[1,2,2],

[2,2],

[1,2],

]

/**

* 這個題目的解題思想是這樣的。由於nums內的元素存在重複,那麼我們必然需要

* 考慮如果元素重複了,怎麼去處理這個元素。最直觀的想法是說比如我碰到了

* nums[i] == nums[i-1]表示當前元素我處理過了,拿題目中的陣列舉例子

* nums:[1,2,2] i=2的時候就滿足上式,那麼我們可以認為這個元素已經處理過了

* 就直接跳過嗎? 顯然不能 因為如果直接跳過我們就會漏掉[2,2] 和 [1,2,2]

* 這兩個組合。那麼說明我們必須找出某種方式,將部分重複的元素去除。

* * 我們仔細思考一下nums[1,2,2] 當i=0的時候由於我們用於儲存所有已知集合的

* retlist只含有乙個元素,那麼不存在重複問題,我們經過這一步可以得到

* retlist: [1] 來到2的時候我們在看 由於也不存在重複我們的2可以和

* 之前的retlist中的元素全組合一遍得到retlist: [1] [2] [1,2]

* 等i=2來到這個重複的2的時候,我們發現他和前面的元素重複了,那麼如果我們

* 先不考慮重複的問題重複會得到 [1] [2] [1,2] [2] [1,2] [2,2] [1,2,2]

* 我們發現[2] [1,2]這部分是重複的部分是需要被踢出的部分 那麼我們的目標現在

* 就轉變成了如何鑑別出引起重複的這一部分,然後在組合的時候跳過他們。我們回憶一下

* 重複的這個[2] [1,2]**於 2 這個元素和 [1] 組合導致的,因為在這個重複的

* 2之前,已經有乙個2和 [1]發生過組合,所以這裡再去組合 必然發生重複現象。

* 那實際上這個第二次出現的2,只應該和[2] [1,2]發生組合。在這個例子中[2] [1,2]

* 是兩個組合,很容易看出來,但是我們需要乙個值,來表示說出現重複時我到底該匹配的值

* 有多少個? 這個值就是上一次沒有出現重複元素時,retlist的長度。這麼說太抽象了

* 我們舉個例子 假設我們來到了 [1] 現在2要和他們進行組合 此時2和1不相同,那麼

* 他應該和整個retlist進行組合 需要進行組合的元素數為2.那麼當 來到第二個2時,此時

* retlist中有四個元素 [1] [2] [1,2] 按照剛才我們說的他只可以組合兩個元素,

* 否則必然引起重複,而且是從後往前數兩個元素(這個方向是因為,新的組合總是新增在陣列的

* 尾巴上),如果照我們說的 他只應該和[2],[1,2]發生組合最後的出 [1] [2] [1,2] [2,2] [1,2,2].

* * 接下來說點別的,為什麼第二個重複元素只能去和倒數的 上一次沒有出現重複元素時,retlist的長度個

* 元素進行組合?

* * 原因是這樣的,比如當nums[i] != num[i-1]時,此時nums[i]需要和retlist中所有元素進行組合

* 該過程完成後retlist的大小會由原大小m 變化為2m。當我們繼續往後走時,當前nums[i] == nums[i-1]

* 我們直到我們當前的nums[i]只應該和之前的nums[i-1]沒處理過的部分,或者之前的nums[i-1]在上一次

* 組合中新生成的部分進行組合(否則必然造成重複),那這個新生成部分的大小是多少呢?答案是m,因為再不重複時

* 每一次的組合結束大小都會變為原來的1倍,一半是之前的值,一半是新生成的值,而這個m就是上一次沒有出現重複元素時,retlist的長度。

* * 以此類推 當我們的nums[1,2,2,2] 當i=3時,這個時候他還是只需要和上一次retlist的最後m個元素進行組合

* *

*/

vector> subsetswithdup(vector& nums) 

sort(nums.begin(), nums.end());

tmp.push_back(nums[0]);

res.push_back(tmp);

tmp.clear();

if (nums.size() == 1)

int lastlen = 1;

for (int i = 1; i < nums.size(); i++)

for (int j = size - lastlen; j < size; j++)

}return res;

}

非重複組合排列(含重複數字時,生成不重複組合排列)

sample input 1 2 2 3 sample output 分析資料 這裡和不含重複資料生成全組合排列 是不同的,如果使用原 會出現重複的資料,主要原因是在遞迴的時候,會把那些重複的數字當作不同的數字利用,而平等對待,直接進行遞迴。我們要做的就是把相同的數區分出來,我們這裡可以引入乙個陣列...

刪除重複數字

給定乙個排序陣列,刪除重複出現的元素 只能保留此元素的乙個 這樣新的陣列中每個元素只出現一次,並返回這個新陣列的長度。解法一 時間 空間複雜度都是0 n def removeduplicates alist if not alist return 0 result for i in alist if...

不重複數字

operatorname luogup 4305 給定 n nn 個數,要求把其中重複的去掉,只保留第一次出現的數。本題有多組資料。第一行乙個整數 t tt 表示資料組數。對於每組資料 第一行乙個整數 n nn 第二行 n nn 個數,表示給定的數。對於每組資料,輸出一行,為去重後剩下的數,兩個數之...