1. 题目
数组 A 包含 N 个数,且索引从0开始。数组 A 的一个子数组划分为数组 (P, Q),P 与 Q 是整数且满足 0<=P<Q<N 。
如果满足以下条件,则称子数组(P, Q)为等差数组:
元素 A[P], A[p + 1], ..., A[Q - 1], A[Q] 是等差的。并且 P + 1 < Q 。
函数要返回数组 A 中所有为等差数组的子数组个数
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/arithmetic-slices
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
2. 示例
A = [1, 2, 3, 4]
返回: 3, A 中有三个子等差数组: [1, 2, 3], [2, 3, 4] 以及自身 [1, 2, 3, 4]
3. 题解
本题需要注意的几个地方:
* 1. 子等差数组一定要相邻
* 2. 满足等差
* 因此本题只要固定第一个元素,然后遍历后面所有数,* 只要满足都sum+1; 否则,退出当前循环。
4. Code
4.1 暴力
1 public class NumberOfArithmeticSlices {
2 public int numberOfArithmeticSlices(int[] nums) {
3 /**
4 * 思想:暴力
5 * 题解:
6 * 本题需要注意的几个地方:
7 * 1. 子等差数组一定要相邻
8 * 2. 满足等差
9 * 因此本题只要固定第一个元素,然后遍历后面所有数,
10 * 只要满足都sum+1; 否则,退出当前循环。
11 */
12 int sum = 0;
13 for(int i = 0; i < nums.length - 2; i++) {
14 int curId = 1, temp = nums[i + 1] - nums[i];
15 for(int j = i + 2; j < nums.length; j++) {
16 if(temp * curId + nums[i + 1] == nums[j]) {
17 curId++;
18 sum++;
19 } else {
20 break;
21 }
22 }
23 }
24 return sum;
25 }
26
27 public static void main(String[] args) {
28 int[] nums = {1, 2, 3, 4, 5, 6};
29 System.out.println(new NumberOfArithmeticSlices().numberOfArithmeticSlices(nums));
30 }
31 }
4.2 动态规划
1 public int numberOfArithmeticSlicesB(int[] nums) {
2 /**
3 * 思想:动态规划
4 * 题解:
5 * 是暴力法的反向
6 * 这里dp[i]存储的是以i结尾的子等差数列数,
7 * 所以还需要一个sum来保存所有的数。
8 */
9 int[]dp = new int[nums.length];
10 int sum = 0;
11 for(int i = 2; i < nums.length; i++) {
12 if(nums[i] - nums[i - 1] == nums[i - 1] - nums[i - 2]) {
13 dp[i] = dp[i - 1] + 1;
14 sum += dp[i];
15 }
16 }
17 return sum;
18 }
4.3 动态规划优化
1 public int numberOfArithmeticSlicesC(int[] nums) {
2 /**
3 * 思想:动态规划
4 * 题解:
5 * 是动态规划的优化,第i个dp[i]只用到了dp[i-1]
6 * 所以可以替换
7 */
8 int sum = 0;
9 int temp = 0;
10 for(int i = 2; i < nums.length; i++) {
11 if(nums[i] - nums[i - 1] == nums[i - 1] - nums[i - 2]) {
12 temp = temp + 1;
13 sum += temp;
14 } else {
15 temp = 0;
16 }
17 }
18 return sum;
19 }