日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 人文社科 > 生活经验 >内容正文

生活经验

递归/回溯:Combination Sum II数组之和

發布時間:2023/11/27 生活经验 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 递归/回溯:Combination Sum II数组之和 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

問題如下:
已知一組數(其中有重復元素),求這組數可以組成的所有子集中,子 集中的各個元素和為整數target的子集,結果中無重復的子集。
例如: nums[] = [10, 1, 2, 7, 6, 1, 5], target = 8
結果為: [[1, 7], [1, 2, 5], [2, 6], [1, 1, 6]]

同樣之前有類似的相關的問題遞歸/回溯:Subsets II求子集(有重復元素),最終將子集中和為8的集合輸出,同樣不能有重復子集

一個直接的辦法就是在輸出最終子集的時候,使用之前類似的問題解決過程,將初始篩選的集合做一個計算,檢查是否滿足target 為8的要求,滿足則返回。
類似如下:

std::vector<std::vector<int> > get_subsets(std::vector<int> &num ,int target) {std::vector<int> item;std::vector<std::vector<int>> result;std::set<std::vector<int> > uniq_result;sort(num.begin(), num.end());result.push_back(item);generate(0, num, item, result, uniq_result);/*對遞歸回溯獲取到的結果進行計算,將滿足要求的和為target的子集篩選出來返回*/int sum; std::vector<std::vector<int>> target_result;for (int i = 0; i< result.size(); ++i){sum = 0;for (int j = 0; j < result[i].size(); ++j) {sum += result[i][j];}if (sum == target) {target_result.push_back(result[i]);}}return target_result;
}

但是一個很嚴重的問題,遞歸/回溯本身是2^n的復雜度,如果仍然按照以上的方法對所有元素篩選一遍之后再返回顯然時間復雜度極高,并且在回溯過程中沒有應用到要求的target條件

提出如下方法,在回溯的過程中進行計算,當計算過程中有超過target的集合或者元素,即可終止繼續遞歸,直接回溯,防止沒有意義的遞歸下去。
類似[10,1,2,3,5],其中包含10的子集顯然沒有必要加入到最終的集合,因為10已經大于target了

實現算法如下:

oid generate(int i, std::vector<int> &num,std::vector<int> &item,std::vector<std::vector<int> > &result,std::set<std::vector<int> > &uniq_result,int sum, int target) {/*當結果大于target,直接返回,沒有必要繼續遞歸*/if (sum > target || i >= num.size()) {return;}sum += num[i];item.push_back(num[i]);/*滿足結果為target,且不是重復子集,則加入到最終的結果中*/if (sum == target && uniq_result.find(item) == uniq_result.end()) {result.push_back(item);uniq_result.insert(item);}generate(i + 1, num, item, result, uniq_result, sum, target);item.pop_back();sum -= num[i];generate(i + 1, num, item, result, uniq_result, sum, target);
}std::vector<std::vector<int> > get_combiname_sets(std::vector<int> &num, int target) {std::vector<int> item;std::vector<std::vector<int>> result; //存儲最終的子集std::set<std::vector<int> > uniq_result; //集合,篩選重復子集sort(num.begin(),num.end());generate(0, num, item, result, uniq_result, 0, target);return result;
}

測試代碼如下:
nums[] = [10, 1, 2, 7, 6, 1, 5], target = 8

#include <iostream>
#include <vector>
#include <algorithm>
#include <set>/*
已知一組數(其中有重復元素),求這組數可以組成的所有子集中,子 集中的各個元素和為整數target的子集,結果中無重復的子集。
例如: nums[] = [10, 1, 2, 7, 6, 1, 5], target = 8
結果為: [[1, 7], [1, 2, 5], [2, 6], [1, 1, 6]]
*/using namespace std;void generate(int i, std::vector<int> &num,std::vector<int> &item,std::vector<std::vector<int> > &result,std::set<std::vector<int> > &uniq_result,int sum, int target) {if (sum > target || i >= num.size()) {return;}sum += num[i];item.push_back(num[i]);if (sum == target && uniq_result.find(item) == uniq_result.end()) {result.push_back(item);uniq_result.insert(item);}generate(i + 1, num, item, result, uniq_result, sum, target);item.pop_back();sum -= num[i];generate(i + 1, num, item, result, uniq_result, sum, target);
}std::vector<std::vector<int> > get_combiname_sets(std::vector<int> &num, int target) {std::vector<int> item;std::vector<std::vector<int>> result;std::set<std::vector<int> > uniq_result;sort(num.begin(),num.end());generate(0, num, item, result, uniq_result, 0, target);return result;
}int main(int argc, char const *argv[])
{std::vector<int> num;std::vector<int> item;std::vector<std::vector<int>> result;int tmp;int N;std::cin >> N;for (int i  = 0;i < N; ++i) {std::cin >> tmp;num.push_back(tmp);}int target;cin >> target;result= get_combiname_sets(num,target);for (int i = 0;i < result.size(); ++i) {for (int j = 0;j < result[i].size(); ++j) {std::cout << "[" << result[i][j] << "] ";}std::cout << std::endl;}return 0;
}

