Algorithm question output the nth largest number

foreword

Given an array and a number n, output the nth largest number in the array, such as an array

array = {1,4,6,5,4,7,8,9,10} 

n = 5

Then the output number is 6.

This article will provide several different writing methods, let's take a look at efficiency

text

The first

First of all, we think of sorting the array, using the Arrays.sort() method, and then counting the nth largest number from the back to the front, the code is as follows

/**
     * 给定一个数组和n,输出第n大数
     * 不存在则返回0
     *
     * @param arr 数组
     * @return 第n大的数
     */
    public static int findNMaxNumberVersion1(int[] arr, int n) {
        if (arr == null || arr.length == 0 || n > arr.length){
            return 0;
        }
        Arrays.sort(arr);
        return arr[arr.length - n];
    }

So let's think about it, is this method optimal?

It is definitely not optimal. We just want to find the nth largest number. The above solution sorts all the numbers, and there will inevitably be a lot of invalid operations, but this way of writing is the most concise.

the second

/**
     * 给定一个数组和n,输出第n大数
     * 不存在则返回0
     *
     * @param arr 数组
     * @return 第n大的数
     */
    public static int findNMaxNumberVersion2(int[] arr, int n) {
        if (arr == null || arr.length == 0 || n > arr.length){
            return 0;
        }
       int count = 0;
        for (int i = 0;i < arr.length;i++){
           int temp =  arr[0];
           int m = 0;
           int j = 1;
           while (j < arr.length){
               if (arr[j] > temp){
                   temp = arr[j];
                   m = j;
               }
               j++;
           }
           arr[m] = 0;
           count++;
           if (count == n){
               return temp;
           }
        }
        return 0;
    }

This way of writing is much more efficient than the first one. He will not sort all the numbers, but just reset the largest n - 1 numbers to 0 and return the nth number. For the remaining numbers, no repeated invalid calculations will be performed. So let's think about it, is there room for optimization in this solution? Obviously yes. We found that the above code resets the largest number to 0, but the reset data will be traversed next time. If the entire array has 10,000 elements, we need to find the 5,000th largest number, then the size of the traversal array will not decrease with the number of times, which means that the size of each traversal array is the same, each time traversing 10,000 times, this part of the traversal work is also invalid, since the analysis of the disadvantages, Let's look down.

third

/**
     * 给定一个数组和n,输出第n大数
     * 不存在则返回0
     *
     * @param arr 数组
     * @return 第n大的数
     */
    public static int findNMaxNumberVersion3(int[] arr, int n) {
        if (arr == null || arr.length == 0 || n > arr.length){
            return 0;
        }
        for (int i = 0; i < n ;i++){
            int j = i + 1;
            while (j < arr.length){
                if (arr[j] > arr[i]){
                    int temp = arr[i];
                    arr[i] = arr[j];
                    arr[j] = temp;
                }
                j++;
            }
        }
        return arr[n -1];
    }

These writing methods only traverse the first n numbers, and solve the disadvantage of the second method that the size of the array traversed each time is the same. I traverse arr.length times for the 0th number, and the number of times for the 1st number arr.length - 1 By analogy, if there are 10,000 elements, then the improved efficiency is obvious.

extend

This algorithm problem can also be extended to find the first n largest elements, which is not the nth largest element, but the first n largest elements. In fact, the solution is the same, but the results of each traversal will be saved.

Guess you like

Origin blog.csdn.net/zanpengfei/article/details/127277445