Permutations II

来源:互联网 发布:最完美的丁丁长度 知乎 编辑:程序博客网 时间:2024/05/29 03:21

第一种方法(非递归)

算法的4个步骤和循环的退出条件我在注释中都写清楚了

class Solution {public:void swap(int &i, int &j){int temp = i;i = j;j = temp;}vector<vector<int> > permuteUnique(vector<int> &num){vector<vector<int>> res;int i, j, n = num.size();sort(num.begin(), num.end());res.push_back(num);while (true){int j_tmp = num.size();int j_val_tmp = INT_MAX;for (i = n - 2; i >= 0; i--)if (num[i] < num[i + 1])//1.从后向前遍历,找到相邻的两个数,且num[i]<num[i+1]break;if (i <= -1)//从后向前遍历已经到头,返回结果return res;for (j = n - 1; j > i; j--)//2.找到比num[i]大的第一个数,这个数是num[j_tmp]{if (num[j] > num[i] && num[j] < j_val_tmp){j_val_tmp = num[j];j_tmp = j;}}swap(num[i], num[j_tmp]);//3.交换num[i], num[j_tmp]for (int k = i + 1; k < (i + 1 + n) / 2; k++)//4.对num[i+1]到结尾的所有数逆序排列一次swap(num[k], num[n - (k - i)]);res.push_back(num);}}};

第二种方法(递归)

这种方法中有一个还原标记变量flag的过程,我称之为还原现场,这种递归的写法很有意思,学习到了

class Solution{public:vector<vector<int> > ans;vector<int>tmp;vector<bool>flag;vector<int>a;int n;void dfs(int index){if (index == n) { ans.push_back(tmp); return; }for (int i = 0; i < n; i++){if (flag[i] || (i - 1 >= 0 && a[i] == a[i - 1] && !flag[i - 1]))   continue;//1.如果当前元素已经压入结果了,则跳过    //2.若两个相邻元素相同且前一个元素已经压入结果,那么当前元素可以压入结果tmp.push_back(a[i]);//压入结果vectorflag[i] = true;//为进入递归做准备dfs(index + 1);tmp.pop_back();//还原现场flag[i] = false;//还原现场}}vector<vector<int> >permuteUnique(vector<int> &num){sort(num.begin(), num.end());ans.clear();tmp.clear();a.assign(num.begin(), num.end());n = num.size();flag.assign(n, false);dfs(0);return ans;}};


0 0
原创粉丝点击