leetcode
leetcode 1851 ~ 1900
摧毁小行星

摧毁小行星

难度:

标签:

题目描述

代码结果

运行时间: 103 ms, 内存: 29.7 MB


/*
 * 思路:
 * 使用 Java Stream 进行小行星数组的排序和遍历。 
 * 通过 reduce 方法累加行星的质量并判断是否能摧毁所有小行星。
 */
import java.util.Arrays;

public class Solution {
    public boolean canDestroyAllAsteroids(int mass, int[] asteroids) {
        return Arrays.stream(asteroids)
                     .sorted()
                     .mapToLong(Long::valueOf)
                     .reduce((planetMass, asteroidMass) -> planetMass >= asteroidMass ? planetMass + asteroidMass : -1)
                     .orElse(-1) != -1;
    }
}

解释

方法:

这个题解采取了一个迭代的方法来处理小行星的摧毁问题。初始时,考虑所有的小行星,并试图摧毁它们。对于当前的小行星列表,遍历每颗小行星,如果当前行星的质量大于或等于小行星的质量,则摧毁它并增加行星的质量;如果不是,则将这颗小行星保留到下一个列表中。如果一轮遍历后没有任何小行星被摧毁(即下一个列表的长度与当前列表相同),则返回False。如果所有的小行星都被摧毁了(即下一个列表为空),则返回True。

时间复杂度:

O(n^2)

空间复杂度:

O(n)

代码细节讲解

🦆
为什么选择迭代逐个检查小行星,而不是先对小行星数组进行排序来尝试优化算法效率?
选择迭代逐个检查小行星而不先对它们进行排序,可能是因为排序本身有一个时间复杂度O(n log n),而迭代检查的过程可能在某些情况下能更早终止执行。例如,如果较早遇到无法摧毁的小行星,就可以立即返回False,而不需要处理整个数组。此外,排序可能不会改变总体的算法复杂度,因为在最坏的情况下,即使排了序,仍然需要遍历整个数组来判断能否摧毁所有小行星。
🦆
在题解中提到,如果一轮遍历后没有任何小行星被摧毁,则返回False。这种情况是如何判断的,能否详细解释其逻辑?
在题解中,每次迭代开始时都会创建一个空的列表next_a,用来存放那些未被当前行星摧毁的小行星。在迭代过程中,如果发现某个小行星的质量大于当前行星的质量,就将其加入到next_a中。在一轮迭代结束时,如果next_a的长度与原始列表asteroids的长度相同,说明这一轮没有任何一个小行星被摧毁。因此,如果next_a的长度未减少,就会返回False,表示当前行星的质量不足以摧毁任何一个小行星,无法继续进行摧毁操作。
🦆
在解法中,如果小行星的质量大于行星的质量,就将小行星放入下一轮列表。这种处理方式是否意味着算法对小行星的处理顺序非常敏感?
是的,这种处理方式意味着算法对小行星的处理顺序非常敏感。在没有进行排序的情况下,小行星被遍历的顺序将直接影响算法的结果。例如,如果较小的小行星先被处理,可能使行星的质量逐渐增加,从而在后续遍历中摧毁原本不能摧毁的更大的小行星。相反,如果一开始就遇到一个较大的小行星,而行星的质量不足以摧毁它,那么就会直接将其加入到下一轮列表中,可能导致算法提前结束。因此,处理顺序对于这种算法来说是一个关键因素。

相关问题