题目链接
解题思路
-
核心在于计算每个元素会出现的次数,然后乘以其值,求和就可以得到结果
-
对于一个如下图所示,有N个元素的数组,以索引i的元素为界,可以把子序列分为
A[0 : i - 1]、A[i]、A[i + 1: n - 1]
这三个部分中
-
显然,一个包含
A[i]
的奇数长度的连续子序列只会有两种情况- 左边和右边的子序列长度均为
奇数
个 - 左边和右边的子序列长度均为
偶数
个 - 注意
0
也是偶数
- 左边和右边的子序列长度均为
-
以第一种情况为例,要从
A[0 : i - 1]
序列中,选取连续的、紧靠A[i]
的,长度为奇数的子序列,所以可能有下面这些情况
- 显然,问题进一步简化为求
1到i中奇数的个数
,右侧也是同样的道理,求1到len-i中奇数的个数
AC代码
class Solution {
public int sumOddLengthSubarrays(int[] arr) {
int ans = 0;
for (int i = 0; i < arr.length; i++) {
int leftOdd = (i + 1) / 2, leftEven = i / 2 + 1;
int rightOdd = (arr.length - i) / 2, rightEven = (arr.length - 1 - i) / 2 + 1;
ans += arr[i] * (leftOdd * rightOdd + leftEven * rightEven);
}
return ans;
}
}
本地测试代码
package com.company;
public class Solution_1588 {
public static int sumOddLengthSubarrays(int[] arr) {
int ans = 0;
for (int i = 0; i < arr.length; i++) {
int leftOdd = (i + 1) / 2, leftEven = i / 2 + 1;
int rightOdd = (arr.length - i) / 2, rightEven = (arr.length - 1 - i) / 2 + 1;
ans += arr[i] * (leftOdd * rightOdd + leftEven * rightEven);
}
return ans;
}
public static void main(String[] args) {
System.out.println(sumOddLengthSubarrays(new int[]{1, 4, 2, 5, 3}));
System.out.println(sumOddLengthSubarrays(new int[]{1, 2}));
System.out.println(sumOddLengthSubarrays(new int[]{10, 11, 12}));
}
}