成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

LeetCode 關(guān)于回溯問題的看法

ASCH / 2180人閱讀

摘要:回溯算法在算法過程中就是類似于枚舉算法,嘗試在搜索過程中找到問題的解。

回溯算法( BackTrack )在算法過程中就是類似于枚舉算法,嘗試在搜索過程中找到問題的解。
使用回溯算法解題的一般步驟

使用回溯算法解題的一般步驟:

針對(duì)所給問題得出一般的解空間

用回溯搜索方法搜索解空間

使用深度優(yōu)先去搜索所有解并包含適當(dāng)?shù)募糁Σ僮?/p>

LeetCode 使用回溯算法的題目主要有 36 題,代表性有 N Queens(51,52), SubSets(78), Permutation(46(distinct), 47(with duplicates)), Combination, Combination Sum.

Problems

SubSets:

Given a set of distinct integers, nums, return all possible subsets (the power set).

Note: The solution set must not contain duplicate subsets.
For example,
If nums = [1,2,3], a solution is:
[[3],[1],[2],[1,2,3],[1,3],[2,3],[1,2],[]]

SubSets 這道題要求 print 出定長(zhǎng) int array 中所有子集合,使用回溯算法遍歷定長(zhǎng) array,然后回溯來選擇出所有可能的組合.

針對(duì) backTrack 時(shí)間復(fù)雜度的分析直接復(fù)習(xí)結(jié)果集的大小有效

Runtime: O(2^n), Space: O(n)

Solution:

