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

【算法系列篇】遞歸、搜索和回溯(四)

這篇具有很好參考價(jià)值的文章主要介紹了【算法系列篇】遞歸、搜索和回溯(四)。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問(wèn)。

【算法系列篇】遞歸、搜索和回溯(四),算法,算法,遞歸,搜索,回溯

前言

前面我們通過(guò)幾個(gè)題目基本了解了解決遞歸類問(wèn)題的基本思路和步驟,相信大家對(duì)于遞歸多多少少有了更加深入的了解。那么本篇文章我將為大家分享結(jié)合決策樹(shù)來(lái)解決遞歸、搜索和回溯相關(guān)的問(wèn)題。

什么是決策樹(shù)

決策樹(shù)是一種基本的分類與回歸方法。在分類問(wèn)題中,決策樹(shù)通過(guò)構(gòu)建一棵樹(shù)形圖來(lái)對(duì)數(shù)據(jù)進(jìn)行分類。樹(shù)的每個(gè)節(jié)點(diǎn)表示一個(gè)特征屬性,每個(gè)分支代表一個(gè)特征屬性上的判斷條件,每個(gè)葉節(jié)點(diǎn)代表一個(gè)類別。在回歸問(wèn)題中,決策樹(shù)可以預(yù)測(cè)一個(gè)實(shí)數(shù)值。

下面是一個(gè)簡(jiǎn)單的決策樹(shù):
【算法系列篇】遞歸、搜索和回溯(四),算法,算法,遞歸,搜索,回溯
知道了什么是決策樹(shù),下面我們將運(yùn)用決策樹(shù)來(lái)解決實(shí)際問(wèn)題。

1. 全排列

https://leetcode.cn/problems/permutations/

1.1 題目要求

給定一個(gè)不含重復(fù)數(shù)字的數(shù)組 nums ,返回其 所有可能的全排列 。你可以 按任意順序 返回答案。

示例 1:

輸入:nums = [1,2,3]
輸出:[[1,2,3],[1,3,2],[2,1,3],[2,3,1],[3,1,2],[3,2,1]]

示例 2:

輸入:nums = [0,1]
輸出:[[0,1],[1,0]]

示例 3:

輸入:nums = [1]
輸出:[[1]]

提示:

1 <= nums.length <= 6
-10 <= nums[i] <= 10
nums 中的所有整數(shù) 互不相同
class Solution {
    public List<List<Integer>> permute(int[] nums) {

    }
}

1.2 做題思路

相信大家肯定做過(guò)跟排列相關(guān)的問(wèn)題,就是三個(gè)人坐座位的問(wèn)題。第一座位可以坐A、B、C 任何一個(gè)人,如果第一個(gè)座位坐的是 A 的話,那么第二個(gè)位子 A 就不能再坐了,第二個(gè)位子就只能在 B、C 之間選擇了,如果 B 選擇了第二個(gè)位子,那么第三個(gè)位置就只能 C 選擇了。所以這個(gè)問(wèn)題通過(guò)決策樹(shù)來(lái)體現(xiàn)的話就是這樣的:

【算法系列篇】遞歸、搜索和回溯(四),算法,算法,遞歸,搜索,回溯
但是上面的圖我們會(huì)發(fā)現(xiàn)這幾種情況會(huì)有重復(fù)的情況,那么我們?nèi)绾魏Y選掉這些重復(fù)的情況呢?可以使用一個(gè)標(biāo)記數(shù)組來(lái)記錄已經(jīng)選擇過(guò)的元素,當(dāng)下一次選擇的時(shí)候就選擇這個(gè)標(biāo)記數(shù)組中沒(méi)有被選擇的剩下的元素的其中一個(gè)。這道題目跟上面的例子的思路是一樣的,這里我就不為大家再畫(huà)一個(gè)圖了。

