国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

【算法】遞歸、回溯、剪枝、dfs 算法題練習(xí)(組合、排列、總和問題;C++)

這篇具有很好參考價值的文章主要介紹了【算法】遞歸、回溯、剪枝、dfs 算法題練習(xí)(組合、排列、總和問題;C++)。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

1. 前言

后面的練習(xí)是接著下面鏈接中的文章所繼續(xù)的,在對后面的題練習(xí)之前,可以先將下面的的文章進行了解??:

【算法】{畫決策樹 + dfs + 遞歸 + 回溯 + 剪枝} 解決排列、子集問題(C++)

2. 算法題

22.括號生成

【算法】遞歸、回溯、剪枝、dfs 算法題練習(xí)(組合、排列、總和問題;C++),算法,算法,剪枝,深度優(yōu)先,c++,決策樹


思路

  • 題意分析:要求根據(jù)給出的數(shù)字,算出合法的括號組成個數(shù)。根據(jù)題目,我們可以總結(jié)出下面的規(guī)則:
    【算法】遞歸、回溯、剪枝、dfs 算法題練習(xí)(組合、排列、總和問題;C++),算法,算法,剪枝,深度優(yōu)先,c++,決策樹
  • 解法dfs + 根據(jù)決策樹設(shè)計遞歸、回溯、剪枝
  • 決策樹
    【算法】遞歸、回溯、剪枝、dfs 算法題練習(xí)(組合、排列、總和問題;C++),算法,算法,剪枝,深度優(yōu)先,c++,決策樹
    • 根據(jù)上圖決策樹,即可直接著手編寫代碼:
    • 細節(jié)問題
      【算法】遞歸、回溯、剪枝、dfs 算法題練習(xí)(組合、排列、總和問題;C++),算法,算法,剪枝,深度優(yōu)先,c++,決策樹

代碼文章來源地址http://www.zghlxwxcb.cn/news/detail-835610.html

class Solution {
public:
    int left, right, _n; // 分別記錄左右括號的數(shù)量
    vector<string> ret; // 結(jié)果數(shù)字
    string path;
    vector<string> generateParenthesis(int n) {
        _n = n;
        dfs();
        return ret;
    }

    void dfs()
    {
        if(right == _n) // 當前path序列有效,加入結(jié)果
        {
            ret.push_back(path);
            return;
        }

        if(left < _n) // 添加左括號
        {
            path.push_back('('); left++;
            dfs();
            path.pop_back(); left--;
        }

        if(right < left) // 添加右括號
        {
            path.push_back(')'); right++;
            dfs();
            path.pop_back(); right--;
        }
    }
};

494.目標和

【算法】遞歸、回溯、剪枝、dfs 算法題練習(xí)(組合、排列、總和問題;C++),算法,算法,剪枝,深度優(yōu)先,c++,決策樹

思路

  • 題意分析:對于數(shù)組給出的數(shù)字,通過向所有數(shù)字前補加減號,使最后的值為 target
  • 解法dfs + 根據(jù)決策樹設(shè)計遞歸、回溯、剪枝
    • 該解法并非最優(yōu)解法,但這里依然用dfs做,并引出一些寫法問題。
    • 決策樹:(省略了后面的步驟)

【算法】遞歸、回溯、剪枝、dfs 算法題練習(xí)(組合、排列、總和問題;C++),算法,算法,剪枝,深度優(yōu)先,c++,決策樹
- 根據(jù)決策樹的思路,不難看出實際上與 題目 78.子集 非常相似,代碼也是如此,但有一個需要注意的細節(jié),先看代碼:

代碼1

class Solution {
public:
    int ret, path, _target;
    
    int findTargetSumWays(vector<int>& nums, int target) {
        _target = target;
        dfs(nums, 0); // 從0位置開始
        return ret;
    }

    void dfs(vector<int>& nums, int pos)
    {
        // 終止條件
        if(pos == nums.size())
        {
            if(path == _target) ret++;
            return;
        }

        // 正號
        path += nums[pos];
        dfs(nums, pos + 1);
        path -= nums[pos];

        // 負號
        path -= nums[pos];
        dfs(nums, pos + 1);
        path += nums[pos];
    }
};
  1. 最開始我們提到,深搜dfs并非該題的最優(yōu)解法, 時間開銷很大,對于上面的代碼,更是面臨超時的風(fēng)險,上面的代碼將 path作為全局變量
  2. 我們可以 進行優(yōu)化:將path作為參數(shù)傳遞
  3. 更改后的代碼,時間開銷會小一些

代碼2

class Solution {
public:
    int ret, _target;
    
    int findTargetSumWays(vector<int>& nums, int target) {
        _target = target;
        dfs(nums, 0, 0); // 從0位置開始
        return ret;
    }

