leetcode专题训练 90. Subsets II

这道题是第78题的升级版,78题中所给数组的元素都是不相同的,所以直接回溯搞一发,每个元素都加或不加搞一发即可。然而这道题中元素可能是相同的,所以不能直接每个元素加或不加来搞。比如样例中的[1, 2, 2],只加前面的那个2和只加后面那个2的结果是重复的,所以需要对相同的数进行判断。
在78题中,一个长为l的数组,子集list的第一个元素可以是数组中的每一个元素,第二个元素就是第一个元素的索引之后的数组中的每一个元素,以此类推。解法如下:

class Solution:
    def subsets(self, nums: List[int]) -> List[List[int]]:
        output = []
        l = len(nums)

        def backtrack(begin: int, cur: List[int]):
            output.append(cur[:])
            for i in range(begin, l):
                cur.append(nums[i])
                backtrack(i+1, cur)
                cur.pop()
        
        backtrack(0, [])
        return output

而在本题中,第二个元素不能是第一个元素索引之后的数组的每一个元素,因为后面的元素有重复,所以如果取每一个元素的话,解会重复。所以第二个元素应该是后面的数组中不重复的元素(例:如果后面的元素是4,5,4,5,6,5,那么第二个元素可能为4,5,6),为了更好的得到这些不重复的元素,可以先将数组进行排序,这样重复的数字就会排在一起,取每个重复串的第一个元素即可得到后面的数组中不重复的元素。想到这里之后,将78题的代码改一下即可。答案如下:

class Solution:
    def subsetsWithDup(self, nums: List[int]) -> List[List[int]]:
        l = len(nums)
        nums.sort()
        result = []
        tmp = []
        def backtrack(ind: int):
            result.append(tmp[:])
            for i in range(ind, l):
                if i != ind and nums[i] == nums[i-1]:
                    continue
                tmp.append(nums[i])
                backtrack(i+1)
                tmp.pop()
            
        backtrack(0)
        return result

以上代码的c++实现如下:

class Solution {
     
    vector<vector<int>> result;
public:
    void dfs(vector<int>& nums, int ind, vector<int> tmp) {
     
        result.push_back(tmp);
        if(ind >= nums.size()) {
     
            return;
        }
        for(int i = ind; i < nums.size(); i++) {
     
            if(i != ind && nums[i] == nums[i-1]) {
     
                continue;
            }
            tmp.push_back(nums[i]);
            dfs(nums, i+1, tmp);
            tmp.pop_back();
        }
        return;
    }
    
    vector<vector<int>> subsetsWithDup(vector<int>& nums) {
     
        result.clear();
        sort(nums.begin(), nums.end());
        vector<int> tmp;
        tmp.clear();
        dfs(nums, 0, tmp);
        return result;
    }
};

我发现我不会写C++了,这不对劲,之后还是偶尔用c++搞一搞吧。

你可能感兴趣的:(leetcode专题训练 90. Subsets II)