那么這道題使用代碼的思想該如何解決呢?每次遞歸我們還是將數(shù)組中的所有元素都給列舉出來(lái),不過(guò)我們需要根據(jù)標(biāo)記數(shù)組中元素的使用情況來(lái)選擇是否可以選擇這個(gè)元素,如果某個(gè)元素沒(méi)有被選擇,那么這次就選擇這個(gè)元素,將這個(gè)元素標(biāo)記為已使用,然后繼續(xù)遞歸,當(dāng)當(dāng)前情況列舉完成之后就需要恢復(fù)現(xiàn)場(chǎng),當(dāng)路徑集合中記錄的元素的個(gè)數(shù)和數(shù)組中的元素個(gè)數(shù)相同的時(shí)候,就說(shuō)明一種情況已經(jīng)列舉完成,就可以將當(dāng)前情況添加進(jìn)ret集合中,返回。

1.3 代碼實(shí)現(xiàn)

class Solution {
    List<Integer> path;
    List<List<Integer>> ret;
    boolean[] vis;
    public List<List<Integer>> permute(int[] nums) {
        //對(duì)全局變量進(jìn)行初始化
        path = new ArrayList<>();
        ret = new ArrayList<>();
        vis = new boolean[nums.length];
        dfs(nums);
        return ret;
    }

    private void dfs(int[] nums) {
    	//當(dāng)path中元素的大小等于數(shù)組的大小,就說(shuō)明一種情況已經(jīng)列舉完成,這事需要我們將當(dāng)前path中的數(shù)據(jù)添加進(jìn)ret中,并且返回
        if (path.size() == nums.length) {
            ret.add(new ArrayList<>(path));
            return;
        }
       for (int i = 0; i < nums.length; i++) {
           if (vis[i] == false) {
               path.add(nums[i]);
               //將當(dāng)前元素標(biāo)記為已使用
               vis[i] = true;
               //考慮該位置之后的其他元素的選擇
               dfs(nums);
               //恢復(fù)現(xiàn)場(chǎng)
               path.remove(path.size() - 1);
               vis[i] = false;
           }
       }
    }
}

【算法系列篇】遞歸、搜索和回溯(四),算法,算法,遞歸,搜索,回溯

2. 子集

https://leetcode.cn/problems/subsets/

2.1 題目要求

給你一個(gè)整數(shù)數(shù)組 nums ,數(shù)組中的元素 互不相同 。返回該數(shù)組所有可能的子集(冪集)。

解集 不能 包含重復(fù)的子集。你可以按 任意順序 返回解集。

示例 1:

輸入:nums = [1,2,3]
輸出:[[],[1],[2],[1,2],[3],[1,3],[2,3],[1,2,3]]

示例 2:

輸入:nums = [0]
輸出:[[],[0]]

提示:

1 <= nums.length <= 10
-10 <= nums[i] <= 10
nums 中的所有元素 互不相同
class Solution {
    public List<List<Integer>> subsets(int[] nums) {

    }
}

2.2 做題思路

前面全排列中是當(dāng)路徑集合中的元素個(gè)數(shù)和數(shù)組中的元素的個(gè)數(shù)相同的時(shí)候視為一種情況,這道題目就不一樣了,這個(gè)是數(shù)組的子集,也就是說(shuō)每一種情況的元素的個(gè)數(shù)可能是不一樣的,所以我們路徑集合每新添加一個(gè)元素就可以視為一種情況,就需要將路徑中的元素添加進(jìn)ret集合中,思路跟上一道題目是類似的,都是通過(guò)決策樹(shù)遞歸來(lái)實(shí)現(xiàn)的,但是呢?仔細(xì)看題目可以發(fā)現(xiàn),就是集合[1,2],[2,1]是一種情況,也就是說(shuō)子集的選擇跟順序無(wú)關(guān),那么我們又該如何避免出現(xiàn)重復(fù)的情況呢?

這其實(shí)也不難,想想如果是在數(shù)學(xué)中我們會(huì)怎樣思考?如果當(dāng)前位置我們選擇了某個(gè)元素,那么后面的位置我們就從這個(gè)元素的后面元素中去選擇。