輸出如下:

#輸入
7
10 1 2 7 6 1 5
8#結果
[1] [1] [6] 
[1] [2] [5] 
[1] [7] 
[2] [6] 

總結:
遞歸回溯的結合,本身是時間復雜度較高的一種算法實現組合,但是如果能夠合理運用給出的篩選條件,能夠極大得縮短時間復雜度,使得代碼更加簡介高效。

總結

以上是生活随笔為你收集整理的递归/回溯:Combination Sum II数组之和的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 黄污视频网站 | 奇米在线777 | 伊人蕉久影院 | 国产99在线播放 | 欧美日韩三级在线 | 美腿丝袜亚洲综合 | 日视频| 影院一区| 男女免费观看视频 | 国产精品一线二线三线 | 亚州欧美在线 | 一区久久久| 亚洲色图国产 | 国产制服丝袜在线 | 日韩一级色 | 六月婷婷中文字幕 | 成人午夜影视在线观看 | 国产精品少妇 | 九九自拍视频 | 国模无码大尺度一区二区三区 | 99国产精品久久久久久久成人 | 国产怡红院 | 国产一区二区精品在线观看 | 毛片久久久 | 欧美日韩在线视频免费 | 人与禽性7777777| 小视频免费在线观看 | 久久这里只有精品久久 | 成人影音在线 | 国产视频在线观看一区二区 | 99色99| 成人三级黄色 | 日韩视频在线观看二区 | xxxx.国产| 久草精品在线观看视频 | 五月天丁香久久 | 黄色一级片欧美 | 一区二区三区在线视频播放 | 中文av网站| 国内精品久久久久久 | 日本裸体网站 | 综合网中文字幕 | 94av| 精品一级少妇久久久久久久 | 干干干操操操 | 91黄色在线视频 | 名人明星三级videos | 亚洲色成人网站www永久四虎 | 少妇第一次交换又紧又爽 | 真实的国产乱xxxx在线 | 天天免费视频 | 亚洲精品视频在线观看视频 | 18欧美性xxxx极品hd | 夜夜夜夜爽 | 成人综合社区 | 女人免费视频 | 潘金莲三级野外 | 99色这里只有精品 | 国产一级性生活 | 国产亚洲精品成人a | 亚洲精品久久久久久动漫器材一区 | 狠狠干天天操 | 91精彩视频在线观看 | 中文字幕一区二区人妻视频 | 国产成人精品视频一区二区 | 岳睡了我中文字幕日本 | 高清欧美性猛交 | 人人搞人人爱 | 日韩人妻无码一区二区三区99 | 亚欧精品在线观看 | 99热这里只 | 蜜臀av一区二区三区 | 午夜激情综合 | 亚洲人成影视 | 亚洲精品一区二三区不卡 | 天天色天天射天天操 | 欧美91精品久久久久国产性生爱 | 精品一区免费观看 | 成人在线播放av | 免费av资源 | 小泽玛利亚一区二区三区视频 | 日韩 欧美 国产 综合 | 青青草国产成人av片免费 | 成年人免费看毛片 | 天堂av影院 | 国产女教师bbwbbwbbw | 四色成人av永久网址 | 色婷婷久久综合中文久久蜜桃av | 中文字幕欲求不满 | 人成精品 | 亚洲第一页在线 | 挪威xxxx性hd极品 | 精品视频一区在线观看 | 综合色婷婷一区二区亚洲欧美国产 | 国产乱国产乱300精品 | 日p视频在线观看 | 中文字幕av二区 | 亚洲四虎av| 久久最新 |