1. 程式人生 > 其它 >LeetCode 刷題 [C++] 周總結 (遞迴、深度優先搜尋、廣度優先搜尋、貪心演算法以及二分查詢演算法)

LeetCode 刷題 [C++] 周總結 (遞迴、深度優先搜尋、廣度優先搜尋、貪心演算法以及二分查詢演算法)

技術標籤:C++演算法與資料結構演算法資料結構leetcodedfs二分法

本週主要對深度優先搜尋、廣度優先搜尋、貪心演算法以及二分查詢演算法進行了學習。特此總結以下這周的收穫和感想分享給大家,希望對大家有幫助。

一、遞迴、回溯和深度優先搜尋的理解

1.遞迴的是借用棧實現一些操作,是有“來回”過程;
2.回溯法的核心為試探和復原。整個過程利用遞迴去執行,在遞迴函式執行前取修改嘗試,滿足條件後下沉到下一層,試探完成後將數值復原。在整個試探和復原的過程中找到最終需要的一個或所有解。
3.回溯演算法其實是一種特殊的深度優先遍歷演算法。之所以叫回溯,主要是因為回溯利用一個不斷變化的變數,通過嘗試各種可能的過程來搜尋需要的結果,強調了回退操作對於搜尋的合理性。而深度優先遍歷強調的是遍歷的思想。

想要深刻理解和掌握這些演算法和思想,需要從做題的過程中感受,因此,多做題能否更加深刻和快速的掌握這些演算法思想。
深度優先搜尋、廣度優先搜尋、回溯練習題:
第46題.全排列:https://leetcode-cn.com/problems/permutations/
第102題.二叉樹的層序遍歷:https://leetcode-cn.com/problems/binary-tree-level-order-traversal/
第433題.最小基因變化:https://leetcode-cn.com/problems/minimum-genetic-mutation/
第22題.括號生成:https://leetcode-cn.com/problems/generate-parentheses/
第515題.在每個樹行中找最大值:https://leetcode-cn.com/problems/find-largest-value-in-each-tree-row/
深度優先程式碼模板

map<int,int> visited;
void dfs(Node* root) {
    //結束條件
    if(!root) return ;
    if(visited.count(root->val)) {
        //已經被訪問
        return;
    }
    visited[root->val] = 1;
    //處理當前層邏輯

    for
(int i=0;i<root->children.size();++i) { dfs(root->children[i]); } return; }

廣度優先程式碼模板

void bfs(Node* root) {
    map<int,int> visited;
    if(!root) return;
    queue<Node*> queueNode;
    queueNode.push(root);
    while(!queueNode.empty()) {
        Node* node = queueNode.top();
        queueNode.pop();
        if(visited.count(node->val)) continue;
        visited[node->val] = 1;
        for(int i=0;i<node->children.size();++i) {
            queueNode.push(node->children[i]);
        }
    }
    return;
}

二、貪心演算法的理解

貪心演算法是一種在每一步選擇中都採用在當前狀態下最好或最優的選擇,從而希望導致結果是全域性最好或者最優的演算法。一旦一個問題可以通過貪心法來解決,那麼貪心法一般是解決這個問題的最好辦法。由於貪心法高效性以及其所求得的答案比較接近最優結果,貪心法也可以用作輔助演算法或者直接解決一些要求結果不特別精確的問題。
貪心演算法與動態規劃的不同在於它對每個子問題的解決方案都做出選擇,不能回退。動態規劃則會儲存之前的運算結果,並根據以前的結果對當前進行選擇,有回退功能。
貪心演算法、回溯、動態規劃之間的區別:
貪心:當下做區域性最優判斷;可解決一些最優化問題,如:求圖中最小生成樹、求哈夫曼編碼的等。
回溯:能夠回退;
動態規劃:最優判斷+回退。
練習貪心法的題目:
第322題.零錢兌換:https://leetcode-cn.com/problems/coin-change/
第455題.分發餅乾:https://leetcode-cn.com/problems/assign-cookies/

三、二分法的理解

二分查詢的前提:
1.目標函式單調性(單調遞增或者遞減);
2.存在上下界;
3.能夠通過索引訪問。

二分程式碼模板

int binarySearch(const vector<int>& nums,int target) {
	int left=0,right=nums.size()-1;
	while(left <= right) {
	    int mid = left + (right - left)/2;
	    if(nums[mid] == target) return mid;
	    else if(nums[mid] < target) left = ++mid;
	    else right = --mid;
	}
	return -1;
}

練習二分習題:
第69題.x 的平方根:https://leetcode-cn.com/problems/sqrtx/
第153題.尋找旋轉排序陣列中的最小值:https://leetcode-cn.com/problems/find-minimum-in-rotated-sorted-array/
第33題.搜尋旋轉排序陣列::https://leetcode-cn.com/problems/search-in-rotated-sorted-array/

最近的刷題感受是:通過刷題,有助於對這些演算法思想進行更深刻的理解。