搜尋順序:
按照給出的數字依次進行搜尋,對於每乙個數字列舉它選用每乙個字母的方案。
回溯:當下乙個字串已經列舉完成時,需要更新當前字串,此時需要進行回溯。然後進行列舉,到當前字串的下乙個元素。第一次寫時,迴圈的意義沒有考慮清楚,這個做法的迴圈是列舉當前字串的每個字元,而不是下乙個字串的每個字元。
class
solution
; vector<
string
> ans;
string path, s;
vector<
string
>
lettercombinations
(string _digits)
void
dfs(
int u,
int y)
string
& cur = letter[s[u]
-'2'];
//當前數字對應字串的每乙個字母都要遍歷一遍
for(
int i =
0; i < cur.
size()
; i ++)}
};
搜尋順序:
對矩陣中的每乙個元素依次進行搜尋,對每乙個元素列舉可能能走的四個方向。
回溯:考慮清楚每個迴圈的意義。考慮清楚何時回溯。對於本題來說,當我已經嘗試走過四個方向後,都沒有匹配上,進行回溯。
class
solution
, dy[4]
=;bool
dfs(
int x,
int y,
int u)
b[x]
[y]= w[u]
;return
false;}
bool
exist
(vectorchar
>
>
& board,
string word)
}return
false;}
};
搜尋順序:
對全排列中的位置依次進行搜尋,對每乙個位置列舉可能能填上的數。
回溯:當第u+1個位置的所有方案填完後,回到第u個位置列舉第u位上的所有方案,此時回溯。
class
solution
//列舉每個位置上的備選數字
for(
int i =
0; i < nums.
size()
; i ++)}
} vectorint>
>
permute
(vector<
int>
& _nums)
};
搜尋順序:
將相同的元素都集中到一起,在填充位置時保證相同元素的相對位置不變。所以上一題dfs是對填充的位置進行搜尋,對填充位置的陣列元素進行列舉,本題dfs為保證相同元素的相對位置不變,對陣列元素依次進行搜尋,對存放陣列的位置進行列舉。如果下乙個遞迴的元素等於上乙個遞迴的元素,則下乙個遞迴的元素只能放在當前元素存放位置的後面。
回溯:陣列中第u+1個數列舉完所有位置時進行回溯。
class
solution
//列舉能被填充的各個位置
for(
int i = t; i < nums.
size()
; i ++)}
} vectorint>
>
permuteunique
(vector<
int>
& _nums)
};
搜尋順序:
對陣列中的元素依次進行搜尋,對每乙個元素可能加入集合,也可能不加。
回溯:第u+1個元素的兩種情況列舉完後,回溯。
class
solution
//不放入,直接進入第u+1個位置
dfs(u +1)
;//將第u個位置上的元素放入子集
path.
push_back
(nums[u]);
dfs(u +1)
; path.
pop_back()
;}vectorint>
>
subsets
(vector<
int>
& _nums)
};
用二進位制數來表示第j位是否選擇加入子集
class
solution
return ans;}}
;
搜尋順序:
在上一題的基礎上推廣,對陣列中的元素依次進行搜尋,同乙個元素選擇0~k次(k為相同元素的數量)。
回溯:第u+1個元素選擇0~k次的所有情況列舉完後,回溯。
class
solution
int k =0;
while
(u+k size()
&& nums[u+k]
== nums[u]
) k++
;//列舉第u個元素選擇從0到k的不同情況
for(
int i =
0; i <= k; i ++
)//恢復現場
for(
int i =
0; i <= k; i ++
) path.
pop_back()
;}vectorint>
>
subsetswithdup
(vector<
int>
& _nums)
};
搜尋順序:
按位置搜尋,每乙個位置都可填入在0~9之內,並比前乙個數大的數。
回溯:下一位置列舉完所有可能數後回溯。
class
solution
else
if(kt > k || nt > n)
return
;for
(int i = t +
1; i <=
9; i ++)}
vectorint>
>
combinationsum3
(int _k,
int _n)
};
搜尋順序:
按行搜尋,列舉每一列上可能的元素。
回溯:下一行列舉完回溯。
class
solution
//列舉每列是否能放上皇后
for(
int y =
0; y < n; y ++)}
}int
totalnqueens
(int _n)
};
搜尋順序:
從左到右,從上到下依次搜尋。
回溯:如果下一次搜尋沒有解,回溯。
class
solution}}
else
return
dfs(x, y +
1, b)
;return
false;}
void
solvesudoku
(vectorchar
>
>
& board)
}dfs(0
,0, board);}
};
搜尋順序:
依次拼接正方形的每條邊。每條邊列舉木棒順序從長到短(木棒越長,dfs的分支越少,分支下的方案數就越多,剪枝的效果就越好。
剪枝:1、所有木棒長度的總和不是4的倍數或木棒不到4根。
2、如果當前木棒拼接失敗,則跳過接下來所有長度相同的木棒。
3、如果當前木棒拼接失敗,且是當前邊的第乙個,則直接剪掉當前分支。
4、如果當前木棒拼接失敗,且是當前邊的最後乙個,則直接剪掉當前分支。
class
solution
//拼接第u根木棒,當前長度為cur,從第start棵木棒開始選
bool
dfs(
int u,
int cur,
int start)
return
false;}
};
中階演算法 dfs 回溯(1)
其實我們在遞迴演算法的學習過程中已經認識到了很多遞迴的思想,而遞迴的思想和dfs是非常相似的,不同的是在dfs中一般需要乙個標記過程也就是回溯,這裡我們練習乙個類似dfs的遞迴題。從現在開始實現從遞迴向dfs 回溯的過渡。include include include include include...
雜湊表習題整理(1)
1.拉鍊法int h n e n ne n idx 向雜湊表中插入乙個數 void insert int x 在雜湊表中查詢某個數是否存在 bool find int x 開放定址法int h n 如果x在雜湊表中,返回x的下標 如果x不在雜湊表中,返回x應該插入的位置 intfind int x ...
動態規劃習題整理(1)
狀態表示 f i 表示以第 i 個元素結尾的所有連續子陣列的最大值。狀態轉移 f i max f i 1 0 nums i f i 可劃分為兩部分,以第 i 1個元素結尾的所有連續子陣列加上第i個元素,或者只選用第 i 個元素。答案為所有f i 中的最大值。優化 由於f i 在計算時只會用到f i ...