[Leetcode题解 --- 2] 深度优先搜索

一. 引例

1. 求数组的全排列

Leetcode 46: 给定一个 没有重复 数字的序列,返回其所有可能的全排列。

输入: [1,2,3]
输出:
[
  [1,2,3],
  [1,3,2],
  [2,1,3],
  [2,3,1],
  [3,1,2],
  [3,2,1]
]

 

[Leetcode题解 --- 2] 深度优先搜索_第1张图片

以上图为例,初始的状态为空,我们首先将上述树看作一个多叉树,每次从左到右遍历,在叶子节点处得到最大长度的序列,实现代码如下,

# include 
# include 
# include 

using namespace std;

class Solution {
public:
    vector> results;
    vector temp;
    vector used;
    void dfs(vector &nums, vector &used, int count) {
        int len = nums.size();

        // 递归终止条件
        if (count == len) {
            results.push_back(temp);
            return;
        }

        for (int i = 0; i < len; i++) {
            if (used[i]) 
                continue;

            temp.push_back(nums[i]);

            used[i] = true;
            count = count + 1;

            dfs(nums, used, count);
            
            temp.pop_back();
            
            used[i] = false;
            count = count - 1;
        }
    }
    vector> permuteUnique(vector& nums) {
        if (nums.size() == 0)
            return results;
        int len = nums.size();
        for (int i = 0; i < len; i++) used.push_back(false);
        dfs(nums, used, 0); 
        return results;
    }
};

int main() {
	Solution solution;
	vector nums({1, 2, 3});
	vector> results = solution.permuteUnique(nums);
	for (int i = 0; i < results.size(); i++) {
		for (int j = 0; j < results[i].size(); j++) 
			cout << results[i][j] << "\t";
		cout << endl;
	}
	return 0;
} 

2. 求重复数组的全排列

若数组中出现重复元素,则涉及到DFS的一个基本操作,剪枝,关键就在于如何选择剪枝的条件。

Leetcode 47: 给定一个可包含重复数字的序列,返回所有不重复的全排列。

输入: [1,1,2]
输出:
[
  [1,1,2],
  [1,2,1],
  [2,1,1]
]

        与无重复元素的全排列不同,此时多了一种特殊条件,当遍历到位置为 i 的节点( i > 0 )时,如果nums[i] == nums[i-1],并且nums[i-1]未遍历过,说明此时nums[i-1]在这次遍历中会出现在nums[i]之后,因此需要额外设置添加条件。

# include 
# include 
# include 

using namespace std;

class Solution {
public:
    vector> results;
    vector temp;
    vector used;
    void dfs(vector &nums, vector &used, int count) {
        int len = nums.size();

        // 递归终止条件
        if (count == len) {
            results.push_back(temp);
            return;
        }

        for (int i = 0; i < len; i++) {
            if (used[i]) 
                continue;
            if (i > 0 && nums[i] == nums[i-1] && !used[i-1])
                continue;

            temp.push_back(nums[i]);

            used[i] = true;
            count = count + 1;

            dfs(nums, used, count);
            
            temp.pop_back();
            
            used[i] = false;
            count = count - 1;
        }
    }
    vector> permuteUnique(vector& nums) {
        if (nums.size() == 0)
            return results;
        sort(nums.begin(), nums.end());
        int len = nums.size();
        for (int i = 0; i < len; i++) used.push_back(false);
        dfs(nums, used, 0); 
        return results;
    }
};

int main() {
	Solution solution;
	vector nums({1, 1, 2, 2});
	vector> results = solution.permuteUnique(nums);
	for (int i = 0; i < results.size(); i++) {
		for (int j = 0; j < results[i].size(); j++) 
			cout << results[i][j] << "\t";
		cout << endl;
	}
	return 0;
} 

 

你可能感兴趣的:(LeetCode)