【Lintcode】1736. Throw Garbage

記錄演算法發表於2021-01-03

題目地址:

https://www.lintcode.com/problem/throw-garbage/description

給定一個浮點型長 n n n陣列 A A A,題目保證每個數的範圍是 [ 1.01 , 3.00 ] [1.01,3.00] [1.01,3.00]。每次可以挑若干數使得和小於等於 3 3 3,問最少多少次挑完。

思路是貪心 + 雙指標。可以看出每次最多挑兩個數。先對 A A A排序,開左右兩個指標 l l l r r r分別賦值為 0 0 0 n − 1 n-1 n1,維護區間 [ l , r ] [l,r] [l,r]為接下來要選的數。考慮 A [ r ] A[r] A[r],如果 A [ l ] + A [ r ] > 3 A[l]+A[r]>3 A[l]+A[r]>3,那 A [ r ] A[r] A[r]只能單獨挑了;否則的話可以將 A [ l ] A[l] A[l] A [ r ] A[r] A[r]都挑出來。挑完了之後計數加 1 1 1,接著繼續迴圈考慮剩餘區間。演算法證明可以用數學歸納法。程式碼如下:

import java.util.Arrays;

public class Solution {
    /**
     * @param A: the weight of all garbage bags.
     * @return: an integer represent the minimum number of times.
     */
    public int Count_ThrowTimes(float[] A) {
        // Write your code here.
        // 先排序
        Arrays.sort(A);
        
        int res = 0, l = 0, r = A.length - 1;
        float sum = 0;

		// 先只考慮挑多於1個數的情況
        while (l < r) {
            sum = A[l] + A[r];
            // 如果挑的兩個數之和大於3了,那隻能A[r]自成一個
            if (sum > 3) {
                r--;
                res++;
            } else {
            	// 如果兩個數之和小於等於3,則就挑掉這兩個
                r--;
                l++;
                
                // 更新計數
                res++;
            }
        }
        
        // 如果還剩一個數,則還需要另外加1
        return res + (l == r ? 1 : 0);
    }
}

時間複雜度 O ( n log ⁡ n ) O(n\log n) O(nlogn),空間 O ( 1 ) O(1) O(1)

相關文章