AI刷题之判断子数组能否被5整除的问题 | 豆包MarsCode AI刷题

61 阅读3分钟

“判断子数组能否被5整除的问题”题目要求

一、问题描述

小R有一个二进制数组 nums,其中的下标从 0 开始。我们定义 xi 为从最高有效位到最低有效位的子数组 nums[0..i] 所表示的二进制数。例如,如果 nums = [1, 0, 1],那么 x0 = 1x1 = 2x2 = 5

小R想知道,对于每个 xi,它能否被 5 整除。你需要返回一个布尔值列表 answer,当 xi 能够被 5 整除时,answer[i] 为 true,否则为 false

二、测试样例

样例1:

输入:nums = [0, 1, 1]
输出:[True, False, False]

样例2:

输入:nums = [1, 1, 1]
输出:[False, False, False]

样例3:

输入:nums = [1, 0, 1, 1, 0]
输出:[False, False, True, False, False]


三、题目解析

3.1代码思路

  1. 初始化变量:需要一个布尔数组 answer 来存储结果,并且需要一个变量来记录当前的二进制数模 5 的余数。
  2. 遍历数组:遍历输入数组 nums,对于每个元素,更新当前的二进制数模 5 的余数。
  3. 更新余数:每次遍历到一个新的元素时,将当前的二进制数左移一位(相当于乘以 2),然后加上当前元素的值,再对 5 取模。
  4. 记录结果:根据当前的余数是否为 0,决定 answer 数组中对应位置的值。

3.2详细代码

import java.util.Arrays;

public class Main {
    public static boolean[] solution(int[] nums) {
        // 初始化结果数组
        boolean[] answer = new boolean[nums.length];
        
        // 初始化当前二进制数模 5 的余数
        int currentMod = 0;
        
        // 遍历数组
        for (int i = 0; i < nums.length; i++) {
            // 更新当前二进制数模 5 的余数
            currentMod = (currentMod * 2 + nums[i]) % 5;
            
            // 根据余数决定 answer 数组中的值
            answer[i] = (currentMod == 0);
        }
        
        // 返回结果数组
        return answer;
    }

    public static void main(String[] args) {
        System.out.println(Arrays.equals(solution(new int[]{0, 1, 1}), new boolean[]{true, false, false}) ? 1 : 0);
        System.out.println(Arrays.equals(solution(new int[]{1, 0, 1, 1, 0}), new boolean[]{false, false, true, false, false}) ? 1 : 0);
        System.out.println(Arrays.equals(solution(new int[]{1, 1, 1}), new boolean[]{false, false, false}) ? 1 : 0);
    }
}

四、知识总结

直接转换前缀数组为二进制数再判断是否能被 5 整除是不高效的,尤其是当数组长度较大时,前缀数可能会变得非常大。因此,我们采用模运算来优化计算:

  1. 模运算性质
    模运算有一个重要性质:

    ( a × b + c ) % m= [ ( a % m ) × b + c ] % m

    利用这一性质,我们可以只关注二进制数对 5 的余数,从而避免直接计算前缀数的完整值。

  2. 状态更新
    每次添加新的二进制位时,只需要更新当前的余数:

    currentMod = ( currentMod × 2 + nums[i] ) % 5

  3. 结果判断
    如果当前余数为 0,则说明该前缀二进制数可以被 5 整除。

通过模运算的巧妙应用,这段代码高效解决了判断二进制前缀能否被 5 整除的问题。算法不仅逻辑清晰,而且避免了直接操作大整数可能导致的性能问题,非常适合处理大规模数据。在实际应用中,这种基于余数的动态更新方法也常用于诸如字符串匹配、哈希算法等场景。

五、复杂度分析

  1. 时间复杂度
    遍历数组时,每个元素只需要常数时间更新 currentMod 和填充 answer 数组,时间复杂度为 O(n)。
  2. 空间复杂度
    只需要额外的布尔数组 answer,其空间复杂度为 O(n)。