1. 程式人生 > 遊戲資訊 >從仇恨區角度看甘雨第一箭衰減問題

從仇恨區角度看甘雨第一箭衰減問題

✅做題思路or感想

這題主思路是回溯

要注意的是會有元素的重複,所以這裡要做樹層去重

以下去重是需要在排序後才能進行!!!!

candidates[i]candidates[i - 1]相同的情況下:

  • 如果used[i - 1] == true,則說明同一樹枝使用過candidates[i - 1]
  • 如果used[i - 1] == false,則說明同一樹層使用過candidates[i - 1]

如果在同一樹層使用過了,則直接continue就好了

class Solution {
public:
    vector<vector<int>>result;
    vector<int>temp;
    void dfs(vector<int>& candidates, int target, int startIndex, vector<bool>& used) {
        if (target < 0)return;	//容易想到的剪枝
        //若滿足,則加入result中
        if (target == 0) {	
            result.push_back(temp);
            return ;
        }
        //這裡有一個不容易想到的剪枝:target - candidates[i] >= 0,若不滿足這個條件,則直接結束遞迴。這個遞迴的使用前提是要用sort排序過遍歷的陣列
        for (int i = startIndex; i < candidates.size() && target - candidates[i] >= 0; i++) {
            //樹層去重
            if (i > 0 && candidates[i - 1] == candidates[i] && used[i - 1] == false)continue;
            temp.push_back(candidates[i]);
            used[i] = true;
            dfs(candidates, target - candidates[i], i + 1, used);
            //回溯
            used[i] = false;
            temp.pop_back();
        }
    }
    vector<vector<int>> combinationSum2(vector<int>& candidates, int target) {
        //注意排序!只有sort排序後,used陣列的樹層去重和for中的剪枝才能實現!!!!
        sort(candidates.begin(), candidates.end());
        vector<bool>used(candidates.size() + 1, false);
        dfs(candidates, target, 0, used);
        return result;
    }
};