【Lintcode】1736. Throw Garbage

题目地址:

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)

你可能感兴趣的:(#,贪心,动态规划与记忆化搜索,算法,java,leetcode)