【贪心】B026_救生艇(排序 + 策略)

一、题目描述

The i-th person has weight people[i], and each boat can carry a maximum weight of limit.

Each boat carries at most 2 people at the same time, provided the sum of the weight of those people is at most limit.

Return the minimum number of boats to carry every given person. (It is guaranteed each person can be carried by a boat.)

[5,1,4,2]
6

二、题解

方法一:排序

错误思路:按体重升序排列后,优先承载体重小的人?但是你会发现轻重搭配有时候是一种最优的选择,比如:

[5,1,4,2]
6、
预期:2
输出:3
public int numRescueBoats(int[] people, int limit) {
    Arrays.sort(people);
    int count = 0, N = people.length;
    for (int i = 0; i < N;) {
        int t = limit;
        while (i < N && t - people[i] >= 0) {
            t -= people[i];
            i++;
        }
        count++;
    }
    return count;
}
  • 当前选择是否最优:必定选最多或者最少。
    • 选择最重和最轻:因为 1 条船最多只能载 2 人,所以轻重搭配可避免船的浪费。
    • 选择先载最轻的,能载多少是多少,但会忽略掉轻重搭配。 ×
  • 如何排序:必定是在循环「内部」排或者「外部」排。
    • 外部:按照体重升序排序。

算法

  • 优先考虑最轻和最重的 2 个人。
    • 若能匹配,则船使用数量 count++。
    • 否则,相对最重的那个人自己坐一条船。为什么呢?因为相对较轻的那个人还可以和其他人 match。
public int numRescueBoats(int[] people, int limit) {
    Arrays.sort(people);
    int N = people.length, count = 0;
    int l = 0, r = N-1;
    while (l <= r) {
        count++;
        if (people[l] + people[r] <= limit) {
            l++; r--;
        } else {
            r--;
        }
    }
    return count;
}

复杂度分析

  • 时间复杂度:O(nlogn)O(nlogn)
  • 空间复杂度:O(1)O(1)
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章