From 458f0c8441e3e7919dc416c729476063f29bdb65 Mon Sep 17 00:00:00 2001 From: yanglbme Date: Thu, 26 Sep 2024 11:23:06 +0800 Subject: [PATCH] feat: add solutions to lc problem: No.3299 No.3299.Sum of Consecutive Subsequences --- .../README.md | 150 +++++++++++++++++- .../README_EN.md | 150 +++++++++++++++++- .../Solution.cpp | 36 +++++ .../Solution.go | 39 +++++ .../Solution.java | 36 +++++ .../Solution.py | 21 +++ 6 files changed, 422 insertions(+), 10 deletions(-) create mode 100644 solution/3200-3299/3299.Sum of Consecutive Subsequences/Solution.cpp create mode 100644 solution/3200-3299/3299.Sum of Consecutive Subsequences/Solution.go create mode 100644 solution/3200-3299/3299.Sum of Consecutive Subsequences/Solution.java create mode 100644 solution/3200-3299/3299.Sum of Consecutive Subsequences/Solution.py diff --git a/solution/3200-3299/3299.Sum of Consecutive Subsequences/README.md b/solution/3200-3299/3299.Sum of Consecutive Subsequences/README.md index 4a00a781cb041..48c2e9c46567d 100644 --- a/solution/3200-3299/3299.Sum of Consecutive Subsequences/README.md +++ b/solution/3200-3299/3299.Sum of Consecutive Subsequences/README.md @@ -70,32 +70,172 @@ edit_url: https://github.com/doocs/leetcode/edit/main/solution/3200-3299/3299.Su -### 方法一 +### 方法一:枚举贡献 + +我们不妨统计每个元素 $\textit{nums}[i]$ 在多少个长度大于 $1$ 的连续子序列中出现,那么其个数乘以 $\textit{nums}[i]$ 就是 $\textit{nums}[i]$ 在所有长度大于 $1$ 的连续子序列中的贡献。我们将其累加,再加上所有元素的和,即为答案。 + +我们可以先统计连续递增子序列对答案的贡献,再统计连续递减子序列对答案的贡献,最后再加上所有元素的和即可。 + +在实现上,我们定义一个函数 $\textit{calc}(\textit{nums})$,其中 $\textit{nums}$ 是一个数组,返回 $\textit{nums}$ 所有长度大于 $1$ 的连续子序列的和。 + +在函数中,我们可以使用两个数组 $\textit{left}$ 和 $\textit{right}$ 分别记录每个元素 $\textit{nums}[i]$ 的左侧以 $\textit{nums}[i] - 1$ 结尾的连续递增子序列的个数,以及右侧以 $\textit{nums}[i] + 1$ 开头的连续递增子序列的个数。这样,我们就可以在 $O(n)$ 的时间复杂度内计算出 $\textit{nums}$ 在所有长度大于 $1$ 的连续子序列中的贡献。 + +在主函数中,我们首先调用 $\textit{calc}(\textit{nums})$ 计算出连续递增子序列对答案的贡献,然后将 $\textit{nums}$ 反转后再次调用 $\textit{calc}(\textit{nums})$ 计算出连续递减子序列对答案的贡献,最后再加上所有元素的和即为答案。 + +时间复杂度 $O(n)$,空间复杂度 $O(n)$。其中 $n$ 是数组 $\textit{nums}$ 的长度。 #### Python3 ```python - +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 ``` #### Java ```java - +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 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; + } +} ``` #### C++ ```cpp - +class Solution { +public: + int getSum(vector& nums) { + using ll = long long; + const int mod = 1e9 + 7; + auto calc = [&](const vector& nums) -> ll { + int n = nums.size(); + vector left(n), right(n); + unordered_map 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((x + y + s) % mod); + } +}; ``` #### Go ```go - +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) +} ``` diff --git a/solution/3200-3299/3299.Sum of Consecutive Subsequences/README_EN.md b/solution/3200-3299/3299.Sum of Consecutive Subsequences/README_EN.md index 12dc40d8eeed7..50eb45b48cf5c 100644 --- a/solution/3200-3299/3299.Sum of Consecutive Subsequences/README_EN.md +++ b/solution/3200-3299/3299.Sum of Consecutive Subsequences/README_EN.md @@ -70,32 +70,172 @@ edit_url: https://github.com/doocs/leetcode/edit/main/solution/3200-3299/3299.Su -### Solution 1 +### Solution 1: Enumeration of Contributions + +Let us count how many times each element $\textit{nums}[i]$ appears in a continuous subsequence of length greater than 1. Then, multiplying this count by $\textit{nums}[i]$ gives the contribution of $\textit{nums}[i]$ in all continuous subsequences of length greater than 1. We sum these contributions, and adding the sum of all elements, we get the answer. + +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 $\textit{calc}(\textit{nums})$, where $\textit{nums}$ is an array. This function returns the sum of all continuous subsequences of length greater than 1 in $\textit{nums}$. + +In the function, we can use two arrays, $\textit{left}$ and $\textit{right}$, to record the number of strictly increasing subsequences ending with $\textit{nums}[i] - 1$ on the left of each element $\textit{nums}[i]$, and the number of strictly increasing subsequences starting with $\textit{nums}[i] + 1$ on the right of each element $\textit{nums}[i]$. In this way, we can calculate the contribution of $\textit{nums}$ in all continuous subsequences of length greater than 1 in $O(n)$ time complexity. + +In the main function, we first call $\textit{calc}(\textit{nums})$ to compute the contribution of strictly increasing subsequences, then reverse $\textit{nums}$ and call $\textit{calc}(\textit{nums})$ again to compute the contribution of strictly decreasing subsequences. Finally, adding the sum of all elements gives the answer. + +The time complexity is $O(n)$, and the space complexity is $O(n)$, where $n$ is the length of the array $\textit{nums}$. #### Python3 ```python - +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 ``` #### Java ```java - +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 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; + } +} ``` #### C++ ```cpp - +class Solution { +public: + int getSum(vector& nums) { + using ll = long long; + const int mod = 1e9 + 7; + auto calc = [&](const vector& nums) -> ll { + int n = nums.size(); + vector left(n), right(n); + unordered_map 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((x + y + s) % mod); + } +}; ``` #### Go ```go - +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) +} ``` diff --git a/solution/3200-3299/3299.Sum of Consecutive Subsequences/Solution.cpp b/solution/3200-3299/3299.Sum of Consecutive Subsequences/Solution.cpp new file mode 100644 index 0000000000000..781cc9a333ac7 --- /dev/null +++ b/solution/3200-3299/3299.Sum of Consecutive Subsequences/Solution.cpp @@ -0,0 +1,36 @@ +class Solution { +public: + int getSum(vector& nums) { + using ll = long long; + const int mod = 1e9 + 7; + auto calc = [&](const vector& nums) -> ll { + int n = nums.size(); + vector left(n), right(n); + unordered_map 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((x + y + s) % mod); + } +}; diff --git a/solution/3200-3299/3299.Sum of Consecutive Subsequences/Solution.go b/solution/3200-3299/3299.Sum of Consecutive Subsequences/Solution.go new file mode 100644 index 0000000000000..2c4f195819bee --- /dev/null +++ b/solution/3200-3299/3299.Sum of Consecutive Subsequences/Solution.go @@ -0,0 +1,39 @@ +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) +} diff --git a/solution/3200-3299/3299.Sum of Consecutive Subsequences/Solution.java b/solution/3200-3299/3299.Sum of Consecutive Subsequences/Solution.java new file mode 100644 index 0000000000000..00aa08176c94e --- /dev/null +++ b/solution/3200-3299/3299.Sum of Consecutive Subsequences/Solution.java @@ -0,0 +1,36 @@ +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 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; + } +} diff --git a/solution/3200-3299/3299.Sum of Consecutive Subsequences/Solution.py b/solution/3200-3299/3299.Sum of Consecutive Subsequences/Solution.py new file mode 100644 index 0000000000000..2dc76b6a308d7 --- /dev/null +++ b/solution/3200-3299/3299.Sum of Consecutive Subsequences/Solution.py @@ -0,0 +1,21 @@ +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