You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java实现数组子数组按位或之和,大测试用例失败求排查

问题要求

给定大小为N的整数数组A,子数组的值定义为其所有元素的按位或(BITWISE OR),需返回所有子数组的值之和对10^9 + 7取模的结果。

提供的代码
public class Solution {
    public int solve(ArrayList<Integer> A) {
        long M = 1000000007;

        int N = A.size();
        
        long totalSubarrays = (N*(N+1))/2;
        long totalORSum = 0; //sum of bitwise OR of all subarrays
        
        //step1: traverse through each bit of element of array
        for(int i = 0; i < 32; i++) {
            long subArrayUnsetBit = 0;
            long zeroCount = 0;
            for(int j = 0; j < N; j++) {
                //2.check if bit is unset(0).count the number of unset bits.
                //Calculate the number of sub arrays with unset ith bit position

                //for each element, check if bit at "position" is unset
                //if it's unset, add to the total
                //since we are looking for number of subarrays, if there are continuous unset bit position, the number of subarrays will depend on it as well. 
                if ((1 & (A.get(j) >> i)) != 1) {
                    zeroCount++;
                } else {
                    subArrayUnsetBit = subArrayUnsetBit + (zeroCount * (zeroCount + 1)) / 2;
                    zeroCount = 0;//reset
                }

            }
            //get the number of subarrays which have ith bit as unset
            subArrayUnsetBit = subArrayUnsetBit + (zeroCount*(zeroCount+1))/2;
            //number of sub arrays which have ith bit set
            long subArraySetBit = totalSubarrays - subArrayUnsetBit;
            //if ith bit is set, its value would be: 2^i == (1<<i)
            long powerValue = (1<<i);
            //contribution to total sum by all subarrays which has set bit at ith position
            long contribution = (subArraySetBit * powerValue);
            totalORSum = (totalORSum + contribution);

        }
        return (int)(totalORSum % M);
        
    }
}
问题现状

上述代码在小数组(如[1,2,3,4,5],预期结果71)中运行正常,但在大测试用例中执行失败,请求帮忙排查问题原因。

问题排查与修复

代码在大测试用例中失败的核心原因是整数溢出和模运算不规范,具体问题及修复如下:

1. 左移操作的int溢出

当i=31时,1 << i中的1是int类型(32位有符号),左移31位会触发符号位变化,得到负数-2147483648,而非预期的2^31,直接导致后续贡献值计算错误。

修复:将1改为1L,以long类型执行左移操作:

long powerValue = 1L << i;

2. 子数组总数计算的int溢出

当N较大时(如N=46341),N*(N+1)的结果会超过int类型的最大值(2147483647),先以int计算会溢出,再转long得到错误的totalSubarrays值。

修复:将N转为long后再计算:

long totalSubarrays = ((long)N * (N + 1)) / 2;

3. 大数乘法的溢出与模运算缺失

当N达到1e5级别时,subArraySetBit * powerValue的结果会超过long类型的最大值(9223372036854775807),导致溢出;同时未在计算过程中分步取模,最终totalORSum也会溢出。

修复:利用模运算性质(a*b) mod m = [(a mod m)*(b mod m)] mod m,分步对贡献值取模,并在累加后立即对totalORSum取模:

long contribution = ((subArraySetBit % M) * (powerValue % M)) % M;
totalORSum = (totalORSum + contribution) % M;

修复后的完整代码

public class Solution {
    public int solve(ArrayList<Integer> A) {
        final long M = 1000000007;

        int N = A.size();
        long totalSubarrays = ((long)N * (N + 1)) / 2;
        long totalORSum = 0;

        for(int i = 0; i < 32; i++) {
            long subArrayUnsetBit = 0;
            long zeroCount = 0;
            for(int j = 0; j < N; j++) {
                if (((A.get(j) >> i) & 1) != 1) {
                    zeroCount++;
                } else {
                    subArrayUnsetBit += (zeroCount * (zeroCount + 1)) / 2;
                    zeroCount = 0;
                }
            }
            subArrayUnsetBit += (zeroCount * (zeroCount + 1)) / 2;
            long subArraySetBit = totalSubarrays - subArrayUnsetBit;
            long powerValue = 1L << i;
            long contribution = ((subArraySetBit % M) * (powerValue % M)) % M;
            totalORSum = (totalORSum + contribution) % M;
        }
        return (int)(totalORSum % M);
    }
}

内容的提问来源于stack exchange,提问作者HK123

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.02 01:17:15