A sequence of number is called arithmetic if it consists of at least three elements and if the difference between any two consecutive elements is the same.
For example, these are arithmetic sequence:
1, 3, 5, 7, 9 7, 7, 7, 7 3, -1, -5, -9
The following sequence is not arithmetic.
1, 1, 2, 5, 7
A zero-indexed array A consisting of N numbers is given. A slice of that array is any pair of integers (P, Q) such that 0 <= P < Q < N.
A slice (P, Q) of array A is called arithmetic if the sequence:
A[P], A[p + 1], ..., A[Q - 1], A[Q] is arithmetic. In particular, this means that P + 1 < Q.
The function should return the number of arithmetic slices in the array A.
Example:
A = [1, 2, 3, 4] return: 3, for 3 arithmetic slices in A: [1, 2, 3], [2, 3, 4] and [1, 2, 3, 4] itself.
思路:
依次取差,用来寻找差值的位置。对每组等差数列,计算子数列个数。
题解:
int numberOfArithmeticSlices(const std::vector<int>& A) {
int lastDelta = std::numeric_limits<int>::max();
int currentLongestSliceLength(2);
int totalSlices(0);
auto numSubSlices = [](int sliceLength) {
// For a slice, e.g. 1, 2, 3, 4, 5, the possible sub slices rae
//
// 1, 2, 3; 2, 3, 4; 3, 4, 5 -- (n - 3 + 1) slices
// 1, 2, 3, 4; 2, 3, 4, 5 -- (n - 4 + 1) slices
// 1, 2, 3, 4, 5 -- (n - n + 1) slices
//
// So the number of subslices are sum(n - 3 + 1, ... n - n + 1) total
// n - 2 items, that is,
// sum(n + 1, n + 1, ...) - sum(3, ... n),
// or
// (n + 1) * (n - 2) - (n + 3) * (n - 2) / 2
//
// NOTE: extract (n - 2) out is unwise
if (sliceLength <= 2) {
return 0;
}
return (sliceLength + 1) * (sliceLength - 2) - (sliceLength + 3) * (sliceLength - 2) / 2;
};
for(size_t i = 1; i < A.size(); ++i) {
int delta = A[i] - A[i - 1];
if (delta == lastDelta) {
currentLongestSliceLength++;
} else {
totalSlices += numSubSlices(currentLongestSliceLength);
currentLongestSliceLength = 2; // two elements at first
}
lastDelta = delta;
}
if (currentLongestSliceLength > 2) {
totalSlices += numSubSlices(currentLongestSliceLength);
}
return totalSlices;
}

本文介绍了一种高效算法来计算数组中等差数列切片的数量,并提供了详细的实现思路与代码示例。
452

被折叠的 条评论
为什么被折叠?



