前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >1046. 最后一块石头的重量

1046. 最后一块石头的重量

作者头像
Regan Yue
发布2022-12-05 15:27:46
2160
发布2022-12-05 15:27:46
举报
文章被收录于专栏:ReganYue's Blog

一、题目描述:

有一堆石头,每块石头的重量都是正整数。 每一回合,从中选出两块 最重的 石头,然后将它们一起粉碎。假设石头的重量分别为 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. 有几种解法,哪种解法时间复杂度最低,哪种解法空间复杂度最低,最优解法是什么?其他人的题解是什么,谁的效率更好一些?用不同语言实现的话,哪个语言速度最快?

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

代码语言:javascript
复制
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)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

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

代码语言:javascript
复制
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)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

三、AC 代码:

代码语言:javascript
复制
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]
}

四、总结:

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

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2022/12/04 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
容器服务
腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档