Computer >> บทช่วยสอนคอมพิวเตอร์ >  >> การเขียนโปรแกรม >> Java

Java: หาค่า Max, Min, Second Max, Second Min ใน Array

วิธีการหาค่าสูงสุด ต่ำสุด อันดับ 2 สูงสุด ต่ำสุด ใน Array มีหลายวิธี ขึ้นอยู่กับ requirement และ constraints

วิธีที่ 1: ใช้ Arrays.sort() - ง่ายที่สุด

Time: O(n log n) | Space: O(1) additional (in-place sort)

import java.util.Arrays;

public class Demo {
    public static void main(String[] args) {
        int[] arr = {55, 10, 8, 90, 43, 87, 95, 25, 50, 12};
        
        System.out.println("Array = " + Arrays.toString(arr));
        Arrays.sort(arr);
        System.out.println("Sorted Array = " + Arrays.toString(arr));
        
        int n = arr.length;
        System.out.println("Smallest = " + arr[0]);
        System.out.println("2nd Smallest = " + arr[1]);
        System.out.println("Largest = " + arr[n - 1]);
        System.out.println("2nd Largest = " + arr[n - 2]);
    }
}

Output

Array = [55, 10, 8, 90, 43, 87, 95, 25, 50, 12]
Sorted Array = [8, 10, 12, 25, 43, 50, 55, 87, 90, 95]
Smallest = 8
2nd Smallest = 10
Largest = 95
2nd Largest = 90

วิธีที่ 2: Single Pass - O(n) Time, O(1) Space (Optimal)

หาทั้ง 4 ค่าในครั้งเดียวโดยไม่ต้อง sort

public class SinglePassDemo {
    public static void findMinMax(int[] arr) {
        if (arr == null || arr.length == 0) {
            System.out.println("Array is empty");
            return;
        }
        
        if (arr.length == 1) {
            System.out.println("Only one element: " + arr[0]);
            return;
        }

        int min = Integer.MAX_VALUE;
        int secondMin = Integer.MAX_VALUE;
        int max = Integer.MIN_VALUE;
        int secondMax = Integer.MIN_VALUE;

        for (int num : arr) {
            // Update min and secondMin
            if (num < min) {
                secondMin = min;
                min = num;
            } else if (num < secondMin && num != min) {
                secondMin = num;
            }

            // Update max and secondMax
            if (num > max) {
                secondMax = max;
                max = num;
            } else if (num > secondMax && num != max) {
                secondMax = num;
            }
        }

        System.out.println("Smallest: " + min);
        System.out.println("2nd Smallest: " + (secondMin == Integer.MAX_VALUE ? "N/A (all same)" : secondMin));
        System.out.println("Largest: " + max);
        System.out.println("2nd Largest: " + (secondMax == Integer.MIN_VALUE ? "N/A (all same)" : secondMax));
    }

    public static void main(String[] args) {
        int[] arr = {55, 10, 8, 90, 43, 87, 95, 25, 50, 12};
        System.out.println("Array = " + Arrays.toString(arr));
        findMinMax(arr);
        
        // Test edge cases
        System.out.println("\n--- All same ---");
        findMinMax(new int[]{5, 5, 5, 5});
        
        System.out.println("\n--- Two elements ---");
        findMinMax(new int[]{10, 20});
    }
}

Output

Array = [55, 10, 8, 90, 43, 87, 95, 25, 50, 12]
Smallest: 8
2nd Smallest: 10
Largest: 95
2nd Largest: 90

--- All same ---
Smallest: 5
2nd Smallest: N/A (all same)
Largest: 5
2nd Largest: N/A (all same)

--- Two elements ---
Smallest: 10
2nd Smallest: 20
Largest: 20
2nd Largest: 10

วิธีที่ 3: Manual Sort (Bubble Sort) - สำหรับการศึกษา

import java.util.Arrays;

public class ManualSortDemo {
    public static void main(String[] args) {
        int[] arr = {55, 10, 8, 90, 43, 87, 95, 25, 50, 12};
        
        System.out.println("Array = " + Arrays.toString(arr));
        
        // Bubble sort
        for (int i = 0; i < arr.length - 1; i++) {
            for (int j = 0; j < arr.length - 1 - i; j++) {
                if (arr[j] > arr[j + 1]) {
                    int temp = arr[j];
                    arr[j] = arr[j + 1];
                    arr[j + 1] = temp;
                }
            }
        }
        
        System.out.println("Sorted = " + Arrays.toString(arr));
        System.out.println("Smallest: " + arr[0]);
        System.out.println("2nd Smallest: " + arr[1]);
        System.out.println("Largest: " + arr[arr.length - 1]);
        System.out.println("2nd Largest: " + arr[arr.length - 2]);
    }
}

วิธีที่ 4: ใช้ Stream API (Java 8+)

import java.util.Arrays;
import java.util.Comparator;

public class StreamDemo {
    public static void main(String[] args) {
        int[] arr = {55, 10, 8, 90, 43, 87, 95, 25, 50, 12};

        // Min
        int min = Arrays.stream(arr).min().orElseThrow();
        // Max
        int max = Arrays.stream(arr).max().orElseThrow();
        
        // 2nd Min - distinct, sorted, skip 1
        int secondMin = Arrays.stream(arr)
            .distinct()
            .sorted()
            .skip(1)
            .findFirst()
            .orElseThrow(() -> new IllegalStateException("No 2nd min"));
            
        // 2nd Max - distinct, sorted descending, skip 1
        int secondMax = Arrays.stream(arr)
            .distinct()
            .boxed()
            .sorted(Comparator.reverseOrder())
            .skip(1)
            .findFirst()
            .orElseThrow(() -> new IllegalStateException("No 2nd max"));

        System.out.println("Min: " + min);
        System.out.println("2nd Min: " + secondMin);
        System.out.println("Max: " + max);
        System.out.println("2nd Max: " + secondMax);
    }
}

การจัดการ Duplicate Values

Input Min 2nd Min (distinct) 2nd Min (with duplicates)
[5, 5, 5, 5] 5 N/A 5
[1, 1, 2, 3] 1 2 1
[3, 2, 2, 1] 1 2 2

แนะนำ: ใช้ distinct values (unique) สำหรับ "2nd smallest/largest" ตามนิยามทางคณิตศาสตร์

สรุปการเลือกวิธี

วิธี Time Space เหมาะสำหรับ
Arrays.sort() O(n log n) O(1) General use, code เรียบง่าย, array ขนาดเล็ก-ปานกลาง
Single Pass O(n) O(1) Performance critical, large arrays, streaming data
Stream API O(n log n) O(n) Functional style, พร้อม distinct/filter
Manual Sort O(n²) O(1) การศึกษา/สอบเท่านั้น

Edge Cases ต้องจัดการ

  • Empty array → throw exception หรือ return Optional
  • Single element → 2nd min/max ไม่มี
  • All elements same → 2nd min/max ไม่มี (หรือเท่ากับ min/max ตามนิยาม)
  • Integer overflow - ใช้ long สำหรับการเปรียบเทียบถ้าจำเป็น