欢迎大家加QQ群:623375442,可以方便群里面交流。

这周题目很简单,第一题是第三题的弱化版本。我们直接从第二题开始。

100182. Maximum Points After Enemy Battles

给你一个下标从 0 开始的整数数组 enemyEnergies ,它表示一个下标从 0 开始的敌人能量数组。

同时给你一个整数 currentEnergy ,它表示你一开始拥有的能量值总量。

你一开始的分数为 0 ,且一开始所有的敌人都未标记。

你可以通过以下操作 之一 任意次(也可以 0 次)来得分:

  • 选择一个 未标记 且满足 currentEnergy >= enemyEnergies[i] 的敌人 i 。在这个操作中:
    • 你会获得 1 分。
    • 你的能量值减少 enemyEnergies[i] ,也就是说 currentEnergy = currentEnergy - enemyEnergies[i] 。
  • 如果你目前 至少 有 1 分,你可以选择一个 未标记 的敌人 i 。在这个操作中:
    • 你的能量值增加 enemyEnergies[i] ,也就是说 currentEnergy = currentEnergy + enemyEnergies[i] 。
    • 敌人 i 被标记 。

请你返回通过以上操作,最多 可以获得多少分。

测试样例:

输入:enemyEnergies = [3,2,2], currentEnergy = 2

输出:2

解释:通过以下操作可以得到最大得分 3 分:

  • 对敌人 1 使用第一种操作:points 增加 1 ,currentEnergy 减少 2 。所以 points = 1 且 currentEnergy = 0 。
  • 对敌人 0 使用第二种操作:currentEnergy 增加 3 ,敌人 0 被标记。所以 points = 1 ,currentEnergy = 3 ,被标记的敌人包括 [0] 。
  • 对敌人 2 使用第一种操作:points 增加 1 ,currentEnergy 减少 2 。所以 points = 2 且 currentEnergy = 1 ,被标记的敌人包括[0] 。
  • 对敌人 2 使用第二种操作:currentEnergy 增加 2 ,敌人 2 被标记。所以 points = 2 ,currentEnergy = 3 且被标记的敌人包括 [0, 2] 。
  • 对敌人 1 使用第一种操作:points 增加 1 ,currentEnergy 减少 2 。所以 points = 3 ,currentEnergy = 1 ,被标记的敌人包括 [0, 2] 。

解答:阅读理解题,本身很简单。寻找整个数组的最小值(这就是获取点数最好的enemy),然后类和剩下的所有数。有个特殊情况需要注意,如果currentEnergy小于最小值,那么无论如何都不能获取点数,这个时候需要直接退出。

class Solution {
    public long maximumPoints(int[] enemyEnergies, int currentEnergy) {
        long sum = currentEnergy;
        int len = enemyEnergies.length, min = Integer.MAX_VALUE;
        for (int n : enemyEnergies) {
            sum += n;
            min = Math.min(min, n);
        }
        if (currentEnergy < min) {
            return 0;
        }
        sum -= min;
        return sum / min;
    }
}

100351. Alternating Groups II

给你一个整数数组 colors 和一个整数 k ,colors表示一个由红色和蓝色瓷砖组成的环,第 i 块瓷砖的颜色为 colors[i] :

  • colors[i] == 0 表示第 i 块瓷砖的颜色是 红色 。
  • colors[i] == 1 表示第 i 块瓷砖的颜色是 蓝色 。

环中连续 k 块瓷砖的颜色如果是 交替 颜色(也就是说除了第一块和最后一块瓷砖以外,中间瓷砖的颜色与它 左边 和 右边 的颜色都不同),那么它被称为一个 交替 组。

请你返回 交替 组的数目。

注意 ,由于 colors 表示一个 环 ,第一块 瓷砖和 最后一块 瓷砖是相邻的。

测试样例:

输入:colors = [0,1,0,1,0], k = 3

输出:3

解释:0,1,2为头的三个连续数组都是交替数组。

解答:利用前缀和来判断当前位置为结尾,最长的连续交替数组长度。如果最长长度大于k,那么计数器+1。注意是循环数组,所以还需要对0 - (k - 1)位置特判一下。

class Solution {
    public int numberOfAlternatingGroups(int[] colors, int k) {
        int alter = 0, res = 0;
        for (int i = 0; i < colors.length; ++i) {
            if (i == 0 || colors[i] == colors[i - 1]) {
                alter = 0;
            }
            ++alter;
            if (alter >= k) {
                ++res;
            }
        }
        for (int i = 0; i < k - 1; ++i) {
            if (colors[i] == colors[(i - 1 + colors.length) % colors.length]) {
                alter = 0;
            }
            ++alter;
            if (alter >= k) {
                ++res;
            }
        }
        return res;
    }
}

100338. Number of Subarrays With AND Value of K

给你一个整数数组 nums 和一个整数 k ,请你返回 nums 中有多少个子数组满足:子数组中所有元素按位 AND 的结果为 k 。

测试样例:

输入:nums = [1,1,1], k = 1

输出:6

解释:所有子数组都只含有元素 1 。

解答:与的特性,碰到某一位碰到第一个0之后,无论如何,这一位都没办法转成1了。按照这个特性,我们遍历数组,并记录每个二进制位最后一个0出现的位置。利用这个位置,和k的二进制情况,就能计算出满足要求的各个区间。

class Solution {
    public long countSubarrays(int[] nums, int k) {
        long res = 0;
        int[] mem = new int[30];
        for (int i = 0; i < 30; ++i) {
            mem[i] = -1;
        }
        for (int i = 0; i < nums.length; ++i) {
            // 记录区间
            int[] range = {0, i};
            for (int j = 0; j < 30; ++j) {
                // 记录最后一个0出现的位置
                if (!isMark(nums[i], j)) {
                    mem[j] = i;
                }
                // 更新区间情况
                if (isMark(k, j)) {
                    range[0] = Math.max(range[0], mem[j] + 1);
                } else {
                    range[1] = Math.min(range[1], mem[j]);
                }
            }
            res += Math.max(range[1] - range[0] + 1, 0);
        }
        return res;
    }

    private boolean isMark(int num, int offset) {
        int tmp = (num >> offset) & 1;
        return tmp == 1;
    }
}

Leave a Reply

Your email address will not be published. Required fields are marked *