任何数组java

时间:2017-08-08 19:33:08

标签: java arrays time-complexity

我尝试在codility中解决演示测试。 问题:

  

给出了N个整数的非空零索引数组A.一对整数(P,Q),使得0≤P≤Q<1。 N,称为阵列A的切片。切片的总和(P,Q)是A [P] + A [P + 1] + ... + A [Q]的总和。

     

最小abs片是绝对和最小的片。

     

例如,数组A使得:

A[0] = 2
A[1] = -4
A[2] = 6
A[3] = -3
A[4] = 9
     

包含以下切片:

(0, 1), whose absolute sum = |2 + (−4)| = 2
(0, 2), whose absolute sum = |2 + (−4) + 6| = 4
(0, 3), whose absolute sum = |2 + (−4) + 6 + (−3)| = 1
(1, 3), whose absolute sum = |(−4) + 6 + (−3)| = 1
(1, 4), whose absolute sum = |(−4) + 6 + (−3) + 9| = 8
(4, 4), whose absolute sum = |9| = 9
     

切片(0,3)和(1,3)都是最小的abs切片,它们的绝对和等于1.

我试图遍历所有切片并做了类似的事情:

class Solution {
    public int solution(int[] A) {
        int N = A.length;
        if(N==1)
        {
            return A[0];
        }
        Arrays.sort(A);
        for(int i=0;i<N; ++i)
        {
            System.out.println(A[i]);
        }
        int tail = 0;
        int head = N - 1;
        System.out.println(tail+ " "+head+"first");
        long minAbsSum =(long) Math.abs(A[tail] + A[head]);
        while (tail <= head) {        
            System.out.println(tail+ " "+head);
            long currentSum = (long)A[tail] + (long)A[head];
            minAbsSum = (long)Math.min(minAbsSum, Math.abs(currentSum));
            // If the sum has become
            // positive, we should know that the head can be moved left
            if (currentSum <= 0)
                tail++;
            else
                head--;
        }
        return (int)minAbsSum;
    }
}

但我得到了2片。

是否有某种方法可以按照O(N * logN)复杂度的要求覆盖所有切片?

1 个答案:

答案 0 :(得分:0)

这对于获得作业帮助并不是一个非常合适的论坛。这是为了帮助开发人员解决他们在开发过程中遇到的问题。

将此放在一边,你的问题似乎是一个算法,它找到所提供数组的任何给定切片的最小绝对和。正如其他人在评论部分指出的那样,你&#34;销毁&#34;输入数组中的值序列通过排序。排序后,您将无法重建输入数组中的值序列。

O(n ^ 2)的可能解决方案是迭代所有可能的切片并记住具有最小绝对和的切片。要将复杂度降低到O(n log(n)),您可以尝试递归地将输入数组拆分为单独的切片,计算每个切片的总和并合并结果。

import java.util.HashSet;
import java.util.Set;

public class MinimalSliceSum {
    private static int[] values = { 2, -4, 6, -3, 9 };
    private static int minimalAbsSum = values[0];
    private static Set<Slice> minimalSlices = new HashSet<>();

    public static void main(String[] args) {
        for (int i = 0; i < values.length; i++) {
            int sum = 0;
            for (int j = i; j < values.length; j++) {
                sum += values[j];
                processRange(i, j, sum);
            }
        }
        System.out.println("Minimal abs sum: " + minimalAbsSum);
        for (Slice slice : minimalSlices) {
            System.out.println("Slice (" + slice.getFrom() + ", " + slice.getTo() + ")");
        }
    }

    private static void processRange(int i, int j, int sum) {
        int absSum = Math.abs(sum);
        if (minimalAbsSum > absSum) {
            minimalAbsSum = absSum;
            minimalSlices.clear();
        }
        if (minimalAbsSum == absSum) {
            minimalSlices.add(new Slice(i, j));
        }
    }

    public static class Slice {
        private int from;
        private int to;

        public Slice(int from, int to) {
            this.from = from;
            this.to = to;
        }

        public int getFrom() {
            return from;
        }

        public int getTo() {
            return to;
        }
    }
}