无重复数组,算法

nwnhqdif  于 2021-07-11  发布在  Java
关注(0)|答案(3)|浏览(312)

我必须写一个函数,返回给定的数组排序,没有重复。
我想出了这样的解决办法:

public static String [] no_repeats(String [] a)
    {
        Arrays.sort(a);

        ArrayList<String> ret = new ArrayList<>();
        for (int i =1; i < a.length; i++)
                   if(a[i].compareTo(a[i-1]) != 0)
                       ret.add(a[i]);

        return  ret.toArray(ret.toArray(new String[0]));
    }

我想知道有没有更好(更快)的办法解决我的问题?这里不允许像set这样的集合。

omvjsjqw

omvjsjqw1#

既然你被要求分类,我想这是一个很好的方法。该算法只是跟踪最后添加的值,以确保不添加重复项。

public static String[] no_repeats(String[] a) {

    Arrays.sort(a);

    ArrayList<String> ret = new ArrayList<>();
    String lastAdded = "";
    for (String str : a) {
        if (!str.equals(lastAdded)) {
            ret.add(str);
        }
        lastAdded = str;
    }
    return ret.toArray(new String[0]);
}

当然,您可以编写自己的最小哈希实现,以加快在本地哈希集中的查找。在这种情况下,跳过重复元素后的排序将是一种方法,因为基于哈希的查找与 List.contains() 打电话,效率很高。然后你就可以在更少的项目上排序了。
下面是使用您自己的set实现来加速流程的方式。
如果元素已经存在,则set.add()返回false。
所以当它返回true时,一定是第一次遇到它,所以将它添加到列表中。
现在排序一个较小的列表。
返回数组。

public static String[] no_repeats(String[] a) {

    MiniHashSet<String> set = new MiniHashSet<>();

    ArrayList<String> ret = new ArrayList<>();

    for (String str : a) {
        if (set.add(str)) {
            ret.add(str);
        }
    }

    Collections.sort(ret);
    return ret.toArray(new String[0]);
}

这是一个简单的实现,它只有一个add-and-contains方法来加速查找过程。哈希表的大小相当大,以减少冲突的可能性。
这个类使用对象的hashcode来获得正确的 bucket 列出清单。
每一个列表都可能包含散列到该存储桶中的所有项目-返回的bucket要么是数组中该索引的现有列表,要么是以前不存在的新列表。

@SuppressWarnings("unchecked")
class MiniHashSet<T> {
    int size = 10_000;

    List<T>[] data = new ArrayList[size];

    public boolean add(T val) {
        List<T> b = getBucket(val);
        if (!b.contains(val)) {
            b.add(val);
            return true;
        }
        return false;
    }

    public boolean contains(T val) {
        List<T> b = getBucket(val);
        return b.contains(val);
    }

    private List<T> getBucket(T val) {
        int i = val.hashCode() % size;
        List<T> b = data[i];
        if (b == null) {
            b = new ArrayList<>();
            data[i] = b;
        }
        return b;
    }
}

虽然这是一个相当多的额外工作,这个解决方案明显优于我提供的第一个,因为查找是有效的,排序现在可能发生后,重复已删除。

pjngdqdw

pjngdqdw2#

使用流可以优雅地解决此问题:

public static String[] no_repeats(String[] a) {
    return Arrays.stream(a)
            .distinct()
            .sorted()
            .toArray(String[]::new);
}
zpjtge22

zpjtge223#

排序,然后检查元素是否相等(如果相等,则它们在一起)

public static String[] no_repeats(String[] a)
    {
        Arrays.sort(a);
        ArrayList<String> al = new ArrayList<String>();
        al.add(a[0]);
        for(int i = 1;i<a.length;i++) {
            if(!a[i].equals(a[i - 1])) {
                al.add(a[i]);
            }
        }

        return  al.toArray(new String[0]);
    }

相关问题