0
点赞
收藏
分享

微信扫一扫

【Leetcode】Permutations II

hwwjian 2023-07-26 阅读 51


题目链接:https://leetcode.com/problems/permutations-ii/

题目:

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], and [2,1,1].


思路:

 1、获取数组下标的全排列,然后将每个排列转化为数组元素的排列,再将结果放入HashSet中去除重复解。其中判断cur前所有下标和当前下标是否冲突需要一次for循环即for (int j = 0; j < cur; j++) ,导致超时。

2、在上述思路的基础上,用空间换时间,用used数组标记 nums数组元素的下标是否被用过。对每个下标无需判断是否和前面的是否冲突,即省略了一个for循环,提交果然AC了O(∩_∩)O~~

算法1:超时

int[] nums;
	List<List<Integer>> iLists = new ArrayList<List<Integer>>();
	HashSet<List<Integer>> hs = new HashSet<List<Integer>>();
	List<Integer> list = new ArrayList<Integer>();
	int cl[]; // 存放排列结果
	int per[];// 存放排列数组下标

	public List<List<Integer>> permuteUnique(int[] nums) {
		this.nums = nums;
		cl = new int[nums.length];
		per = new int[nums.length];
		dspPermute(0);
		iLists.addAll(hs);
		return iLists;
	}

	void dspPermute(int cur) {
		if (cur == nums.length) {
			hs.add(new ArrayList<Integer>(list));
		} else {
			for (int i = 0; i < nums.length; i++) { // 探索每一列
				per[cur] = i;// 数组下标的组合
				boolean flag = true;
				for (int j = 0; j < cur; j++) {// cur前所有行 若无冲突
					if (per[cur] == per[j])
						flag = false;
				}
				if (flag == true) {
					list.add(nums[per[cur]]);
					dspPermute(cur + 1);
					list.remove(list.size() - 1);
				}
			}
		}
	}




算法2:

int[] nums;
	List<List<Integer>> iLists = new ArrayList<List<Integer>>();
	HashSet<List<Integer>> hs = new HashSet<List<Integer>>();
	List<Integer> list = new ArrayList<Integer>();
	int cl[]; // 存放排列结果
	int per[];// 存放排列数组下标
	boolean used[];//表示数组下标是否被使用过

	public List<List<Integer>> permuteUnique(int[] nums) {
		this.nums = nums;
		cl = new int[nums.length];
		per = new int[nums.length];
		used = new boolean[nums.length];
		dspPermute(0);
		iLists.addAll(hs);
		return iLists;
	}

	void dspPermute(int cur) {
		if (cur == nums.length) {
			hs.add(new ArrayList<Integer>(list));
		} else {
			for (int i = 0; i < nums.length; i++) { // 探索每一列
				if(used[i]) //如果该下标被用过
					continue;
				per[cur] = i;// 数组下标的组合
				used[i] = true;
				list.add(nums[per[cur]]);
				dspPermute(cur + 1);
				list.remove(list.size() - 1);
				used[i]=false;//记得要复原,否则走到底后used数组全为true,跟list要remove道理一样
			}
		}
	}




举报

相关推荐

0 条评论