LintCode 16. 带重复元素的排列

写在前面:这题和全排列不含重复元素的那题几乎一样,我比较垃圾,就用HashSet去掉了重复的元素但是看了九章算法的答案也没看懂,他写的很有感觉。

用了hash,本来想着怎么写hashcode()和equal()方法的,哪知道都帮我写好了,Integer类型的元素存储在List中的hashcode()和equal()的方法可以直接使用
下面是源代码和我的测试代码:

//这是ArrayList父类public abstract class AbstractList中的源码
public int hashCode() {
        int hashCode = 1;
        for (E e : this)
            hashCode = 31*hashCode + (e==null ? 0 : e.hashCode());
        return hashCode;
    }

public boolean equals(Object o) {
        if (o == this)
            return true;
        if (!(o instanceof List))
            return false;

        ListIterator e1 = listIterator();
        ListIterator e2 = ((List) o).listIterator();
        while (e1.hasNext() && e2.hasNext()) {
            E o1 = e1.next();
            Object o2 = e2.next();
            if (!(o1==null ? o2==null : o1.equals(o2)))
                return false;
        }
        return !(e1.hasNext() || e2.hasNext());
    }
@Test
    public void test() {
        List list1 = new ArrayList<>();
        list1.add(1);
        List list2 = new ArrayList<>();
        list2.add(2);
        List list3 = new ArrayList<>();
        list3.add(1);

        System.out.println(list1.hashCode());
        System.out.println(list2.hashCode());
        System.out.println(list3.hashCode());
        System.out.println(list1==list2);
        System.out.println(list1==list3);
        System.out.println(list2==list3);
        System.out.println(list1.equals(list2));
        System.out.println(list1.equals(list3));
        System.out.println(list2.equals(list3));
        }
//运行结果
//        32
//        33
//        32
//        false
//        false
//        false
//        false
//        true
//        false

下面是我写的代码,只是使用HashSet去重

import org.junit.Test;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;

public class permuteUnique {
    /**
     * @param : A list of integers
     * @return: A list of unique permutations
     * 

* 16. 带重复元素的排列 * 给出一个具有重复数字的列表,找出列表所有不同的排列。 *

* 样例 * 给出列表 [1,2,2],不同的排列有: *

* [ * [1,2,2], * [2,1,2], * [2,2,1] * ] * 挑战 * 使用递归和非递归分别完成该题。 *

* 写过不含重复元素的全排列,这提是含重复元素的,应该相差不大 */ public List> permuteUnique(int[] nums) { // write your code here HashSet> hashResult = new HashSet<>(); List> result = new ArrayList<>(); List list = new ArrayList<>(); if (nums == null) { return result; } if (nums.length == 0) { result.add(list); return result; } boolean[] color = new boolean[nums.length]; for (int i = 0; i < nums.length; i++) { color[i] = false; } dfs(hashResult, list, nums, color); result = new ArrayList<>(hashResult); return result; } public void dfs(HashSet> hashResult, List list, int[] nums, boolean[] color) { if (list.size() == nums.length) { hashResult.add(new ArrayList<>(list)); return; } for (int i = 0; i < nums.length; i++) { if (color[i] == false) { list.add(nums[i]); color[i] = true; dfs(hashResult, list, nums, color); color[i] = false; list.remove(list.size() - 1); } } } @Test public void testPermuteUnique() { // List> result = permuteUnique(new int[]{1, 2, 2}); // for (int i = 0; i < result.size(); i++) { // System.out.println(result.get(i).toString()); // } } }


下面是九章的答案,写的很难懂,狠巧妙
和没有重复元素的 Permutation 一题相比,只加了两句话:

Arrays.sort(nums) // 排序这样所有重复的数
if (i > 0 && nums[i] == nums[i - 1] && !visited[i - 1]) { continue; } // 跳过会造成重复的情况

    public List> permuteUnique(int[] nums) {
        List> results = new ArrayList<>();
        if (nums == null) {
            return results;
        }

        Arrays.sort(nums);
        dfs(nums, new boolean[nums.length], new ArrayList(), results);

        return results;
    }


      private void dfs(int[] nums,
                     boolean[] visited,
                     List permutation,
                     List> results) {
        if (nums.length == permutation.size()) {
            results.add(new ArrayList(permutation));
            return;
        }

        for (int i = 0; i < nums.length; i++) {
            if (visited[i]) {
                continue;
            }
            if (i > 0 && nums[i] == nums[i - 1] && !visited[i - 1]) {
                continue;
            }

            permutation.add(nums[i]);
            visited[i] = true;
            dfs(nums, visited, permutation, results);
            visited[i] = false;
            permutation.remove(permutation.size() - 1);
        }
    } 

你可能感兴趣的:(算法题)