遞迴 回溯 分治

2021-09-11 01:43:51 字數 4217 閱讀 3858

題目:

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

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

示例:輸入: nums = [1,2,3]

輸出:[

[3],

[1],

[2],

[1,2,3],

[1,3],

[2,3],

[1,2],

]方法1:回溯法(o(2^n))

item.push_back(nums[i]);//將nums中第i個數字push進item中

result.push_back(item);//將item中的內容push進result中

generate(i+1, nums, item,result);//遞迴呼叫尋找子集的函式

item.pop_back();//將前個數字pop出,再呼叫遞迴函式,這樣對於nums中的數字而言每個數字都進行過選擇或者不選擇的組合

generate(i+1, nums, item,result);

}};方法2:位運演算法

簡單的說就是將要判斷的整數陣列看成一串可以為(0或者1)的二進位制數,計算不同位置為0為1的組合則是該位置數字出現或者不出現的組合

vector> subsets2(vector& nums)

void generate1(int i, vector& nums, vector> &res, vector&item, set> &re_res)

item.push_back(nums[i]);//將第i個數字push進item中

if(re_res.find(item)==re_res.end())

generate1(i+1,nums,res,item,re_res);//呼叫遞迴函式

item.pop_back();//將當前數字pop再遞迴,這樣對於nums中的數字而言每個數字都進行過選擇或者不選擇的組合

generate1(i+1,nums,res,item,re_res);

}};

題目:給定乙個陣列 candidates 和乙個目標數 target ,找出 candidates 中所有可以使數字和為 target 的組合。

candidates 中的每個數字在每個組合中只能使用一次。

說明:所有數字(包括目標數)都是正整數。

解集不能包含重複的組合。

思路:

item.push_back(candidates[i]);//將candidates中的第i個數存進item

sum+=candidates[i];//sum加上item中儲存的數

if(sum == target && re_res.find(item)==re_res.end())

generate2(i+1,candidates,res,item,re_res,sum,target);//呼叫遞迴

item.pop_back();//item中最後乙個數字pop後再遞迴

sum-=candidates[i];//pop後不要忘了sum也要減掉這個數

generate2(i+1,candidates,res,item,re_res,sum,target);

}};題目:給出 n 代表生成括號的對數,請你寫出乙個函式,使其能夠生成所有可能的並且有效的括號組合。

例如,給出 n = 3,生成結果為:

[「((()))」,

「(()())」,

「(())()」,

「()(())」,

「()()()」

]思路:

void put_down_the_queen(int x, int y, vector> &mark);//設定方向陣列,代表8個方向

static const int dy =;

mark[x][y]=1;

for(int i=0; i < mark.size();i++)

}} }

void generate(int k, int n, vector&location, vector> &result, vector> &mark)

for(int i=0; i> temp_mark = mark;//申請臨時陣列存放當前mark

put_down_the_queen(k,i,mark);//在[k][i]處放置皇后

location[k][i] = 'q'; //在location相應位置設為q

generate(k+1, n, location, result, mark);//遞迴尋找下一行可以放置皇后的位置

mark = temp_mark;//讓mark重新回到回溯前的狀態

location[k][i] = '.';//location同理

}} }

};void main()

merge_sort(vec, count);

return count;

}private:

void merge_sort_two_vec(vector> &sub_vec1, //陣列1 將陣列1,2 排序合併

vector> &sub_vec2, //陣列2

vector> &vec,

vector&count)

else

} for(;i < sub_vec1.size();i++)

for(;j < sub_vec2.size(); j++)

} void merge_sort(vector> &vec, vector&count)

int mid = vec.size()/2; //拆分時,從數中間進行拆分

vector> sub_vec1;//拆分的陣列1

vector> sub_vec2;//拆分的陣列2

//進行拆分

for(int i=0;inums;

nums.push_back(5);

nums.push_back(2);

nums.push_back(1);

nums.push_back(1);

vectorresult = solve.countsmaller(nums);

cout<

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

cout<

system("pause");

}

Leetcode分類 遞迴 回溯 分治

回溯是一種應用遞迴演算法,遞迴不是 題目迴圈的困難之處在於不好模擬選不選某乙個數的過程,即選了乙個數,不方便回溯到不選這個數的情況。給定一組不含重複元素的整數陣列 nums,返回該陣列所有可能的子集 冪集 說明 解集不能包含重複的子集。示例 輸入 nums 1 2,3 輸出 3 1 2 1,2,3 ...

使用with遞迴回溯

向上回溯,查詢頂級部門 declare pdeptid uniqueidentifier with dept deptid,pdeptid as select udepid,uparentid from oa.dbo.depinfo where udepid in select p.udepid f...

遞迴回溯總結

遞迴回溯法對解空間樹作深度優先搜尋,一般情況可表示為 void backtrack int n else 引數n表示遞迴的深度 is ok 表示已經求得問題解 print reult 表示列印結果 如果只求出乙個可行解,那麼求得第乙個問題解後便可exit 如果要求出所有可行解則不需exit base...