[路飞]最后一块石头的重量

340 阅读1分钟

记录 1 道算法题

最后一块石头的重量

leetcode-cn.com/problems/la…

拿出最大的两块石头,相互销毁,把剩余的重量放回去。再次拿出最大的两个石头,相互销毁然后放回去。重复这样的步骤。

最后会剩下最多一个石头的重量。或者为0。

  1. 如果是暴力的解法,只需要在放回去的时候将数组重新排序就可以了。

        function lastStoneWeight(stones) {
            // 先排序一遍
            stones.sort((a, b) => a - b)
            while (stones.length > 1) {
                // 拿出最大的两个
                const a = stones.pop() ?? 0
                const b = stones.pop() ?? 0
                // 推进去
                stones.push(a - b)
                // 重新排序
                stones.sort((a,b) => a - b)
            }
    
            return stones.length > 0 ? stones[0] : 0
        }
    
  2. 使用大根堆

    大根堆是什么呢, 大根堆是存放最大的几个数的容器,堆顶是最大的数。所以当我们用数组进行模拟的时候,我们需要使这个数组是升序排列的,最后一个元素就是最大的数。

        function lastStoneWeight(stones) {
            stones.sort((a,b) => a - b)
            while(stones.length > 1) {
                // 最后一个减前一个,只要是保证升序,就一定是 >=0
                const c = stones.pop() - stones.pop()
                // 放回去
                stones.push(c)
                let i = stones.length
                // 从后面开始遍历,处理刚推进去的 c
                // 因为已经是升序的,所以当停下来的时候就代表 c 已经找到正确的位置了
                while(stones[i] < stones[i - 1]) {
                    const temp = stones[i]
                    stones[i] = stones[i - 1]
                    stones[i + 1] = temp
                    i--
                }
            }
            // 最后最多会有一位。
            return stones[0] ?? 0
        }
    

    结束