最小的

题目 #

牛客网

输入n个整数,找出其中最小的K个数。例如输入4,5,1,6,2,7,3,8这8个数字,则最小的4个数字是1,2,3,4,

解题思路 #

Partition #

该算法基于 Partition

public ArrayList<Integer> GetLeastNumbers_Solution_Partition(int[] input, int k) {
    ArrayList<Integer> res = new ArrayList<>();

    if (k > input.length || k < 1) {
        return res;
    }

    int start = 0, end = input.length - 1;
    int index = partition(input, start, end);
    while (index != k - 1) {
        if (index > k - 1) {
            end = index - 1;
            index = partition(input, start, end);
        } else {
            start = index + 1;
            index = partition(input, start, end);
        }
    }

    for (int i = 0; i < input.length && i < k; i++) {
        res.add(input[i]);
    }
    return res;
}

private int partition(int[] nums, int start, int end) {
    int left = start, right = end;
    int key = nums[left];

    while (left < right) {
        while (left < right && nums[right] > key) {
            right--;
        }
        if (left < right) {
            nums[left] = nums[right];
            left++;
        }

        while (left < right && nums[left] <= key) {
            left++;
        }
        if (left < right) {
            nums[right] = nums[left];
            right++;
        }
    }

    nums[left] = key;

    return left;
}

小根堆算法 #

该算法基于小根堆,适合海量数据,时间复杂度为:n*logk

public ArrayList<Integer> GetLeastNumbers_Solution(int[] input, int k) {
    ArrayList<Integer> res = new ArrayList<>();
    if (k > input.length||k==0) {
        return res;
    }

    for (int i = input.length - 1; i >= 0; i--) {
        minHeap(input, 0, i);

        swap(input, 0, i);

        res.add(input[i]);
        if (res.size() == k) break;
    }
    return res;
}

private void minHeap(int[] heap, int start, int end) {
    if (start == end) {
        return;
    }

    int childLeft = start * 2 + 1;
    int childRight = childLeft + 1;

    if (childLeft <= end) {
        minHeap(heap, childLeft, end);

        if (heap[childLeft] < heap[start]) {
            swap(heap, start, childLeft);
        }
    }

    if (childRight <= end) {
        minHeap(heap, childRight, end);

        if (heap[childRight] < heap[start]) {
            swap(heap, start, childRight);
        }
    }
}

private void swap(int[] nums, int a, int b) {
    int t = nums[a];
    nums[a] = nums[b];
    nums[b] = t;
}