首页 > 其他分享 >力扣-1049. 最后一块石头的重量 II

力扣-1049. 最后一块石头的重量 II

时间:2024-06-05 09:13:59浏览次数:24  
标签:stones 力扣 int 1049 重量 石头 II sum dp

1.题目

题目地址(1049. 最后一块石头的重量 II - 力扣(LeetCode))

https://leetcode.cn/problems/last-stone-weight-ii/

题目描述

有一堆石头,用整数数组 stones 表示。其中 stones[i] 表示第 i 块石头的重量。

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

  • 如果 x == y,那么两块石头都会被完全粉碎;
  • 如果 x != y,那么重量为 x 的石头将会完全粉碎,而重量为 y 的石头新重量为 y-x

最后,最多只会剩下一块 石头。返回此石头 最小的可能重量 。如果没有石头剩下,就返回 0

 

示例 1:

输入:stones = [2,7,4,1,8,1]
输出:1
解释:
组合 2 和 4,得到 2,所以数组转化为 [2,7,1,8,1],
组合 7 和 8,得到 1,所以数组转化为 [2,1,1,1],
组合 2 和 1,得到 1,所以数组转化为 [1,1,1],
组合 1 和 1,得到 0,所以数组转化为 [1],这就是最优值。

示例 2:

输入:stones = [31,26,33,21,40]
输出:5

 

提示:

  • 1 <= stones.length <= 30
  • 1 <= stones[i] <= 100

2.题解

2.1 动态规划

思路

可以看作是494.目标和的变体
我们思考将石头分为两个团体,两个团体之间的石头相互碰撞,而内部不发生任何碰撞
这样我们最终发现,无论两个团体之间的石头碰撞顺序如何是怎么样的,最后都会得到同一个结果:|sum1 - sum2|, 也就是两组和的差值——保留为最后一块石头的重量

而要使这最后一块石头的重量最小,我们便要考虑使这两组的差值最小,即使其中一组的值最接近[sum/2]即可
然后我们开始选择dp数组,选择条件(元素和), 选择结果(是否存在,true/false)
最后倒序遍历dp数组,找到最接近sum/2(即m)的那个值,结果差值为(m- j) * 2 = sum - 2 * j

代码

  • 语言支持:C++

C++ Code:

class Solution {
public:
    int lastStoneWeightII(vector<int>& stones) {
        int n = stones.size();
        int sum = accumulate(stones.begin(), stones.end(), 0);
        int mid = sum / 2;
        vector<bool> dp(mid + 1);
        dp[0] = true;
        for(int i = 0; i < n; i++){
            int num = stones[i];
            for(int j = mid; j >= num; j--){
                dp[j] = dp[j] | dp[j - num];
            }
        }

        for(int j = mid; j >= 0; j--){
            if(dp[j] == true){
                return sum - 2 * j;
            }
        }
        return 0;
    }
};

复杂度分析

  • 时间复杂度:\(O(n\cdot sum)\)。其中\(n\)是数组stones的长度,sum为stones所有元素之和。
  • 空间复杂度:\(O(sum)\)。

标签:stones,力扣,int,1049,重量,石头,II,sum,dp
From: https://www.cnblogs.com/trmbh12/p/18230445

相关文章

  • 代码随想录训练营第28天 | 93.复原IP地址、78.子集 、90.子集II
    93.复原IP地址本期本来是很有难度的,不过大家做完分割回文串之后,本题就容易很多了题目链接/文章讲解:https://programmercarl.com/0093.复原IP地址.html视频讲解:https://www.bilibili.com/video/BV1XP4y1U73i/和分割字符串类似,还有判断当前数字是否符合要求functionisValid......
  • 【每周例题】 C++ 力扣 优势洗牌
    优势洗牌题目优势洗牌 题目分析1.采用双指针方法进行匹配2.依照题目所说,采用索引,首先需要填充索引,然后对索引进行升序排序。2.使用双指针进行匹配如果nums1[idx1[i]](即当前nums1中的元素)大于nums2[idx2[left]](即nums2中的当前最小元素),则将nums1[idx1[i]]赋值给ans[idx2[......
  • 【每周例题】C++ 力扣 旋转字符串
    旋转字符串 题目旋转字符串 题目分析方法1:模拟字符串1.采用双for循环去模拟字符串旋转,第一个for循环,模拟字符串循环位移;第二个for循环,进行逐个字符串检测2.使用if进行判断是否符合要求方法2:假设我们将goal字符串拆分为2个字符串,将其命名为R、L,我们将会得到以下式子go......
  • 力扣每日一题 6/4
    3067.在带权树网络中统计可连接服务器对数目[中等]题目:给你一棵无根带权树,树中总共有 n 个节点,分别表示 n 个服务器,服务器从 0 到 n-1 编号。同时给你一个数组 edges ,其中 edges[i]=[ai,bi,weighti] 表示节点 ai 和 bi 之间有一条双向边,边的权值为 we......
  • 代码随想录算法训练营第四十六天|动态规划:完全背包理论基础、518.零钱兑换II、377. 组
    动态规划:完全背包理论基础文档讲解:代码随想录题目链接:52.携带研究材料(第七期模拟笔试)完全背包有N件物品和一个最多能背重量为W的背包。第i件物品的重量是weight[i],得到的价值是value[i]。每件物品都有无限个(也就是可以放入背包多次),求解将哪些物品装入背包里物品价值总......
  • (nice!!!)LeetCode 3097. 或值至少为 K 的最短子数组 II(位运算、滑动窗口)
    3097.或值至少为K的最短子数组II思路:既然求的是区间,那么我们自然就想到前缀和、滑动窗口、双指针。结合本题的特点:或运算,会发现如果一段连续的区间进行或运算,最多只会有32次运算可以改变,这是因为int型的二进制范围是-2^31~2^31-1,每次增加一个二进制形式的1。所......
  • 力扣-494. 目标和
    1.题目题目地址(494.目标和-力扣(LeetCode))https://leetcode.cn/problems/target-sum/题目描述给你一个非负整数数组nums和一个整数target。向数组中的每个整数前添加 '+'或'-',然后串联起所有整数,可以构造一个表达式:例如,nums=[2,1],可以在2之前添加'+',......
  • 力扣每日一题 6/3
    1103.分糖果II[简单]题目:排排坐,分糖果。我们买了一些糖果 candies,打算把它们分给排好队的 n=num_people 个小朋友。给第一个小朋友1颗糖果,第二个小朋友2颗,依此类推,直到给最后一个小朋友 n 颗糖果。然后,我们再回到队伍的起点,给第一个小朋友 n +1 颗糖果,第二......
  • 代码随想录算法训练营第27天 | 39. 组合总和 、 40.组合总和II 、 131.分割回文串
    组合总和本题是集合里元素可以用无数次,那么和组合问题的差别其实仅在于startIndex上的控制题目链接/文章讲解:https://programmercarl.com/0039.组合总和.html视频讲解:https://www.bilibili.com/video/BV1KT4y1M7HJ/***@param{number[]}candidates*@param{number......
  • ERP发展历程四之 MRP II的局限性和与ERP的主要区别
    MRPⅡ理论的局限性MRPI思想的局限性主要表现在以下几个方面:(1)企业竞争范围的扩大,要求在企业的各个方面加强管理,并要求企业有更高的信息化集成,要求对企业的整体资源进行集成管理,而不仅仅只是对制造资源进行集成管理。现代企业都意识到,企业的竞争是综合实力的竞争,要求企业有......