力扣第 375 场周赛(Java)

文章目录

    • T1 统计已测试设备
      • 代码解释
    • T2 双模幂运算
      • 代码解释
    • T3 统计最大元素出现至少 K 次的子数组
      • 代码解释
    • T4 统计好分割方案的数目
      • 代码解释

链接:第 375 场周赛 - 力扣(LeetCode)

T1 统计已测试设备

给你一个长度为 n 、下标从 0 开始的整数数组 batteryPercentages ,表示 n 个设备的电池百分比。

你的任务是按照顺序测试每个设备 i,执行以下测试操作:

  • 如果 batteryPercentages[i] 大于 0
    • 增加 已测试设备的计数。
    • 将下标在 [i + 1, n - 1] 的所有设备的电池百分比减少 1,确保它们的电池百分比 不会低于 0 ,即 batteryPercentages[j] = max(0, batteryPercentages[j] - 1)
    • 移动到下一个设备。
  • 否则,移动到下一个设备而不执行任何测试。

返回一个整数,表示按顺序执行测试操作后 已测试设备 的数量。

示例 1:

输入:batteryPercentages = [1,1,2,1,3]
输出:3
解释:按顺序从设备 0 开始执行测试操作:
在设备 0 上,batteryPercentages[0] > 0 ,现在有 1 个已测试设备,batteryPercentages 变为 [1,0,1,0,2] 。
在设备 1 上,batteryPercentages[1] == 0 ,移动到下一个设备而不进行测试。
在设备 2 上,batteryPercentages[2] > 0 ,现在有 2 个已测试设备,batteryPercentages 变为 [1,0,1,0,1] 。
在设备 3 上,batteryPercentages[3] == 0 ,移动到下一个设备而不进行测试。
在设备 4 上,batteryPercentages[4] > 0 ,现在有 3 个已测试设备,batteryPercentages 保持不变。
因此,答案是 3 。

示例 2:

输入:batteryPercentages = [0,1,2]
输出:2
解释:按顺序从设备 0 开始执行测试操作:
在设备 0 上,batteryPercentages[0] == 0 ,移动到下一个设备而不进行测试。
在设备 1 上,batteryPercentages[1] > 0 ,现在有 1 个已测试设备,batteryPercentages 变为 [0,1,1] 。
在设备 2 上,batteryPercentages[2] > 0 ,现在有 2 个已测试设备,batteryPercentages 保持不变。 因此,答案是 2 。

提示:

  • 1 <= n == batteryPercentages.length <= 100
  • 0 <= batteryPercentages[i] <= 100

代码解释

暴力 O(n^2)

class Solution {
    public int countTestedDevices(int[] batteryPercentages) {
        int ans = 0;
        int n = batteryPercentages.length;
        for (int i = 0; i < n; i++) {
            if (batteryPercentages[i] > 0) {
                for (int j = i + 1; j < n; j++) {
                    batteryPercentages[j] = Math.max(0, batteryPercentages[j]-1);
                }
                ans++;
            }
        }
        return ans;
    }
}

T2 双模幂运算

给你一个下标从 0 开始的二维数组 v a r i a b l e s variables variables ,其中 v a r i a b l e s [ i ] = [ a i , b i , c i , m i ] variables[i] = [a_i, b_i, c_i, m_i] variables[i]=[ai,bi,ci,mi],以及一个整数 target 。

如果满足以下公式,则下标 i 是 好下标:

  • 0 < = i < v a r i a b l e s . l e n g t h 0 <= i < variables.length 0<=i<variables.length
  • ( ( a i b i m o d   10 ) c i )   m o d   m i = = t a r g e t ((a_i^{b_i} mod~ 10)^{c_i}) ~mod~ m_i == target ((aibimod 10)ci) mod mi==target

返回一个由 好下标 组成的数组,顺序不限 。

提示:

  • 1 <= variables.length <= 100
  • variables[i] == [ai, bi, ci, mi]
  • 1 <= ai, bi, ci, mi <= 103
  • 0 <= target <= 103

代码解释

暴力 O(n(b+c)),用 BigInteger 防止超范围

import java.math.BigInteger;
class Solution {
    public List<Integer> getGoodIndices(int[][] variables, int target) {
        List<Integer> ans = new ArrayList<>();
        int n = variables.length;
        for (int j = 0; j < n; j++) {
            int[] v = variables[j];
            int a = v[0], b = v[1], c = v[2], m = v[3];
            long sum = 1;
            for (int i = 0; i < b; i++) {
                sum *= a;
                sum %= 10;
            }
            BigInteger s = new BigInteger(String.valueOf(sum));
            long t = sum;
            for (int i = 1; i < c; i++) {
                s = s.multiply(BigInteger.valueOf(t));
            }
            if (s.mod(BigInteger.valueOf(m)).intValue() == target) {
                ans.add(j);
            }
        }
        return ans;
    }
}

