zoukankan      html  css  js  c++  java
  • 47. Permutations II(medium, backtrack, 重要, 条件较难思考)

    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();
    		}
    	}
    }
    
  • 相关阅读:
    面试官问:为什么 Java 线程没有 Running 状态?我懵了
    阿里内部员工,排查Java问题常用的工具单
    面试美团,面试官突然问我 Java “锁” ,我哭了
    python optparse模块的用法
    cmd的终结工具cmder
    python的pexpect模块
    thinkpad8平板安装win10系统
    linux系统中set、env、export关系
    网件wndr4300 ttl连接
    Ubuntu下修改缺省dash shell为bash shell
  • 原文地址:https://www.cnblogs.com/ZhongliangXiang/p/7509462.html
Copyright © 2011-2022 走看看