[LeetCode]413. Arithmetic Slices 解题报告

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.

这一题咋看之下,还以为使用动态规划,辅助数组空间换时间来做,后来发现我想多了。

只要发现这种数列的成型特征就可以很好做了这一题。思路:我们可以发现所有的数列,必定是从P开始,到Q结束,这种之间是没有中断的。因此,我们遍历一遍数组,计算以每一个数字开头的数列的数量即可。

具体来说,对于给定的开头数字,A[P],先计算A[P],A[P+1],A[P+2],是不是数列,如果是,将总数++。继续往后计算,只用计算A[p+3]-A[p+2]的值和前面数列的公差是否相等,就可以判断是不是一个新的数列,将总数++即可。

需要注意的是,在遍历以给定数字A[P]开头的数列时,一旦出现不是数列,可以立刻跳出这个循环,开始遍历以A[P+1]开头的数列。因为就算是A[P]这一行后面还有数列,但是这个数列都不是以A[P]开头的了,后面的遍历中会算到这个数列的。

public class Solution {

	public int numberOfArithmeticSlices(int[] A) {
		if (A.length < 3) {
			return 0;
		}
		int nTotal = 0;
		for (int i = 0; i < A.length - 2; i++) {
			int nCurrentIndex = i;
			int nCurrentDiff = Integer.MAX_VALUE;
			// find first seq
			if (isSeq(A[nCurrentIndex], A[nCurrentIndex + 1], A[nCurrentIndex + 2])) {
				nCurrentDiff = A[nCurrentIndex + 1] - A[nCurrentIndex];
				nTotal++;
				nCurrentIndex += 3;
				// find follow seq
				while (nCurrentIndex < A.length) {
					if (A[nCurrentIndex] - A[nCurrentIndex - 1] == nCurrentDiff) {
						nTotal++;
						nCurrentIndex++;
					} else {
						break;
					}
				}
			}
		}
		return nTotal;

	}

	private boolean isSeq(int a, int b, int c) {
		return b - a == c - b ? true : false;
	}
}

以上代码的复杂度为O(n^2),由于大量的内层循环都没有遍历所有剩下的数,具体来说运行时间应该远小于(n+1)n/2

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值