代码随想录算法训练营Day29 | 491.非递减子序列、46.全排列、47.全排列 II

491.非递减子序列

这题不能对原序列进行排序,想了半天最后还是用回了set来去重。其他方面与之前题型差不多,按模板写即可。

判断子序列是否递增只需要将当前元素与path尾元素对比即可。

vector> ans;
vector path;

void backtracking(int startIndex, vector& nums) {
	if (path.size() >= 2)
		ans.push_back(path);
	
	// 每层设置一个set来进行树层去重
	// 由于本题nums元素有限定范围,所以也可以使用数组来进行哈希映射
	unordered_set record;
	for (int i = startIndex; i < nums.size(); ++i) {
        // 第一次使用该值 且 该元素可以组成非递减序列
		if (record.find(nums[i]) == record.end() && (path.empty() || nums[i] >= path.back())) {
			record.insert(nums[i]);
			path.push_back(nums[i]);
			backtracking(i + 1, nums);
			path.pop_back();
		}
	}
}

// 这题不能先排序,只能想到set去重:<
vector> findSubsequences(vector& nums) {
	backtracking(0, nums);
	return ans;
}

46.全排列

排列问题与组合问题的差别:

        排列问题不需要startIndex,而是每次都从第一个元素开始选取。相对的,一次排列中已经使用过的元素在之后的排列过程中不可再次被选中

明白了排列问题的特点,问题就变为如何知道哪些元素已经被使用过了。其解法也比较容易想到了:使用used数组标记使用过的元素

vector> ans;
vector path;

void backtracking(vector& used, vector nums) {
	if (path.size() == nums.size()) {
		ans.push_back(path);
		return;
	}

	for (int i = 0; i < nums.size(); ++i) {
        // 当前排列中已经使用过的元素不再使用
		if (!used[i]) {
			path.push_back(nums[i]);
			used[i] = true;
			backtracking(used, nums);
			used[i] = false;
			path.pop_back();
		}
	}
}

vector> permute(vector& nums) {
    // 使用used数组来标记使用过的元素,初始全为false
	vector used(nums.size(), false);
	backtracking(used, nums);
	return ans;
}

47.全排列 II

由于我习惯的树层去重写法不基于used数组,所以这题其实就是46全排列后面加上两行树层去重的代码。

如果树层去重也基于used数组或许可以更简短一些?

vector> ans;
vector path;

void backtracking(vector used, vector nums) {
	if (path.size() == nums.size()) {
		ans.push_back(path);
		return;
	}

	for (int i = 0; i < nums.size(); ++i) {
		if (!used[i]) {
			path.push_back(nums[i]);
			used[i] = true;
			backtracking(used, nums);
			used[i] = false;
			path.pop_back();
			// 与46.全排列相比,就多了两行树层去重的代码
			while (i + 1 < nums.size() && nums[i + 1] == nums[i])
				++i;
		}
	}
}

vector> permuteUnique(vector& nums) {
	std::sort(nums.begin(), nums.end());
	vector used(nums.size(), false);
	backtracking(used, nums);
	return ans;
}

你可能感兴趣的:(算法,数据结构)