comments | difficulty | edit_url | tags | |||
---|---|---|---|---|---|---|
true |
Hard |
|
We call an array arr
of length n
consecutive if one of the following holds:
arr[i] - arr[i - 1] == 1
for all1 <= i < n
.arr[i] - arr[i - 1] == -1
for all1 <= i < n
.
The value of an array is the sum of its elements.
For example, [3, 4, 5]
is a consecutive array of value 12 and [9, 8]
is another of value 17. While [3, 4, 3]
and [8, 6]
are not consecutive.
Given an array of integers nums
, return the sum of the values of all consecutive non-empty subsequences.
Since the answer may be very large, return it modulo 109 + 7.
Note that an array of length 1 is also considered consecutive.
Example 1:
Input: nums = [1,2]
Output: 6
Explanation:
The consecutive subsequences are: [1]
, [2]
, [1, 2]
.
Example 2:
Input: nums = [1,4,2,3]
Output: 31
Explanation:
The consecutive subsequences are: [1]
, [4]
, [2]
, [3]
, [1, 2]
, [2, 3]
, [4, 3]
, [1, 2, 3]
.
Constraints:
1 <= nums.length <= 105
1 <= nums[i] <= 105
Let us count how many times each element
We can first compute the contribution of strictly increasing subsequences, then the contribution of strictly decreasing subsequences, and finally add the sum of all elements.
To implement this, we define a function
In the function, we can use two arrays,
In the main function, we first call
The time complexity is
class Solution:
def getSum(self, nums: List[int]) -> int:
def calc(nums: List[int]) -> int:
n = len(nums)
left = [0] * n
right = [0] * n
cnt = Counter()
for i in range(1, n):
cnt[nums[i - 1]] += 1 + cnt[nums[i - 1] - 1]
left[i] = cnt[nums[i] - 1]
cnt = Counter()
for i in range(n - 2, -1, -1):
cnt[nums[i + 1]] += 1 + cnt[nums[i + 1] + 1]
right[i] = cnt[nums[i] + 1]
return sum((l + r + l * r) * x for l, r, x in zip(left, right, nums)) % mod
mod = 10**9 + 7
x = calc(nums)
nums.reverse()
y = calc(nums)
return (x + y + sum(nums)) % mod
class Solution {
private final int mod = (int) 1e9 + 7;
public int getSum(int[] nums) {
long x = calc(nums);
for (int i = 0, j = nums.length - 1; i < j; ++i, --j) {
int t = nums[i];
nums[i] = nums[j];
nums[j] = t;
}
long y = calc(nums);
long s = Arrays.stream(nums).asLongStream().sum();
return (int) ((x + y + s) % mod);
}
private long calc(int[] nums) {
int n = nums.length;
long[] left = new long[n];
long[] right = new long[n];
Map<Integer, Long> cnt = new HashMap<>();
for (int i = 1; i < n; ++i) {
cnt.merge(nums[i - 1], 1 + cnt.getOrDefault(nums[i - 1] - 1, 0L), Long::sum);
left[i] = cnt.getOrDefault(nums[i] - 1, 0L);
}
cnt.clear();
for (int i = n - 2; i >= 0; --i) {
cnt.merge(nums[i + 1], 1 + cnt.getOrDefault(nums[i + 1] + 1, 0L), Long::sum);
right[i] = cnt.getOrDefault(nums[i] + 1, 0L);
}
long ans = 0;
for (int i = 0; i < n; ++i) {
ans = (ans + (left[i] + right[i] + left[i] * right[i] % mod) * nums[i] % mod) % mod;
}
return ans;
}
}
class Solution {
public:
int getSum(vector<int>& nums) {
using ll = long long;
const int mod = 1e9 + 7;
auto calc = [&](const vector<int>& nums) -> ll {
int n = nums.size();
vector<ll> left(n), right(n);
unordered_map<int, ll> cnt;
for (int i = 1; i < n; ++i) {
cnt[nums[i - 1]] += 1 + cnt[nums[i - 1] - 1];
left[i] = cnt[nums[i] - 1];
}
cnt.clear();
for (int i = n - 2; i >= 0; --i) {
cnt[nums[i + 1]] += 1 + cnt[nums[i + 1] + 1];
right[i] = cnt[nums[i] + 1];
}
ll ans = 0;
for (int i = 0; i < n; ++i) {
ans = (ans + (left[i] + right[i] + left[i] * right[i] % mod) * nums[i] % mod) % mod;
}
return ans;
};
ll x = calc(nums);
reverse(nums.begin(), nums.end());
ll y = calc(nums);
ll s = accumulate(nums.begin(), nums.end(), 0LL);
return static_cast<int>((x + y + s) % mod);
}
};
func getSum(nums []int) int {
const mod = 1e9 + 7
calc := func(nums []int) int64 {
n := len(nums)
left := make([]int64, n)
right := make([]int64, n)
cnt := make(map[int]int64)
for i := 1; i < n; i++ {
cnt[nums[i-1]] += 1 + cnt[nums[i-1]-1]
left[i] = cnt[nums[i]-1]
}
cnt = make(map[int]int64)
for i := n - 2; i >= 0; i-- {
cnt[nums[i+1]] += 1 + cnt[nums[i+1]+1]
right[i] = cnt[nums[i]+1]
}
var ans int64
for i, x := range nums {
ans = (ans + (left[i]+right[i]+(left[i]*right[i]%mod))*int64(x)%mod) % mod
}
return ans
}
x := calc(nums)
for i, j := 0, len(nums)-1; i < j; i, j = i+1, j-1 {
nums[i], nums[j] = nums[j], nums[i]
}
y := calc(nums)
s := int64(0)
for _, num := range nums {
s += int64(num)
}
return int((x + y + s) % mod)
}