在总和<= M的K个串联数组中找到子数组的总数

时间:2020-04-22 22:16:31

标签: java arrays search

enter image description here给出一个数组和K(其连接的次数。我们需要找到总和<=给定值M

的连续子数组的总数

我已经通过检查总和超过M之前可以走多远,计算出了原始数组中每个索引可能的所有子数组。计算时,我可能会在总和超过M之前到达末尾,否则仍然有(K -使用的数组)剩余的数组 我为单个数组计算的子集,我将根据在findTotalSubsets方法中提到的条件再次与(K用)相乘,以获得最右边的剩余几个索引。 以下解决方案适用于少量输入,但总的来说,这不是平台解决方案。

public class ModifiedSubarraySumProblem {
    static int MOD = 1000000007;

    public static void main(String[] args) {
        Scanner scan = new Scanner(System.in);
        byte t = scan.nextByte();
        while (t-- > 0) {
            int[] arr = new int[scan.nextInt()], subsetsStartingWithCount = new int[arr.length];
            long K = scan.nextLong();
            int M = scan.nextInt();

            for (int i = 0; i < arr.length; i++)
                arr[i] = scan.nextInt();

            long subsetCount = findSubsets(arr, subsetsStartingWithCount, K, M);
            if (subsetCount == 0 || K == 1)
                System.out.println(subsetCount % MOD);
            else
                System.out.println(findTotalSubsets(arr, subsetsStartingWithCount, subsetCount, K, M));
        }
    }

    private static int findTotalSubsets(int[] arr, int[] subsetsStartingWithCount, long subsetCount, long K, int M) {
        int n = arr.length;
        long span, left;
        if (arr[0] >= M || arr[n - 1] >= M || n > 1 && arr[0] + arr[n - 1] > M)
            return (int) ((K % MOD) * (subsetCount % MOD) % MOD);
        span = (int) Math.ceil((subsetsStartingWithCount[n - 1] - 1) / (double) n);
        if (K - span > 0)
            subsetCount = (K - span) * subsetCount;
        left = span * n;
        for (int i = 0; i < n; i++) {
            if (subsetsStartingWithCount[i] > (left - i))
                subsetCount = subsetCount + (left - i);
            else
                subsetCount = subsetCount + subsetsStartingWithCount[i];
        }
        span = (span - 1) * n;
        subsetCount = subsetCount + span * (span + 1) / 2;
        return (int) (subsetCount % MOD);
    }

    private static long findSubsets(int[] input, int[] output, long K, int M) {
        long subsetCount = 0, j = 0;
        int sum = 0, n = input.length;
        for (int i = 0; i < n; i++) {
            if (i != 0) {
                sum = sum - input[i - 1];
            }
            // n*k might overflow, subarray can never go beyond 1000000
            if ((n * K) / n != K)
                K = 10000000000l;
            else
                K = n * K;
            for (; j < K; j++) {
                if (sum + input[(int) (j % n)] <= M)
                    sum += input[(int) (j % n)];
                else
                    break;
            }
            output[i] = (int) j - i;
            subsetCount += output[i];
        }
        return subsetCount;
    }

}

0 个答案:

没有答案