【算法系列篇】遞歸、搜索和回溯(四),算法,算法,遞歸,搜索,回溯
所以通過(guò)代碼體現(xiàn)的話,就是我們可以使用一個(gè) pos 變量來(lái)記錄當(dāng)前位置選擇的元素的下標(biāo),然后下一個(gè)位置選擇元素遞歸的話,我們就從 pos 的下一個(gè)位置開(kāi)始選擇。

2.3 代碼實(shí)現(xiàn)

class Solution {
    List<Integer> path;
    List<List<Integer>> ret;
    public List<List<Integer>> subsets(int[] nums) {
        path = new ArrayList<>();
        ret = new ArrayList<>();
        dfs(nums, 0)
        return ret;
    }

    private void dfs(int[] nums, int pos) {
        //進(jìn)入這個(gè)函數(shù)就可以將path中的結(jié)果添加進(jìn)ret中,這樣就可以將空集的情況給考慮上
        ret.add(new ArrayList<>(path));
        //循環(huán)的話,就從pos位置開(kāi)始遍歷
        for (int i = pos; i < nums.length; i++) {
            path.add(nums[i]);
            dfs(nums, i + 1);
            path.remove(path.size() - 1);
        }
    }
}

【算法系列篇】遞歸、搜索和回溯(四),算法,算法,遞歸,搜索,回溯

3. 找出所有子集的異或總和再求和

https://leetcode.cn/problems/sum-of-all-subset-xor-totals/

3.1 題目要求

一個(gè)數(shù)組的 異或總和 定義為數(shù)組中所有元素按位 XOR 的結(jié)果;如果數(shù)組為 空 ,則異或總和為 0 。

例如,數(shù)組 [2,5,6] 的 異或總和 為 2 XOR 5 XOR 6 = 1 。
給你一個(gè)數(shù)組 nums ,請(qǐng)你求出 nums 中每個(gè) 子集 的 異或總和 ,計(jì)算并返回這些值相加之 和 。

注意:在本題中,元素 相同 的不同子集應(yīng) 多次 計(jì)數(shù)。

數(shù)組 a 是數(shù)組 b 的一個(gè) 子集 的前提條件是:從 b 刪除幾個(gè)(也可能不刪除)元素能夠得到 a 。

示例 1:

輸入:nums = [1,3]
輸出:6
解釋:[1,3] 共有 4 個(gè)子集:
- 空子集的異或總和是 0 。
- [1] 的異或總和為 1 。
- [3] 的異或總和為 3 。
- [1,3] 的異或總和為 1 XOR 3 = 2 。
0 + 1 + 3 + 2 = 6

示例 2:

輸入:nums = [5,1,6]
輸出:28
解釋:[5,1,6] 共有 8 個(gè)子集:
- 空子集的異或總和是 0 。
- [5] 的異或總和為 5 。
- [1] 的異或總和為 1 。
- [6] 的異或總和為 6 。
- [5,1] 的異或總和為 5 XOR 1 = 4 。
- [5,6] 的異或總和為 5 XOR 6 = 3 。
- [1,6] 的異或總和為 1 XOR 6 = 7 。
- [5,1,6] 的異或總和為 5 XOR 1 XOR 6 = 2 。
0 + 5 + 1 + 6 + 4 + 3 + 7 + 2 = 28

示例 3:

輸入:nums = [3,4,5,6,7,8]
輸出:480
解釋:每個(gè)子集的全部異或總和值之和為 480 。

提示:

1 <= nums.length <= 12
1 <= nums[i] <= 20
class Solution {
    public int subsetXORSum(int[] nums) {

    }
}

3.2 做題思路

這道題目跟上面的子集思路基本上沒(méi)什么區(qū)別,之不過(guò)上面的子集是要求出所有子集的情況,而這道題目是求出所有子集異或之后的總和。因?yàn)樗悸坊靖蟼€(gè)題一樣,所以我們直接來(lái)看代碼。

3.3 代碼實(shí)現(xiàn)

