Find the 2nd largest element in an array with minimum number of comparisons

后端 未结 24 1362
清酒与你
清酒与你 2020-11-28 01:03

For an array of size N, what is the number of comparisons required?

24条回答
  •  一个人的身影
    2020-11-28 01:17

    I know this is an old question, but here is my attempt at solving it, making use of the Tournament Algorithm. It is similar to the solution used by @sdcvvc , but I am using two-dimensional array to store elements.

    To make things work, there are two assumptions:
    1) number of elements in the array is the power of 2
    2) there are no duplicates in the array

    The whole process consists of two steps:
    1. building a 2D array by comparing two by two elements. First row in the 2D array is gonna be the entire input array. Next row contains results of the comparisons of the previous row. We continue comparisons on the newly built array and keep building the 2D array until an array of only one element (the largest one) is reached.
    2. we have a 2D-array where last row contains only one element: the largest one. We continue going from the bottom to the top, in each array finding the element that was "beaten" by the largest and comparing it to the current "second largest" value. To find the element beaten by the largest, and to avoid O(n) comparisons, we must store the index of the largest element in the previous row. That way we can easily check the adjacent elements. At any level (above root level),the adjacent elements are obtained as:

    leftAdjacent = rootIndex*2
    rightAdjacent = rootIndex*2+1,
    

    where rootIndex is index of the largest(root) element at the previous level.

    I know the question asks for C++, but here is my attempt at solving it in Java. (I've used lists instead of arrays, to avoid messy changing of the array size and/or unnecessary array size calculations)

    public static Integer findSecondLargest(List list) {
            if (list == null) {
                return null;
            }
            if (list.size() == 1) {
                return list.get(0);
            }
            List> structure = buildUpStructure(list);
            System.out.println(structure);
            return secondLargest(structure);
    
        }
    
        public static List> buildUpStructure(List list) {
            List> newList = new ArrayList>();
            List tmpList = new ArrayList(list);
            newList.add(tmpList);
            int n = list.size();
            while (n>1) {
                tmpList = new ArrayList();
                for (int i = 0; i> structure) {
            int n = structure.size();
            int rootIndex = 0;
            Integer largest = structure.get(n-1).get(rootIndex);
            List tmpList = structure.get(n-2);
            Integer secondLargest = Integer.MIN_VALUE;
            Integer leftAdjacent = -1;
            Integer rightAdjacent = -1;
            for (int i = n-2; i>=0; i--) {
                rootIndex*=2;
                tmpList = structure.get(i);
                leftAdjacent = tmpList.get(rootIndex);
                rightAdjacent = tmpList.get(rootIndex+1); 
                if (leftAdjacent.equals(largest)) {
                    if (rightAdjacent > secondLargest) {
                        secondLargest = rightAdjacent;
                    }
                }
                if (rightAdjacent.equals(largest)) {
                    if (leftAdjacent > secondLargest) {
                        secondLargest = leftAdjacent;
                    }
                    rootIndex=rootIndex+1;
                }
            }
    
            return secondLargest;
        }
    

提交回复
热议问题