public List> subsets(int[] nums) {
    if(nums == null || nums.length == 0) return null;`                
    List> res = new ArrayList>();
    helper(nums, res, 0, new ArrayList<>());
    return res;       
}
    
public void helper(int[] nums, List> res, int index, List temp) {
    //考慮空子集的情況
    res.add(new ArrayList<>(temp));
    for(int i = index; i < nums.length; i++) {
        //每次加下一個(gè)index的element
        temp.add(nums[i]);
        //深度優(yōu)先到下一層
        helper(nums, res, i + 1, temp);
        //backTracking
        temp.remove(temp.size() - 1);
    }
}

針對(duì)如果輸入數(shù)組有重復(fù)的元素,但是要求輸出的結(jié)果沒有重復(fù),可以一些去重的方法并注意防止溢出

If nums = [1,2,2], a solution is
[[2],[1],[1,2,2],[2,2],[1,2],[]]

Solution:

public List> subsetsWithDup(int[] nums) {
    if(nums == null || nums.length == 0) return null;
    List> res = new ArrayList>();
    //對(duì)input數(shù)組進(jìn)行排序,準(zhǔn)備為數(shù)組進(jìn)行去重
    Arrays.sort(nums);
    helper(nums, res, 0, new ArrayList<>());
    return res;
}
    
public void helper(int[] nums, List> res, int index, List temp) {
    res.add(new ArrayList<>(temp));
    for(int i = index; i < nums.length; i++) {
        //去重復(fù),并且防止溢出
        if(i != index && nums[i] == nums[i - 1]) continue;
        temp.add(nums[i]);
        helper(nums, res, i + 1, temp);
        temp.remove(temp.size() - 1);
    }
}
Combination Sum

Given a set of candidate numbers (C) (without duplicates) and a target number (T), find all unique combinations in C where the candidate numbers sums to T.

The same repeated number may be chosen from C unlimited number of times.

Note:
All numbers (including target) will be positive integers.
The solution set must not contain duplicate combinations.

For example, given candidate set [2, 3, 6, 7] and target 7, A solution set is:
[[7],[2, 2, 3]]

這道題要求given一個(gè)定長(zhǎng)數(shù)組,要求找到所有子數(shù)組集合以至于子數(shù)組所有數(shù)的和等于目標(biāo)數(shù),可以運(yùn)用回溯算法,區(qū)間為given的定長(zhǎng)數(shù)組

Solution:

同樣是用回溯的方法,但是針對(duì)數(shù)組中子數(shù)可以重復(fù)使用
time:O(2^n), space: O(n)

public List> combinationSum(int[] candidates, int target) {
    if(candidates == null || candidates.length == 0) return null;
    List> res = new ArrayList>();
    helper(candidates, target, res, new ArrayList(), 0);
    return res;
}

public void helper(int[] candidates, int target, List>res, List temp, int index) {
    if(target < 0) return;
    else if(taget == 0) res.add(new ArrayList(temp));
    else {
        for(int i = index; i < candidats.length; i++) {
        temp.add(candidates[i]);
        //DFS dive into next level, 因?yàn)樾枰貜?fù)使用所以遞歸調(diào)用i 沒有變化
        helper(candidates, target - candidates[i], res, temp, i);
        temp.remove(temp.size() - 1);
    }
}

變種,針對(duì)CombinationSum 數(shù)組中子數(shù)只可以被使用一次:
時(shí)間復(fù)雜度仍然為O(2^n), 空間復(fù)雜度為O(n)

public List> combinationSum(int[] candidates, int target) {
    if(candidates == null || candidates.length == 0) return null;
    List> res = new ArrayList>();
    helper(candidates, target, res, new ArrayList(), 0);
    return res;
}

public void helper(int[] candidates, int target, List>res, List temp, int index) {
        if(target < 0) return;
        else if(taget == 0) res.add(new ArrayList(temp));
        else {
            for(int i = index; i < candidats.length; i++) {
                //進(jìn)行防溢出和去重
                if(i != index && candidates[i] == candidates[i - 1]) continue;
                temp.add(candidates[i]);
                //DFS dive into next level, 因?yàn)樾枰貜?fù)使用所以遞歸調(diào)用i 沒有變化
                helper(candidates, target - candidates[i], res, temp, i);
                temp.remove(temp.size() - 1);
    }
}

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/68275.html

相關(guān)文章

  • 回溯算法講解--適用于leetcode絕大多數(shù)回溯題目

    摘要:什么是回溯算法回溯法是一種系統(tǒng)搜索問題解空間的方法。解空間定義為與數(shù)字長(zhǎng)度相同。最后,為什么要掌握回溯法因?yàn)槎嘶厮莘ㄖ蠊P試?yán)锏暮芏囝}就算不了,起碼成功運(yùn)行到之間是沒問題的。 什么是回溯算法?回溯法是一種系統(tǒng)搜索問題解空間的方法。為了實(shí)現(xiàn)回溯,需要給問題定義一個(gè)解空間。說到底它是一種搜索算法。只是這里的搜索是在一個(gè)叫做解空間的地方搜索。而往往所謂的dfs,bfs都是在圖或者樹這種數(shù)據(jù)...

    saucxs 評(píng)論0 收藏0
  • LeetCode偶爾一題 —— 39. Combination Sum(回溯算法系列)

    摘要:輸入輸出分析題目由于我們需要找到多個(gè)組合,簡(jiǎn)單的使用循環(huán)肯定是不行的,這時(shí)候我們可以使用回溯算法來解決這個(gè)問題。用回溯算法解決問題的一般步驟針對(duì)所給問題,定義問題的解空間,它至少包含問題的一個(gè)最優(yōu)解。 題目描述 Given a set of candidate numbers (candidates) (without duplicates) and a target number ...

    linkin 評(píng)論0 收藏0
  • LeetCode 刷題 (九)算法入門--回溯

    摘要:用來存放每一個(gè)可能的結(jié)果最終結(jié)果深度優(yōu)先遍歷剪枝當(dāng)遍歷到底個(gè)數(shù)是,如果的元素個(gè)數(shù)剩余元素個(gè)數(shù)時(shí),就不滿足條件了中元素個(gè)數(shù)達(dá)到,表示深度優(yōu)先遍歷到達(dá)最深處了。 ?77. 組合77. 組合77. 組合 給定兩個(gè)整數(shù)?n?和?k,返回范圍?[1, n]?中所有可能的?k?個(gè)數(shù)的組合。 你可以按?任...

    morgan 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<