    void dfs(vector<int>& nums, int pos, int path)
    {
        // 終止條件
        if(pos == nums.size())
        {
            if(path == _target) ret++;
            return;
        }

        // 正號
        dfs(nums, pos + 1, path + nums[pos]);

        // 負號
        dfs(nums, pos + 1, path - nums[pos]);
    }
};

path定義形式的理由

  1. 頻繁的執(zhí)行 + - 操作,是一比不小的時間消耗,直接傳參可以只需要將計算后的結(jié)果直接作為參數(shù)遞歸
  2. 而對于 [78.子集],我們將path定義為全局變量,因為對于該題情況,path 本身為vector類型,作為參數(shù)傳遞會導(dǎo)致頻繁的創(chuàng)建vector,不利于節(jié)省時間。

39.組合總和

【算法】遞歸、回溯、剪枝、dfs 算法題練習(xí)(組合、排列、總和問題;C++),算法,算法,剪枝,深度優(yōu)先,c++,決策樹

思路

  • 題意分析:即通過給定的數(shù)組任意分配,組成和為目標值的序列,求序列的種類。
  • 解法dfs + 根據(jù)決策樹設(shè)計遞歸、回溯、剪枝

解法1

  • 決策樹:如圖所示:
    • 即每次分支都進行所有數(shù)字的選擇,符合條件的繼續(xù),由于題目要去重,同層下選過的不再復(fù)選
    • 剪枝:同層的選過的剪掉 + 該路徑和超出目標值或該位置超出數(shù)組范圍的剪掉
      【算法】遞歸、回溯、剪枝、dfs 算法題練習(xí)(組合、排列、總和問題;C++),算法,算法,剪枝,深度優(yōu)先,c++,決策樹

代碼

class Solution {
public:
    int _target;
    vector<int> path;
    vector<vector<int>> ret;
    vector<vector<int>> combinationSum(vector<int>& candidates, int target) {
        _target = target;
        dfs(candidates, 0, 0);
        return ret;
    }

    void dfs(vector<int>& nums, int pos, int pathSum)
    {
        // 路徑和等于目標值,記錄結(jié)果,向上返回
        if(pathSum == _target)
        {
            ret.push_back(path);
            return;
        }
        // 路徑和大于目標值 / 當前位置超出數(shù)組; 向上返回
        if(pathSum > _target || pos >= nums.size()) return;

        for(int i = pos; i < nums.size(); ++i)
        {
            path.push_back(nums[i]);
            dfs(nums, i, pathSum + nums[i]);
            path.pop_back();
        }
    }
};

解法2

  • 決策樹
    【算法】遞歸、回溯、剪枝、dfs 算法題練習(xí)(組合、排列、總和問題;C++),算法,算法,剪枝,深度優(yōu)先,c++,決策樹

對于上圖,有一個需要注意的細節(jié)問題:
- 對于恢復(fù)現(xiàn)場:

【算法】遞歸、回溯、剪枝、dfs 算法題練習(xí)(組合、排列、總和問題;C++),算法,算法,剪枝,深度優(yōu)先,c++,決策樹

此時我們可以編寫代碼:

代碼

class Solution {
public:
    int _target;
    vector<int> path;
    vector<vector<int>> ret;

    vector<vector<int>> combinationSum(vector<int>& candidates, int target) {
        _target = target;
        dfs(candidates, 0, 0);
        return ret;
    }

    void dfs(vector<int>& nums, int pos, int pathSum)
    {
        // 路徑和等于目標值,記錄結(jié)果,向上返回
        if(pathSum == _target)
        {
            ret.push_back(path);
            return;
        }
        // 路徑和大于目標值 / 當前位置超出數(shù)組; 向上返回
        if(pathSum > _target || pos >= nums.size()) return;

        for(int k = 0; k * nums[pos] <= _target; ++k)
        {
            if(k) path.push_back(nums[pos]); // 枚舉 當前值的個數(shù),添加到數(shù)組中
            dfs(nums, pos + 1, pathSum + k*nums[pos]);
        }

        // 恢復(fù)現(xiàn)場
        for(int k = 1; k * nums[pos] <= _target; ++k)
        {
            // 將每個元素添加過的個數(shù)值 都恢復(fù)
            path.pop_back();
        }
    }
};

784.字母大小寫全排列

【算法】遞歸、回溯、剪枝、dfs 算法題練習(xí)(組合、排列、總和問題;C++),算法,算法,剪枝,深度優(yōu)先,c++,決策樹

思路

  • 題意分析:即返回所有轉(zhuǎn)換字母大小寫后的字符串
  • 決策樹:如下圖所示
    • 當當前位置是字母時,進行變與不變的分支,當是數(shù)字時,直接繼續(xù),無分支,最后葉子節(jié)點處即為結(jié)果。
      【算法】遞歸、回溯、剪枝、dfs 算法題練習(xí)(組合、排列、總和問題;C++),算法,算法,剪枝,深度優(yōu)先,c++,決策樹