class Solution {
    int path;
    int ret;
    public int subsetXORSum(int[] nums) {
        dfs(nums, 0);
        return ret;
    }

    private void dfs(int[] nums, int pos) {
        //前面是將集合添加進(jìn)ret中,這里我們是將每種情況加進(jìn)ret中
        ret += path;
        for (int i = pos; i < nums.length; i++) {
            //這里我們不是將新加入的元素加入到path集合中,而是將新加入的元素和之前path元素的異或的結(jié)果異或
            path ^= nums[i];
            dfs(nums, i + 1);
            //恢復(fù)現(xiàn)場(chǎng)(兩個(gè)相同的元素異或,結(jié)果為0)
            path ^= nums[i];
        }
    }
}

【算法系列篇】遞歸、搜索和回溯(四),算法,算法,遞歸,搜索,回溯

4. 全排列II

https://leetcode.cn/problems/permutations-ii/

4.1 題目要求

給定一個(gè)可包含重復(fù)數(shù)字的序列 nums ,按任意順序 返回所有不重復(fù)的全排列。

示例 1:

輸入:nums = [1,1,2]
輸出:
[[1,1,2],
[1,2,1],
[2,1,1]]

示例 2:

輸入:nums = [1,2,3]
輸出:[[1,2,3],[1,3,2],[2,1,3],[2,3,1],[3,1,2],[3,2,1]]

提示:

1 <= nums.length <= 8
-10 <= nums[i] <= 10
class Solution {
    public List<List<Integer>> permuteUnique(int[] nums) {

    }
}

4.2 做題思路

這道題目跟 全排列I 是不一樣的,全排列I 中不存在重復(fù)的元素,但是這道題目中存在重復(fù)的元素,也就是說(shuō)[1, 1, 2] 和 [1, 1, 2] 是同一個(gè)排列,這不看起來(lái)就是同一個(gè)排列嗎?難道還能不同嗎?其實(shí)這里的 1 不是同一個(gè)1,[1(下標(biāo)為0), 1(下標(biāo)為1), 2],[1(下標(biāo)為1), 1(下標(biāo)為0), 2],全排列I 中我們只需要使用一個(gè)標(biāo)記數(shù)組來(lái)避免同一個(gè)元素被重復(fù)使用的情況,而這個(gè) 全排列II 中,我們還需要篩選出因元素相同而導(dǎo)致的相同排列的情況。那么如何篩選呢?我們來(lái)看個(gè)例子:

【算法系列篇】遞歸、搜索和回溯(四),算法,算法,遞歸,搜索,回溯

4.3 代碼實(shí)現(xiàn)

class Solution {
    List<Integer> path;
    List<List<Integer>> ret;
    boolean[] vis;
    public List<List<Integer>> permuteUnique(int[] nums) {
        path = new ArrayList<>();
        ret = new ArrayList<>();
        vis = new boolean[nums.length];
        //首先將重復(fù)元素給排序到一起
        Arrays.sort(nums);
        dfs(nums);
        return ret;
    }

    private void dfs(int[] nums) {
        if (path.size() == nums.length) {
            ret.add(new ArrayList<>(path));
            return;
        }
        for (int i = 0; i < nums.length; i++) {
            if (vis[i] == false && (i == 0 || (nums[i - 1] != nums[i]) || vis[i - 1] == true)) {
                path.add(nums[i]);
                vis[i] = true;
                dfs(nums);
                //恢復(fù)現(xiàn)場(chǎng)
                path.remove(path.size() - 1);
                vis[i] = false;
            }
        }
    }
}

【算法系列篇】遞歸、搜索和回溯(四),算法,算法,遞歸,搜索,回溯文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-760837.html

到了這里,關(guān)于【算法系列篇】遞歸、搜索和回溯(四)的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

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

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

