小根堆的解法。一定要注意边界的处理。忽略了几处的边界处理居然可以通过10个用例

1. 初始化堆,自底向上初始化,如果发生了交换,就要该节点自顶向下交换
2. 每次调整选中一个最小的,放入list

import java.util.ArrayList;

public class Solution {
    private void swap(int[] input, int i, int j) {
        int t = input[i];
        input[i] = input[j];
        input[j] = t;
    }
    private void initHeap(int[] input) {
        int length = (input.length - 1) / 2;
        // 边界条件 i >= length,不能忽略
        for (int i = input.length - 1; i >= length; i--) {
            
            int j = i;
            while (j != 0) {
                int parent = (j-1)/2;
                if (input[j] < input[parent]) {
                    swap(input, j, parent);
                    // 向下调整
                    adjust(input, parent, input.length - 1);
                }
                j = parent;
            }
        }
    }
    
    private void adjust(int[] input, int start, int length) {
        if (length == 0) {
            return;
        }
        while (start <= (length - 1) / 2) {
            int left = 2 * start + 1;
            int right = 2 * start + 2;
            int minIndex = left;
            // 这里一定要小于等于
            if(right <= length) {
                minIndex = input[left] < input[right] ? left : right;
            }
            if (input[minIndex] < input[start]) {
                swap(input, minIndex, start);
            }
            start  = minIndex;
        }
    }

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

        initHeap(input);
        list.add(input[0]);
        swap(input, 0, input.length - 1);
        for(int i = 1; i < k; i++) {
            adjust(input, 0, input.length - i - 1);
            list.add(input[0]);
            swap(input, 0, input.length - 1 - i);
        }
        return list;
    }
}