【每日一題】力扣1046.最後一塊石頭的重量

Josvin發表於2020-12-30

題目描述(傳送門

有一堆石頭,每塊石頭的重量都是正整數。

每一回合,從中選出兩塊 最重的 石頭,然後將它們一起粉碎。假設石頭的重量分別為 x 和 y,且 x <= y。那麼粉碎的可能結果如下:

如果 x == y,那麼兩塊石頭都會被完全粉碎;
如果 x != y,那麼重量為 x 的石頭將會完全粉碎,而重量為 y 的石頭新重量為 y-x。
最後,最多隻會剩下一塊石頭。返回此石頭的重量。如果沒有石頭剩下,就返回 0。

示例:

輸入:[2,7,4,1,8,1]
輸出:1
解釋:
先選出 78,得到 1,所以陣列轉換為 [2,4,1,1,1],
再選出 24,得到 2,所以陣列轉換為 [2,1,1,1],
接著是 21,得到 1,所以陣列轉換為 [1,1,1],
最後選出 11,得到 0,最終陣列轉換為 [1],這就是最後剩下那塊石頭的重量。

解題思路

方法一:sort暴力

對stones 陣列進行排序,然後將最大的兩個相減,差值更新到len-1下標,另一個更新為0.對陣列在進行排序。。
一直這樣迴圈,每次排序之後都保證了,兩個最大值相減,最後迴圈結束,剩下的最大值就是最後剩下的那塊石頭的重量。

public int lastStoneWeight(int[] stones) {
        Arrays.sort(stones);
        int len = stones.length;
        while (len-- >=0) {
            stones[stones.length-1] = stones[stones.length-1] - stones[stones.length - 2];
            stones[stones.length-2] = 0;
            Arrays.sort(stones);
        }
        return stones[stones.length - 1];
    }

方法二:大頂堆

PriorityQueue的深入解析

利用PriorityQueue優先佇列實現大堆,相關用法可以檢視API以及原始碼。
構造方法:
在這裡插入圖片描述
介面方法:
在這裡插入圖片描述

public int lastStoneWeight(int[] stones) {
         PriorityQueue<Integer> priorityQueue = new PriorityQueue<Integer>((a, b) -> b - a);
         /**
			 * 重寫compare方法。
			 * 在此體現了所謂的"自定義":即根據自己所寫邏輯來決定實現最大/小堆
			 */
		// a-b  則是小根堆
        for (int stone : stones
                ) {
            priorityQueue.offer(stone);
        }

        
        while (priorityQueue.size() > 1) {
            int a = priorityQueue.poll();
            int b = priorityQueue.poll();
            if (a - b > 0) {
                priorityQueue.offer(a - b);
            }
        }
        return priorityQueue.isEmpty()?0:priorityQueue.poll();
    }

相關文章