T3 统计最大元素出现至少 K 次的子数组

给你一个整数数组 nums 和一个 正整数 k

请你统计有多少满足 「 nums 中的 最大 元素」至少出现 k 次的子数组,并返回满足这一条件的子数组的数目。

子数组是数组中的一个连续元素序列。

示例 1:

输入:nums = [1,3,2,3,3], k = 2
输出:6
解释:包含元素 3 至少 2 次的子数组为:[1,3,2,3]、[1,3,2,3,3]、[3,2,3]、[3,2,3,3]、[2,3,3] 和 [3,3] 。

示例 2:

输入:nums = [1,4,2,1], k = 3
输出:0
解释:没有子数组包含元素 4 至少 3 次。

提示:

  • 1 <= nums.length <= 10^5
  • 1 <= nums[i] <= 10^6
  • 1 <= k <= 10^5

代码解释

滑动窗口,窗口内最大值刚好为 K 次时包含此窗口数组的子数组数为左长度乘右长度,用队列记录每个最大值的位置,多找到一个最大值,左长度向右侧移动一个位置,防止左侧算重复了。时间复杂度 O(n)

做的时候脑抽了,以为是子数组里的最大元素出现至少 K 次,没写出来,快结束了才发现最大值固定了。

class Solution {
    public long countSubarrays(int[] nums, int k) {
        int n = nums.length;
        int max = Arrays.stream(nums).max().getAsInt();
        Queue<Integer> queue = new LinkedList<>();
        int cnt = 0, l = 0, r = 0;
        for (int i = 0; i < n; i++) {
            if (nums[i] == max) {
                cnt++;
                queue.add(i);
                r = i;
            }
            if (cnt == k) {
                break;
            }
        }
        if (cnt < k) return 0;
        int pre = queue.poll();
        long ans = (long) (pre + 1) * (n - r);
        while (++r < n) {
            if (nums[r] == max) {
                queue.add(r);
                int t = queue.poll();
                ans += (long) (t - pre) * (n - r);
                pre = t;
            }
        }
        return ans;
    }
}

T4 统计好分割方案的数目

给你一个下标从 0 开始、由 正整数 组成的数组 nums

将数组分割成一个或多个 连续 子数组,如果不存在包含了相同数字的两个子数组,则认为是一种 好分割方案

返回 nums好分割方案数目

由于答案可能很大,请返回答案对 109 + 7 取余 的结果。

示例 1:

输入:nums = [1,2,3,4]
输出:8
解释:有 8 种 好分割方案 :([1], [2], [3], [4]), ([1], [2], [3,4]), ([1], [2,3], [4]), ([1], [2,3,4]), ([1,2], [3], [4]), ([1,2], [3,4]), ([1,2,3], [4]) 和 ([1,2,3,4]) 。

示例 2:

输入:nums = [1,1,1,1]
输出:1
解释:唯一的 好分割方案 是:([1,1,1,1]) 。

示例 3:

输入:nums = [1,2,1,3]
输出:2
解释:有 2 种 好分割方案 :([1,2,1], [3]) 和 ([1,2,1,3]) 。

提示:

1 <= nums.length <= 10^5
1 <= nums[i] <= 10^9

代码解释

这次最后一题也比较简单,用一个哈希表记数的出现次数,一个哈希集合记出现的数,所有集合中的数都有了就划分为一个组,划分出来的所有组可以随意组合,根据组合公式可以知道 n n n 组就有 2 n 2^n 2n 个方案数,最后用 BigInteger 防止超范围。

import java.math.BigInteger;
class Solution {
    public int numberOfGoodPartitions(int[] nums) {
        Map<Integer, Integer> map = new HashMap<>();
        for (int n : nums) {
            map.putIfAbsent(n, 0);
            map.put(n, map.get(n) + 1);
        }
        int n = nums.length, cnt = 0;
        Set<Integer> set = new HashSet<>();
        for (int num : nums) {
            set.add(num);
            map.put(num, map.get(num) - 1);
            if (map.get(num) == 0) {
                set.remove(num);
            }
            if (set.isEmpty()) {
                cnt++;
            }
        }
        BigInteger ans = new BigInteger("1");
        BigInteger t = new BigInteger("2");
        BigInteger mod = new BigInteger("1000000007");
        for (int i = 1; i < cnt; i++) {
            ans = ans.multiply(t);
        }
        return ans.mod(mod).intValue();
    }
}

你可能感兴趣的:(算法学习,leetcode,java,算法)