• 1046. 最后一块石头的重量


    一、题目描述:

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

    每一回合,从中选出两块 最重的 石头,然后将它们一起粉碎。假设石头的重量分别为 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

    二、思路分析:

    1. 这道题考察了什么思想?你的思路是什么?

    刚开始,我的思路是这样的。每次从石头中取出两个最重的(可以排序再取),然后将轻的移出队列,将重的减去轻的质量,然后再从石头中取出两个最重的(可以继续排序后再取)…

    直到队列长度为1,然后取这个元素即可。

    1. 做题的时候是不是一次通过的,遇到了什么问题,需要注意什么细节?

    但是我忽略了一个问题,就是Go语言使用for range遍历切片时,操作的是副本,移出队列的操作并不会影响实际队列,因此这样就会导致失败,但是我们可以采用一种取巧的方式,我们将要去除的元素值设置为0,然后每次进行排序,仅操作排序后的两个最大值,当这两个最大值中较小的那个为0时,表示找到了最终值,即可退出循环。

    1. 有几种解法,哪种解法时间复杂度最低,哪种解法空间复杂度最低,最优解法是什么?其他人的题解是什么,谁的效率更好一些?用不同语言实现的话,哪个语言速度最快?

    我的这种方法还不够简洁,下面有优化方法:

    func lastStoneWeight(stones []int) int {
        sort.Ints(stones)
        for i:=len(stones)-1;i>0;i--{
            stones[i-1]=stones[i]-stones[i-1]//两个最大的相减
            sort.Ints(stones[:i])//剩下的排序
        }
        return stones[0]
    }
    
    
    作者:1725762388
    链接:https://leetcode.cn/problems/last-stone-weight/solution/pai-xu-liang-ge-zui-da-xiang-jian-wan-sh-zvcu/
    来源:力扣(LeetCode)
    著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    还有使用最大堆的方法:
    使用堆容器,创建大根堆,pop出最大值两次比较,满足第一次大于第二次,把差值重新放回大根堆,直到堆内至多一个元素后返回。

    type hp struct{ sort.IntSlice }
    
    func (h hp) Less(i, j int) bool  { return h.IntSlice[i] > h.IntSlice[j] }
    func (h *hp) Push(v interface{}) { h.IntSlice = append(h.IntSlice, v.(int)) }
    func (h *hp) Pop() interface{}   { a := h.IntSlice; v := a[len(a)-1]; h.IntSlice = a[:len(a)-1]; return v }
    func (h *hp) push(v int)         { heap.Push(h, v) }
    func (h *hp) pop() int           { return heap.Pop(h).(int) }
    
    func lastStoneWeight(stones []int) int {
        q := &hp{stones}
        heap.Init(q)
        for q.Len() > 1 {
            x, y := q.pop(), q.pop()
            if x > y {
                q.push(x - y)
            }
        }
        if q.Len() > 0 {
            return q.IntSlice[0]
        }
        return 0
    }
    
    作者:LeetCode-Solution
    链接:https://leetcode.cn/problems/last-stone-weight/solution/zui-hou-yi-kuai-shi-tou-de-zhong-liang-b-xgsx/
    来源:力扣(LeetCode)
    著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27

    三、AC 代码:

    func lastStoneWeight(stones []int) int {
        if len(stones) == 1 {
    		return stones[0]
    	}
        sort.Ints(stones)
        length := len(stones)
        fmt.Println(stones)
        for stones[length-2] != 0{
            stones[length-1] -= stones[length-2]
    		stones[length-2] = 0
    		sort.Ints(stones)
        }
    
        return stones[length-1]
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    四、总结:

    这题虽然是简单题目,但是如果用Go语言写,不能使用简单暴力的方法,只能取巧和使用最大堆。

  • 相关阅读:
    基于51单片机出租车计费设计(proteus仿真+程序+原理图+设计说明书)
    分治&暴力求解最近点对问题 + 时间性能量化分析
    STM32F103学习笔记(8)——读取芯片UID和MAC地址
    大型网站高并发解决方案——集群
    大语言模型RAG-将本地大模型封装为langchain的chat model(三)
    java毕业设计百分百教育集团教务管理系统设计Mybatis+系统+数据库+调试部署
    HDC2022的无障碍参会体验,手语服务是如何做到的?
    虚拟机使用 WinSCP & Putty
    pinctrl子系统 - 源码解析(五)
    7.1 yolov5优化模型时,自动标注xml数据
  • 原文地址:https://blog.csdn.net/qq_36045898/article/details/128177485