代碼

class Solution {
public:
    string path; // 記錄當前字母序列
    vector<string> ret;

    vector<string> letterCasePermutation(string s) {
        dfs(s, 0);
        return ret;
    }

    void dfs(string s, int pos)
    {
        if(path.size() == s.size())
        {
            ret.push_back(path);
            return;
        }

        char ch = s[pos];
        // 不改變的情況:數(shù)字 以及 字母的第一種情況
        path += ch;
        dfs(s, pos + 1);
        path.pop_back();

        if(isalpha(ch)) // 需要改變  
        {
            // 改變大小寫
            if(ch <= 'z' && ch >= 'a') ch -= 32;
            else ch += 32;

            path += ch;
            dfs(s, pos + 1);
            path.pop_back();
        }
    }
};

526. 優(yōu)美的排列

【算法】遞歸、回溯、剪枝、dfs 算法題練習(xí)(組合、排列、總和問題;C++),算法,算法,剪枝,深度優(yōu)先,c++,決策樹

思路

  • 題意分析:即找出所有的符合規(guī)則(優(yōu)美排列)的排列
  • 解法利用全排列 與 規(guī)則
    • 決策樹:這里不再畫決策樹了,相當于全排列的思路
    • 全排列的思路即:如果該位置未被檢索過,則加入path中并繼續(xù)dfs
    • 這里我們增加一條判定,即當前位置的下標與perm[i]滿足整除關(guān)系時,才進行dfs

代碼

class Solution {
public:
    bool used[16];
    int ret;

    int countArrangement(int n) {
        dfs(1, n); // 從下標為1處填n個數(shù)
        return ret;
    }

    void dfs(int pos, int n)
    {
        if(pos == n + 1){ // 更新結(jié)果
            ret += 1;
            return;
        }

        // 全排列 + 判斷是否符合優(yōu)美排列
        for(int i = 1; i <= n; ++i)
        {
            if(!used[i] && (i % pos == 0 || pos % i == 0))
            {
                used[i] = true;
                dfs(pos + 1, n);
                used[i] = false; // 恢復(fù)現(xiàn)場
            }   
            
        }
    }
};

到了這里,關(guān)于【算法】遞歸、回溯、剪枝、dfs 算法題練習(xí)(組合、排列、總和問題;C++)的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務(wù),不擁有所有權(quán),不承擔相關(guān)法律責任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實不符,請點擊違法舉報進行投訴反饋,一經(jīng)查實,立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費用

