【貪心】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)
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章