Spurs

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::

Given a collection of numbers that might contain duplicates, return all possible unique permutations.

For example,
[1,1,2] have the following unique permutations:

[
  [1,1,2],
  [1,2,1],
  [2,1,1]
]

本题有重复元素,条件较难思考,做这个题费了小劲.
总体框架是应用 backtrack 解决.

样例:[1 1 2] -> [1 2 1] -> [2 1 1]
设定一个 vector<bool> used(A.size(), false); 表示哪些元素用过, 用过的用true表示.

[1 1 2] -> [1 2 1] dfs到这种状态后, i 将要为 1, 就是下面的样子.

[1 1 2] 此时所有的 used[0 - 2] 都为 false.
   i

if (i > 0 && A[i - 1] == A[i] && !used[i - 1]) continue; // <--这句话,想不出来啊

若无上面那个判断条件(有这个标志的那行 '<--'),将会再次产生下面的序列:
[1 1 2], 这里的第一个1是上面i=1所指的元素,第二个1是i=0的元素.

为防止这种事的发生,就应该跳过i=1的那个元素, 仔细观察, 发现:

  1. i > 0;
  2. A[i] = A[i-1];
  3. A[i-1] = false;

满足上述3条的元素, 就应跳过!

经验: 想写清楚条件,必须把简单例子用笔纸走一遍; 找出自己跑的结果与正确结果不同之处; 针对错误点, 设置if()语句,避免之!

自己代码:

// e.g.
// [1 1 2] -> [1 2 1] -> [2 1 1]
vector<vector<int>> permuteUnique(vector<int>& A) {
	sort(A.begin(), A.end());
	vector < vector<int> > res;
	vector<int> temp;

	// 用 used[0-2], true 表用过
	vector<bool> used(A.size(), false);
	backtrack(res, temp, A, used);
	return res;
}

void backtrack(vector<vector<int> >& res, vector<int>& temp, vector<int>& A,
		vector<bool> used) {
	if (temp.size() == A.size())
		res.push_back(temp);
	else {
		for (int i = 0; i < A.size(); i++) {
			if (used[i] == true) {
				continue;
			}
			if (i > 0 && A[i - 1] == A[i] && !used[i - 1])
				continue; // <--这句话,想不出来啊
			// [1 1 2] -> [1 2 1]  dfs到这种状态后, i 将要为 1, 就是下面的样子.

			// [1 1 2]    此时所有的 used[0 - 2] 都为 false.
			//    i
			// 若无上面那个判断条件(有这个标志的那行 '<--'),将会再次产生下面的序列:
			// [1 1 2], 这里的第一个1是上面i=1所指的元素,第二个1是i=0的元素
			// 为防止这种事的发生,就应该跳过i=1的那个元素, 仔细观察, 发现:
			// 1. i > 0;
			// 2. A[i] = A[i-1];
			// 3. A[i-1] = false;
			// 满足上述3条的元素,就应跳过!
			// 
			// 经验:
			// 想写清楚条件,必须把简单例子用笔纸走一遍;
			// 找出自己跑的结果与正确结果不同之处;
			// 针对错误点,设置if()语句,避免之!

			temp.push_back(A[i]);
			used[i] = true;
			backtrack(res, temp, A, used);
			used[i] = false;
			temp.pop_back();
		}
	}
}
posted on 2017-09-12 12:04  英雄与侠义的化身  阅读(167)  评论(0编辑  收藏  举报