相關(guān)文章

  • DFS:深搜+回溯+剪枝解決排列、子集問題

    DFS:深搜+回溯+剪枝解決排列、子集問題

    ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 創(chuàng)作不易,感謝三連支持?。? . - 力扣(LeetCode) . - 力扣(LeetCode) ?方案1:不合法就continue 方案2:合法才能進循環(huán) . - 力扣(LeetCode) . - 力扣(LeetCode) ?策略1:決策樹以選不選作為參考,結(jié)果為葉子節(jié)點 策略2:決策樹以選幾個

    2024年04月16日
    瀏覽(22)
  • 【算法】回溯:與遞歸,dfs的同質(zhì)與分別,剪枝與恢復(fù)現(xiàn)場的詳細理解,n皇后的回溯解法及算法復(fù)雜度分析。

    【算法】回溯:與遞歸,dfs的同質(zhì)與分別,剪枝與恢復(fù)現(xiàn)場的詳細理解,n皇后的回溯解法及算法復(fù)雜度分析。

    目錄 ?編輯 1.什么是回溯 2.關(guān)于剪枝 3.關(guān)于恢復(fù)現(xiàn)場 4.題目:二叉樹的所有路徑(凸顯恢復(fù)現(xiàn)場:切實感受回溯與深搜) 問題分析 ①函數(shù)設(shè)置為:void Dfs(root) ②函數(shù)設(shè)置為:void Dfs(root,path) 解題思想:使?深度優(yōu)先遍歷(DFS)求解。 代碼實現(xiàn) 5.N后問題 問題分析 4皇后的放置

    2024年04月16日
    瀏覽(20)
  • LeetCode刷題13:回溯+剪枝解決216.組合總和 III

    LeetCode刷題13:回溯+剪枝解決216.組合總和 III

    找出所有相加之和為? n ? 的? k ? 個數(shù)的組合,且滿足下列條件: 只使用數(shù)字1到9 每個數(shù)字? 最多使用一次 ? 返回? 所有可能的有效組合的列表 ?。該列表不能包含相同的組合兩次,組合可以以任何順序返回。 示例 1: 輸入: k = 3, n = 7 輸出: [[1,2,4]] 解釋: 1 + 2 + 4 = 7 沒有其他

    2024年02月02日
    瀏覽(18)
  • 【C/C++練習(xí)】經(jīng)典的排列組合問題(回溯算法)——電話號碼的字母組合

    【C/C++練習(xí)】經(jīng)典的排列組合問題(回溯算法)——電話號碼的字母組合

    ??題目描述 題目出處 :電話號碼的字母組合 示例: ??題解 ?這是一道典型的排列組合問題,根據(jù)輸入,我們需要找到所有的組合。下面以輸入字符串 digits = \\\"23\\\" 為例來講解這道題目。 圖解: 分析: ?首先要知道輸入的字符串 \\\"23\\\" 中的數(shù)字字符分別對應(yīng)哪些字符串,其中

    2024年02月16日
    瀏覽(14)
  • DFS:深搜+回溯+剪枝解決組合問題

    DFS:深搜+回溯+剪枝解決組合問題

    ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?創(chuàng)作不易,感謝支持!!! . - 力扣(LeetCode) . - 力扣(LeetCode) . - 力扣(LeetCode) . - 力扣(LeetCode) . - 力扣(LeetCode) . - 力扣(LeetCode) . - 力扣(LeetCode) . - 力扣(LeetCode) 該題和前面是類似的,但是用回溯算法,會超

    2024年04月12日
    瀏覽(21)
  • 組合(力扣)dfs + 回溯 + 剪枝 JAVA

    組合(力扣)dfs + 回溯 + 剪枝 JAVA

    給定兩個整數(shù) n 和 k,返回范圍 [1, n] 中所有可能的 k 個數(shù)的組合。 你可以按 任何順序 返回答案。 示例 1: 輸入:n = 4, k = 2 輸出: [ [2,4], [3,4], [2,3], [1,2], [1,3], [1,4], ] 示例 2: 輸入:n = 1, k = 1 輸出:[[1]] 提示: 1 = n = 20 1 = k = n 解題思路: 1.每個元素有選與不選兩種情況,

    2024年02月16日
    瀏覽(17)
  • 遞歸實現(xiàn) 組合問題+排列問題(DFS)

    遞歸實現(xiàn) 組合問題+排列問題(DFS)

    目錄 遞歸實現(xiàn)排列型枚舉 遞歸實現(xiàn)排列類型枚舉 II ?遞歸實現(xiàn)組合型枚舉 遞歸實現(xiàn)組合型枚舉 II 遞歸實現(xiàn)指數(shù)型枚舉 遞歸實現(xiàn)指數(shù)型枚舉 II 遞歸不是循環(huán),遞歸利用了系統(tǒng)棧,只要是函數(shù)都會被系統(tǒng)管理。當執(zhí)行到函數(shù)地址入口時就會為函數(shù)在系統(tǒng)棧上分配一塊內(nèi)存。當

    2024年02月15日
    瀏覽(23)
  • LeetCode算法題解(回溯)|39. 組合總和、40. 組合總和 II、131. 分割回文串

    題目鏈接:39. 組合總和 題目描述: 給你一個? 無重復(fù)元素 ?的整數(shù)數(shù)組? candidates ?和一個目標整數(shù)? target ?,找出? candidates ?中可以使數(shù)字和為目標數(shù)? target ?的 所有 ? 不同組合 ?,并以列表形式返回。你可以按? 任意順序 ?返回這些組合。 candidates ?中的? 同一個 ?數(shù)

    2024年02月05日
    瀏覽(26)
  • leetcode216. 組合總和 III(回溯算法-java)

    leetcode216. 組合總和 III(回溯算法-java)

    來源:力扣(LeetCode) 鏈接:https://leetcode.cn/problems/combination-sum-iii 找出所有相加之和為 n 的 k 個數(shù)的組合,且滿足下列條件: 只使用數(shù)字1到9 每個數(shù)字 最多使用一次 返回 所有可能的有效組合的列表 。該列表不能包含相同的組合兩次,組合可以以任何順序返回。 示例 1: 輸

    2024年02月10日
    瀏覽(20)
  • 【Leetcode60天帶刷】day27回溯算法——39. 組合總和,40.組合總和II,131.分割回文串

    【Leetcode60天帶刷】day27回溯算法——39. 組合總和,40.組合總和II,131.分割回文串

    ? 39. 組合總和 給你一個? 無重復(fù)元素 ?的整數(shù)數(shù)組? candidates ?和一個目標整數(shù)? target ?,找出? candidates ?中可以使數(shù)字和為目標數(shù)? target ?的 所有 ? 不同組合 ?,并以列表形式返回。你可以按? 任意順序 ?返回這些組合。 candidates ?中的? 同一個 ?數(shù)字可以? 無限制重復(fù)

    2024年02月11日
    瀏覽(24)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包