1.题目(HARD)
A non-empty zero-indexed array A of N integers is given. A pair of integers (P, Q), such that 0 ≤ P ≤ Q < N, is called a slice of array A. Thesum of a slice (P, Q) is the total of A[P] + A[P+1] + ... + A[Q].
A min abs slice is a slice whose absolute sum is minimal.
For example, array A such that:
A[0] = 2 A[1] = -4 A[2] = 6 A[3] = -3 A[4] = 9
contains the following slices, among others:
- (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
Both slices (0, 3) and (1, 3) are min abs slices and their absolute sum equals 1.
Write a function:
int solution(int A[], int N);
that, given a non-empty zero-indexed array A consisting of N integers, returns the absolute sum of min abs slice.
For example, given:
A[0] = 2 A[1] = -4 A[2] = 6 A[3] = -3 A[4] = 9
the function should return 1, as explained above.
Assume that:
- N is an integer within the range [1..100,000];
- each element of array A is an integer within the range [−10,000..10,000].
Complexity:
- expected worst-case time complexity is O(N*log(N));
- expected worst-case space complexity is O(N), beyond input storage (not counting the storage required for input arguments).
Elements of input arrays can be modified.
Copyright 2009–2015 by Codility Limited. All Rights Reserved. Unauthorized copying, publication or disclosure prohibited.
2.题目分析
这个题目看上去很简单。
slice求和,prefix的经典解法。不过,这个要求的是和的绝对值。这就有一点生硬了。贪心算法或者蠕虫都不太实用。
有点着急呢。。眼看答案就在眼前,可是就是想不出。过了20分钟,我有点开窍了。
首先是看到了时间复杂度为O(N*logN).这感觉是要排序啊,不过对元数据排序貌似没有用啊。突然意识到,可以对prefix排序。
瞬间感觉自己很牛逼。
你想,prefix任何两者的差,即是这一段slice的和,那么我们现在其实找的就是这段和的最小绝对值。我们将prefix排序以后,那么就是大小最相近的两个prefix的值会成为相邻。对其做差,就是找到一段最小值。我们顺序遍历这个prefix数组,找到所有的相邻项相差的最小值,不就是我们要找的那个绝对值吗?(因为已经从大到小排序了)。
当然,还是要做一些其他的处理,比如找到prefix的绝对值最小值,和数组的绝对值的最小值,同得出的结论进行比较。
就必然得出了最后的答案。