(两百三十九)leetcode-堆 最后一块石头的重量

1.题目

有一堆石头,每块石头的重量都是正整数。

每一回合,从中选出两块 最重的 石头,然后将它们一起粉碎。假设石头的重量分别为 x 和 y,且 x <= y。那么粉碎的可能结果如下:

如果 x == y,那么两块石头都会被完全粉碎;
如果 x != y,那么重量为 x 的石头将会完全粉碎,而重量为 y 的石头新重量为 y-x。
最后,最多只会剩下一块石头。返回此石头的重量。如果没有石头剩下,就返回 0。

 

示例:

输入:[2,7,4,1,8,1]
输出:1
解释:
先选出 7 和 8,得到 1,所以数组转换为 [2,4,1,1,1],
再选出 2 和 4,得到 2,所以数组转换为 [2,1,1,1],
接着是 2 和 1,得到 1,所以数组转换为 [1,1,1],
最后选出 1 和 1,得到 0,最终数组转换为 [1],这就是最后剩下那块石头的重量。
 

提示:

1 <= stones.length <= 30
1 <= stones[i] <= 1000


来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/last-stone-weight
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

 

 

2.思路

既然是堆系列的题目,用堆来实现就好了,先用堆对数组进行最大堆的存储,然后碎石的时候,先移除倒数第二大的,将最后的数值挪到倒数第二大那边,然后若小于父亲节点,进行下沉,否则进行上浮。(由于是最大堆,所以肯定是下沉)之后将最大的进行减法,若为0,则继续移除最大的,否则对减后的数值进行下沉操作。

 

3.coding

class Solution {
    public int lastStoneWeight(int[] stones) {
        //初始化最大堆
        initMaxHeap(stones);
        System.out.println("Solution" + Arrays.toString(stones));
        int size = stones.length;
        while (size > 1) {
            //移除并记录第二大的元素,将最后一个数值与第二大数组进行交换,第二大位置进行下沉操作
            int second = (size > 2) ? ((stones[1] > stones[2]) ? 1 : 2) : 1;
            int secondValue = stones[second];
            swap(second, size - 1, stones);
            size--;
            sink(second, stones, size);
            System.out.println("Solution" + Arrays.toString(stones));
            //第一大元素减去第二大元素,若为0,则和最后一个元素作交换,对位置0进行下沉操作
            stones[0] = stones[0] - secondValue;
            if (stones[0] == 0) {
                swap(0, size - 1, stones);
                size--;
            }
            sink(0, stones, size);
            System.out.println("Solution" + Arrays.toString(stones));
        }


        return size == 0 ? 0 : stones[0];
    }

    void initMaxHeap(int[] arr) {
        for (int i = 1; i < arr.length; i++) {
            rise(i, arr);
        }
    }

    void rise(int index, int[] arr) {
        int i = index;
        int parent = (i - 1) / 2;
        while (i != 0 && arr[parent] < arr[i]) {
            swap(parent, i, arr);
            i = parent;
            parent = (i - 1) / 2;
        }
    }

    void sink(int index, int[] arr, int size) {
        while (true) {
            int leftIndex = 2 * index + 1;
            int rightIndex = 2 * index + 2;
            if (leftIndex > size - 1) {
                //没有左孩子
                return;
            }
            if (rightIndex > size - 1) {
                //没有右孩子
                if (arr[index] < arr[leftIndex]) {
                    swap(index, leftIndex, arr);
                }
                return;
            }
            int swapIndex = arr[leftIndex] > arr[rightIndex] ? leftIndex : rightIndex;
            if (arr[swapIndex] > arr[index]) {
                swap(swapIndex, index, arr);
                index = swapIndex;
            } else {
                return;
            }
        }
    }

    void swap(int i, int j, int[] arr) {
        int temp = arr[i];
        arr[i] = arr[j];
        arr[j] = temp;
    }


}

 

 

 

 

相关推荐
©️2020 CSDN 皮肤主题: 鲸 设计师:meimeiellie 返回首页