G
N
I
D
A
O
L

题目链接:https://leetcode.cn/contest/biweekly-contest-100/

# 将钱分给最多的儿童

# 解题思路

按照题目分情况讨论即可

# 提交结果

image.png

# 代码

a
class Solution {
    public int distMoney(int money, int children) {
        if (children > money) return -1;
        if (children * 8 > money) {
            int x = money / 8;
            int y = money % 8;
            if (children - x == 1 && y == 4) return x - 1;
            // 每人分一美元后,再看还有多少组 7 美元即可
            return (money - children) / 7;
        } else if (children * 8 < money) {
            return children - 1;
        } else {
            return children;
        }
    }
}
# [最大化数组的伟大值](https://leetcode.cn/problems/maximize-greatness-of-an-array/)
## 解题思路:贪心 + 双指针
  
整个数组排序后,始终拿最大的与第二大的配对,如果相等,则需要与更小的配对;如果大于,结果直接加一,继续给剩余最大的数进行配对;直到遍历完整个数组。
## 代码
``` java
class Solution {
    public int maximizeGreatness(int[] nums) {
        Arrays.sort(nums);
        int n = nums.length;
        int k = n -1;
        int ret = 0;
        for (int i = n - 2; i >= 0; --i) {
            if (nums[k] > nums[i]) {
                ++ret;
                --k;
            }
        }
        
        return ret;
    }
}

# 标记所有元素后数组的分数

# 思路:模拟 + 排序优化

按照题意模拟即可,只不过可以加快每次寻找最小值的速度,用数组同时保存 nums[i]i ,再进行升序排序,这样依次取到最小的数,同时用原数组进行标记已经被标记的数,直接赋值 -1 即可。

# 代码

a
class Solution {
    public long findScore(int[] nums) {
        int n = nums.length;
        int[][] arr = new int[n][2];
        for (int i = 0; i < n; ++i) {
            arr[i][0] = i;
            arr[i][1] = nums[i];
        }
        Arrays.sort(arr, (o1, o2) -> o1[1] == o2[1] ? o1[0] - o2[0] : o1[1] - o2[1]);
        
        long score = 0;
        for (int i = 0; i < n; ++i) {
            int j = arr[i][0];
            if (nums[j] > -1) {
                // 当前最小值可选
                score += arr[i][1];
                // 标记周围的数
                if (j > 0) nums[j - 1] = -1;
                if (j < n - 1) nums[j + 1] = -1;
            }
        }
        return score;
    }
}

# 修车的最少时间

# 法一:暴力

对每一辆车分配给当前能最快完成修理工作的工人,这里就需要记录每位工人修理的汽车数量。为了能较快地找到当前修理最快的工人,根据修理当前车辆所花时间建立小顶堆。

# 代码

a
class Solution {
    public long repairCars(int[] ranks, int cars) {
        int n = ranks.length;
        long spend = 0;
        // 每位工人修车的数量
        int[] rc = new int[n];
        Arrays.fill(rc, 1);
        PriorityQueue<Integer> pq = new PriorityQueue<>((o1, o2) -> {
            long l1 = (long) ranks[o1] * rc[o1] * rc[o1];
            long l2 = (long) ranks[o2] * rc[o2] * rc[o2];
            return (int) (l1 - l2);
        });
        
        for (int i = 0; i < n; ++i) pq.offer(i);
        
        for (int k = 1; k <= cars; ++k) {
            // 第 k 辆车交给谁来修
            // 选择花费时间最小的工人
            int j = pq.poll();
            long min = (long) ranks[j] * rc[j] * rc[j];
            spend = Math.max(spend, min);
            // 累加当前工人的修车数量
            ++rc[j];
            pq.offer(j);
        }
        return spend;
    }
}

当前时间复杂度:O (n*logn),有超时的风险!

# 法二:二分法

参考:https://leetcode.cn/problems/minimum-time-to-repair-cars/solution/er-fen-da-an-pythonjavacgo-by-endlessche-keqf/

# 代码

a
class Solution {
    public long repairCars(int[] ranks, int cars) {
        long min = Arrays.stream(ranks).min().orElse(0);
        long l = 0, r = min * cars * cars;
        
        while (l + 1 < r) {
            long m = (l + r) / 2;
            long t = 0;
            
            for (int g : ranks) {
                t += Math.sqrt(m / g);
            }
            
            if (t >= cars) r = m;
            else l = m;
        }
        
        return r;
    }
}
更新于 阅读次数

😉觉得写的还不错,请我喝杯咖啡吧😁

独步凌波 微信支付

微信支付

独步凌波 支付宝

支付宝