在ArrayList中查找最大的未重复数

时间:2015-01-17 04:43:30

标签: java algorithm sorting for-loop compare

我需要一种算法,找出只在ArrayList中出现一次的最大数字。

例如,假设我有ArrayList<Integer>元素

[3, 3, 3, 6, 7, 8, 8, 9, 9, 9]

这里,我需要的算法会产生数字7,因为它是列表中最大的未重复数字。

前提条件:

  • 输入列表保证排序。

  • 输入列表始终包含至少一个非重复的数字。

4 个答案:

答案 0 :(得分:2)

如果我们假设输入列表已排序,我们应该能够在O(N)中执行此操作,而无需额外的空间。

public static Integer maxUnduplicatedVal(ArrayList<Integer> lst){
    if(lst == null || lst.isEmpty()) 
        return null;
    if(lst.size() == 1) return lst.get(0);

    if(! lst.get(lst.size() - 1).equals(lst.get(lst.size() - 2))) 
        return lst.get(lst.size() - 1);

    for(int i = lst.size() - 2; i > 0; i--){
        Integer next = lst.get(i + 1);
        Integer here = lst.get(i);
        Integer prev = lst.get(i - 1);
        if(! next.equals(here) && ! prev.equals(here)) return here;
    }

    if(! lst.get(0).equals(lst.get(1))) return lst.get(0);
    return null; //All duplicates
}

如果并不总是排序,最快的方法是创建列表的副本,然后删除重复项,然后在Collections中调用max函数。制作副本是一个非常好的主意 - 吸气者真的不应该改变他们收到的收藏品。 (这包括对给定集合进行排序)。

private static List<Integer> getUniques(List<Integer> list) {
    HashMap<Integer, Boolean> flagMap = new HashMap<>();

    //Total Loop: O(N)
    for(Integer i : list){
        if(flagMap.containsKey(i)) flagMap.put(i, false); //O(1)
        else flagMap.put(i, true); //O(1)
    }

    ArrayList<Integer> result = new ArrayList<Integer>();

    //Total Loop: O(N)
    for(Integer i : list){
        if(flagMap.get(i)) result.add(i); //O(1)
    }
    return result;
}

public static Integer maxUnduplicatedVal(ArrayList<Integer> lst){
    List<Integer> lstCopy = getUniques(lst);
    return Collections.max(lstCopy);
}

这仍然是O(N),同时还有一些额外的空间要求。

答案 1 :(得分:2)

Collections.frequency可能在这里有用......

    Integer[] myArr = {3, 3, 3, 6, 7, 8, 8, 9, 9, 9}; // sample array
    ArrayList<Integer> myList = new ArrayList<Integer>(Arrays.asList( myArr ) );

    // creating a set from an ArrayList will remove any duplicate elements
    HashSet<Integer> mySet = new HashSet<Integer>(myList);

    /* Make sure list isn't empty or null here, etc. */

    Integer largest = null;

    // iterate through the set, ensuring you don't examine duplicates
    for ( Integer i : mySet ) {

        // if the frequency of that element is 1, we can compare it
        if ( Collections.frequency(myList, i) == 1 )
        {
            if ( largest == null )
            {
                largest = i; // base case
            } else if ( i > largest ) {
                largest = i;
            }
        }
    }

    System.out.println( "The largest non-duplicate is " + largest );
    // or return, etc.

答案 2 :(得分:1)

最好的方法是在元素列表的排序数组中找到未重复的元素。因此,通过这样做,我们可以分离未重复元素的列表,然后我们可以找到列表中最大的元素。

建议您参考以下链接了解详情。

Find the unduplicated element in a sorted array

-Bruce

答案 3 :(得分:1)

这是Algo

1)如果列表尚未排序,首先执行Collections.sort(list)

2)从最后一个开始,因为它是最大数字并获得其索引

3)检查该索引处的数字是否等于index-1处的数字,如果是,则它是最大的重复数字,否则重复此步骤为index-1