全排列去重
Posted linukey
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了全排列去重相关的知识,希望对你有一定的参考价值。
全排列去重的前提要求是目标集合必须是经过排序的。
在目标集合排序的前提下,第i位变换数字前后,如果是相同的数字,就会产生重复的排列。
注意:第i位变换的意思是i位本身的变换,而不是i与i-1的比较。
[题目链接](https://leetcode.cn/problems/permutations-ii)
代码如下:
void dfs(const vector<int>& nums, int pos, vector<vector<int>>& result, vector<int>& cur)
if (pos == nums.size())
result.push_back(cur);
return;
for (int i = 0; i < nums.size(); ++i)
// 控制i位 and 全排列去重
if (Visited[i] || (i > 0 && nums[i] == nums[i - 1] && !Visited[i - 1]))
continue;
Visited[i] = true;
cur.push_back(nums[i]);
dfs(nums, pos + 1, result, cur);
cur.pop_back();
Visited[i] = false;
vector<vector<int>> permuteUnique(vector<int>& nums)
vector<vector<int>> result;
vector<int> cur;
// 全排列去重的关键是排序过的集合
sort(nums.begin(), nums.end());
dfs(nums, 0, result, cur);
return result;
java 全排列,去重全排列,全组合
import java.util.ArrayList;
import java.util.List;
public class Test {
ArrayList<List<Integer>> list = new ArrayList<List<Integer>> ();
public List<List<Integer>> permute(int[] nums) {
solve(nums, 0, nums.length-1);
System.out.println(list.toString());
return list;
}
/**
* 算法思想
* 让每一个元素做首个元素,剩下的start+1递归全排列,之后再换回来,恢复初始状态,让下一个元素做首个元素
* @param nums
* @param start
* @param end
*/
public void solve(int[] nums, int start, int end) {
if (start == end) {
list.add(convert(nums));
}
// 每个元素都尝试和第一个元素互换,剩下的再递归
for (int i=start; i<=end; i++) {
// 判断第i个元素是否需要和start互换。从start开始判断到i前一个位置是否有和nums[i]相同的元素,如果有表示该元素做过第一个元素,不需要再进行排列
if (isSwap(nums, start, i)) {
swap(nums, i, start); //
solve(nums, start+1, end);
swap(nums, start, i); // 处理完再换回来
}
}
}
public boolean isSwap(int[] num, int m, int n) {
for (int j=m;j<n;j++) {
if (num[j] == num[n]) {
return false;
}
}
return true;
}
public void swap(int[] nums, int x, int y) {
if (x == y) return;
System.out.println("交换" + x + ":" + y);
int temp = nums[x];
nums[x] = nums[y];
nums[y] = temp;
}
public List<Integer> convert(int[] nums) {
ArrayList<Integer> listTemp = new ArrayList<Integer>();
for(int i=0;i<nums.length;i++) {
listTemp.add(nums[i]);
}
return listTemp;
}
public static void main(String[] args) {
int[] aa = new int[]{1, 2, 3 };
Test n = new Test();
//n.permute(aa);
Character[] ch = new Character[]{'a', 'b', 'c'};
n.solve2(ch);
}
// 全组合 如a,b,c=>a,b,c,ab,ac,bc,abc
/**
* 共有2^n-1个结果。对应于位图 001
* @param arr
* @return
*/
public String[] solve2(Character[] arr) {
int length = arr.length;
int n = 1<<length;
for (int i=1;i<n;i++) {
for (int j=0;j<length;j++) {
if ((i & (1<<j)) > 0) {
System.out.print(""+arr[j]);
}
}
System.out.println();
}
return null;
}
}
以上是关于全排列去重的主要内容,如果未能解决你的问题,请参考以下文章
java 字符串全排列 和 去重
[Mdfs] lc剑指 Offer 38. 字符串的排列(全排列+枚举顺序+组合类型枚举+知识理解+模板题)
LeetCode-回溯全排列 II
全排列
Leetcode篇:全排列II
47. 全排列 II