leetcode
leetcode 1001 ~ 1050
最后一块石头的重量

最后一块石头的重量

难度:

标签:

题目描述

代码结果

运行时间: 20 ms, 内存: 0.0 MB


/*
 * 思路:
 * 1. 使用Java Stream API和集合框架处理石头的重量。
 * 2. 我们可以用List来存储石头,并通过Stream排序。
 * 3. 每次从列表中选出最大的两个元素进行处理,然后更新列表。
 * 4. 重复操作直到列表中剩下最多一个元素。
 * 5. 返回剩余的石头重量或者0。
 */
import java.util.*;
import java.util.stream.Collectors;

public class LastStoneWeightStream {
    public int lastStoneWeight(int[] stones) {
        List<Integer> stoneList = Arrays.stream(stones).boxed().collect(Collectors.toList());
        while (stoneList.size() > 1) {
            stoneList = stoneList.stream().sorted(Comparator.reverseOrder()).collect(Collectors.toList());
            int stone1 = stoneList.remove(0);
            int stone2 = stoneList.remove(0);
            if (stone1 != stone2) {
                stoneList.add(stone1 - stone2);
            }
        }
        return stoneList.isEmpty() ? 0 : stoneList.get(0);
    }
}

解释

方法:

该题解采用的是一个简单直观的方法来解决问题。首先,如果石头堆为空或只有一块石头,直接返回对应的结果。否则,进入一个循环,不断排序并取出当前两块最重的石头进行对决。如果两块石头重量相同,则它们都被完全粉碎;如果不同,较小的一块将被完全粉碎,较大的一块的新重量将是二者的差值。这个过程重复,直到石头堆中剩下零块或一块石头。最后返回剩下的石头重量,或者如果没有石头剩下,则返回 0。

时间复杂度:

O(n^2logn)

空间复杂度:

O(1)

代码细节讲解

🦆
在每个循环中进行排序来选择最重的两块石头是否效率最优?存在没有使用排序但效率更高的方法吗?
在每个循环中进行排序并不是效率最优的方法,因为排序的时间复杂度为O(n log n),而整个过程需要多次进行排序,使得总体时间复杂度较高。存在更高效的方法,例如使用最大堆(或优先队列)来管理石头。最大堆可以在O(log n)的时间内完成插入和删除最大元素的操作,因此在整个对决过程中维护石头的顺序会更加高效。使用最大堆,我们可以在总体时间复杂度为O(n log n)内完成整个问题的求解,其中n是石头的数量。
🦆
题解中提到如果两块石头重量不同,较小的石头会被完全粉碎。这种情况下,为什么不考虑较大的石头的重量可能变得不是最大,而是应该重新排序?
确实,按照题解的方法,每次处理两块石头后,新生成的石头的重量可能不再是列表中最大的,因此重新排序是必要的来保证每次都能处理最重的两块石头。这是题解所采用排序方法的一个必要步骤,以确保正确性。不过,如果使用最大堆作为数据结构,这个问题可以更高效地得到解决,因为最大堆会自动保证最大的元素总是可直接访问的。
🦆
在题解的逻辑中,使用了一个不断减少元素数量的列表。这种方式会影响列表的内存管理和性能吗?
在Python中,列表是一个动态数组,频繁地进行元素的添加和删除操作(特别是删除列表末端以外的元素)可能会导致额外的内存分配和数据移动,从而影响性能。在题解中,每次循环删除两个最重的石头并可能添加一个新的石头,这种操作确实可能使得性能受到影响。使用最大堆可以更有效地管理这种动态变化的数据集合,因为堆是为优化添加和删除最大元素的操作而设计的。
🦆
题解中将新重量的石头重新添加到列表中然后再次排序,这种操作是否会导致不必要的重复排序?有没有更高效的数据结构来避免这一问题?
题解中的做法确实导致了不必要的重复排序,每次添加新的石头重量后都需要重新排序以找到新的两个最重的石头,这增加了算法的时间复杂度。更高效的数据结构是使用最大堆(或优先队列),它能够在保持内部元素顺序的同时,高效地处理元素的添加和删除操作。使用最大堆,每次可以直接访问最大元素,且插入新元素的时间复杂度为O(log n),大大提高了效率。

相关问题