相關(guān)文章

  • 遞歸、搜索與回溯算法(專題六:記憶化搜索)

    遞歸、搜索與回溯算法(專題六:記憶化搜索)

    目錄 1. 什么是記憶化搜索(例子:斐波那契數(shù)) 1.1 解法一:遞歸 1.2 解法二:記憶化搜索 1.2.1 記憶化搜索比遞歸多了什么? 1.2.2 提出一個(gè)問(wèn)題:什么時(shí)候要使用記憶化搜索呢? 1.3 解法三:動(dòng)態(tài)規(guī)劃 1.3.1 先復(fù)習(xí)一下動(dòng)態(tài)規(guī)劃的核心步驟(5個(gè)),并將動(dòng)態(tài)規(guī)劃的每一步對(duì)應(yīng)

    2024年01月20日
    瀏覽(19)
  • 遞歸、搜索與回溯算法(專題二:深搜)

    遞歸、搜索與回溯算法(專題二:深搜)

    往期文章(希望小伙伴們?cè)诳催@篇文章之前,看一下往期文章) (1)遞歸、搜索與回溯算法(專題零:解釋回溯算法中涉及到的名詞)【回溯算法入門(mén)必看】-CSDN博客 (2)遞歸、搜索與回溯算法(專題一:遞歸)-CSDN博客 ?深搜是實(shí)現(xiàn)遞歸的一種方式,接下來(lái)我們之間從題

    2024年01月20日
    瀏覽(18)
  • 【C++】遞歸,搜索與回溯算法入門(mén)介紹和專題一講解

    【C++】遞歸,搜索與回溯算法入門(mén)介紹和專題一講解

    個(gè)人主頁(yè):??在肯德基吃麻辣燙 我的gitee:C++倉(cāng)庫(kù) 個(gè)人專欄:C++專欄 從本文開(kāi)始進(jìn)入遞歸,搜索與回溯算法專題講解。 遞歸就是函數(shù)自己調(diào)用自己。 遞歸的本質(zhì)是: 主問(wèn)題:—相同的子問(wèn)題 子問(wèn)題:—相同的子問(wèn)題 通過(guò): 1)通過(guò)遞歸的細(xì)節(jié)展開(kāi)圖(前期可以,過(guò)了前期

    2024年02月09日
    瀏覽(15)
  • 專題一:遞歸【遞歸、搜索、回溯】

    專題一:遞歸【遞歸、搜索、回溯】

    什么是遞歸 函數(shù)自己調(diào)用自己的情況。 為什么要用遞歸 主問(wèn)題-子問(wèn)題????????子問(wèn)題-子問(wèn)題 宏觀看待遞歸 不要在意細(xì)節(jié)展開(kāi)圖,把函數(shù)當(dāng)成一個(gè)黑盒,相信這個(gè)黑盒一定能完成任務(wù)。 ?如何寫(xiě)好遞歸 ? 分析跟上一題差不多,不詳解。 實(shí)現(xiàn)?pow(x,?n)?,即計(jì)算? x ?的整

    2024年02月07日
    瀏覽(15)
  • 專題二:二叉樹(shù)的深搜【遞歸、搜索、回溯】

    專題二:二叉樹(shù)的深搜【遞歸、搜索、回溯】

    深度優(yōu)先遍歷 (DFS,全稱為DepthFirstTraversal),是我們樹(shù)或者圖這樣的數(shù)據(jù)結(jié)構(gòu)中常用的?種遍歷算法。這個(gè)算法會(huì)盡可能深的搜索樹(shù)或者圖的分?,直到?條路徑上的所有節(jié)點(diǎn)都被遍歷完畢,然后再回溯到上?層,繼續(xù)找?條路遍歷。 在?叉樹(shù)中,常?的深度優(yōu)先遍歷為:

    2024年02月07日
    瀏覽(21)
  • 遞歸回溯兩個(gè)例題:1.數(shù)組組合 2.在矩陣中搜索單詞

    遞歸回溯兩個(gè)例題:1.數(shù)組組合 2.在矩陣中搜索單詞

    題目1:組合 給定兩個(gè)整數(shù) n 和 k ,返回范圍 [1, n] 中所有可能的 k 個(gè)數(shù)的組合。 你可以按 任何順序 返回答案。 輸入:n = 4, k = 2 輸出: [ ? [2,4], ? [3,4], ? [2,3], ? [1,2], ? [1,3], ? [1,4], ] ?解題思路: 1.定義一個(gè)temp數(shù)組,存放臨時(shí)的組合結(jié)果 2.兩種選擇:1.選擇當(dāng)前元素2.不選

    2024年02月15日
    瀏覽(21)
  • 算法與數(shù)據(jù)結(jié)構(gòu)——遞歸算法+回溯算法——八皇后問(wèn)題

    算法與數(shù)據(jù)結(jié)構(gòu)——遞歸算法+回溯算法——八皇后問(wèn)題

    八皇后問(wèn)題是一個(gè)經(jīng)典的回溯算法問(wèn)題,目的是在8×8的國(guó)際象棋棋盤(pán)上放置八個(gè)皇后,使得沒(méi)有皇后可以互相攻擊(即沒(méi)有兩個(gè)皇后在同一行、同一列或同一對(duì)角線上)。 回溯算法是一種解決問(wèn)題的算法,它通過(guò)嘗試所有可能的解決方案來(lái)解決問(wèn)題。在八皇后問(wèn)題中,計(jì)算

    2024年02月09日
    瀏覽(22)
  • 算法 矩陣最長(zhǎng)遞增路徑-(遞歸回溯+動(dòng)態(tài)規(guī)劃)

    ??途W(wǎng): BM61 求矩陣的最長(zhǎng)遞增路徑 解題思路: 1. 遍歷二維矩陣每個(gè)位置,max求出所有位置分別為終點(diǎn)時(shí)的最長(zhǎng)路徑 2. 求某個(gè)位置為終點(diǎn)的最長(zhǎng)路徑時(shí),使用動(dòng)態(tài)規(guī)劃dp對(duì)已經(jīng)計(jì)算出的位置進(jìn)行記錄 3. 處理某個(gè)位置的最長(zhǎng)路徑時(shí),如果dp[i][j]位置已有值,則直接返回即可,否則

    2024年02月07日
    瀏覽(26)
  • 【算法】遞歸、回溯、剪枝、dfs 算法題練習(xí)(組合、排列、總和問(wèn)題;C++)

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

    后面的練習(xí)是接著下面鏈接中的文章所繼續(xù)的,在對(duì)后面的題練習(xí)之前,可以先將下面的的文章進(jìn)行了解??: 【算法】{畫(huà)決策樹(shù) + dfs + 遞歸 + 回溯 + 剪枝} 解決排列、子集問(wèn)題(C++) 思路 題意分析 :要求根據(jù)給出的數(shù)字,算出合法的括號(hào)組成個(gè)數(shù)。根據(jù)題目,我們可以總

    2024年02月22日
    瀏覽(24)
  • DSt:數(shù)據(jù)結(jié)構(gòu)的最強(qiáng)學(xué)習(xí)路線之?dāng)?shù)據(jù)結(jié)構(gòu)知識(shí)講解與刷題平臺(tái)、刷題集合、問(wèn)題為導(dǎo)向的十大類刷題算法(數(shù)組和字符串、棧和隊(duì)列、二叉樹(shù)、堆實(shí)現(xiàn)、圖、哈希表、排序和搜索、動(dòng)態(tài)規(guī)劃/回溯法/遞歸/貪心/分治)總

    Algorithm:【算法進(jìn)階之路】之算法面試刷題集合—數(shù)據(jù)結(jié)構(gòu)知識(shí)和算法刷題及其平臺(tái)、問(wèn)題為導(dǎo)向的十大類刷題算法(數(shù)組和字符串、鏈表、棧和隊(duì)列、二叉樹(shù)、堆、圖、哈希表、排序和搜索、回溯算法、枚舉/遞歸/分治/動(dòng)態(tài)規(guī)劃/貪心算法)總結(jié) 目錄 相關(guān)文章

    2024年02月08日
    瀏覽(34)

覺(jué)得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

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

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包