Skip to content

feat: add solutions to lc problem: No.1588 #3888

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Dec 26, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,17 @@ tags:

<!-- solution:start -->

### Solution 1
### Solution 1: Bubble Sort

The problem is essentially equivalent to determining whether any substring of length 2 in string $s$ can be swapped using bubble sort to obtain $t$.

Therefore, we use an array $pos$ of length 10 to record the indices of each digit in string $s$, where $pos[i]$ represents the list of indices where digit $i$ appears, sorted in ascending order.

Next, we iterate through string $t$. For each character $t[i]$ in $t$, we convert it to the digit $x$. We check if $pos[x]$ is empty. If it is, it means that the digit in $t$ does not exist in $s$, so we return `false`. Otherwise, to swap the character at the first index of $pos[x]$ to index $i$, all indices of digits less than $x$ must be greater than or equal to the first index of $pos[x]. If this condition is not met, we return `false`. Otherwise, we pop the first index from $pos[x]$ and continue iterating through string $t$.

After the iteration, we return `true`.

The time complexity is $O(n \times C)$, and the space complexity is $O(n)$. Here, $n$ is the length of string $s$, and $C$ is the size of the digit set, which is 10 in this problem.

<!-- tabs:start -->

Expand Down
259 changes: 197 additions & 62 deletions solution/1500-1599/1588.Sum of All Odd Length Subarrays/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -80,11 +80,19 @@ tags:

<!-- solution:start -->

### 方法一:枚举 + 前缀和
### 方法一:动态规划

我们可以枚举子数组的起点 $i$ 和终点 $j$,其中 $i \leq j$,维护每个子数组的和,然后判断子数组的长度是否为奇数,如果是,则将子数组的和加入答案
我们定义两个长度为 $n$ 的数组 $f$ 和 $g$,其中 $f[i]$ 表示以 $\textit{arr}[i]$ 结尾的长度为奇数的子数组的和,而 $g[i]$ 表示以 $\textit{arr}[i]$ 结尾的长度为偶数的子数组的和。初始时 $f[0] = \textit{arr}[0]$,而 $g[0] = 0$。答案即为 $\sum_{i=0}^{n-1} f[i]$

时间复杂度 $O(n^2)$,空间复杂度 $O(1)$。其中 $n$ 是数组的长度。
当 $i > 0$ 时,考虑 $f[i]$ 和 $g[i]$ 如何进行状态转移:

对于状态 $f[i]$,元素 $\textit{arr}[i]$ 可以与前面的 $g[i-1]$ 组成一个长度为奇数的子数组,一共可以组成的子数组个数为 $(i / 2) + 1$ 个,因此 $f[i] = g[i-1] + \textit{arr}[i] \times ((i / 2) + 1)$。

对于状态 $g[i]$,当 $i = 0$ 时,没有长度为偶数的子数组,因此 $g[0] = 0$;当 $i > 0$ 时,元素 $\textit{arr}[i]$ 可以与前面的 $f[i-1]$ 组成一个长度为偶数的子数组,一共可以组成的子数组个数为 $(i + 1) / 2$ 个,因此 $g[i] = f[i-1] + \textit{arr}[i] \times ((i + 1) / 2)$。

最终答案即为 $\sum_{i=0}^{n-1} f[i]$。

时间复杂度 $O(n)$,空间复杂度 $O(n)$。其中 $n$ 为数组 $\textit{arr}$ 的长度。

<!-- tabs:start -->

Expand All @@ -93,13 +101,14 @@ tags:
```python
class Solution:
def sumOddLengthSubarrays(self, arr: List[int]) -> int:
ans, n = 0, len(arr)
for i in range(n):
s = 0
for j in range(i, n):
s += arr[j]
if (j - i + 1) & 1:
ans += s
n = len(arr)
f = [0] * n
g = [0] * n
ans = f[0] = arr[0]
for i in range(1, n):
f[i] = g[i - 1] + arr[i] * (i // 2 + 1)
g[i] = f[i - 1] + arr[i] * ((i + 1) // 2)
ans += f[i]
return ans
```

Expand All @@ -109,15 +118,13 @@ class Solution:
class Solution {
public int sumOddLengthSubarrays(int[] arr) {
int n = arr.length;
int ans = 0;
for (int i = 0; i < n; ++i) {
int s = 0;
for (int j = i; j < n; ++j) {
s += arr[j];
if ((j - i + 1) % 2 == 1) {
ans += s;
}
}
int[] f = new int[n];
int[] g = new int[n];
int ans = f[0] = arr[0];
for (int i = 1; i < n; ++i) {
f[i] = g[i - 1] + arr[i] * (i / 2 + 1);
g[i] = f[i - 1] + arr[i] * ((i + 1) / 2);
ans += f[i];
}
return ans;
}
Expand All @@ -131,15 +138,13 @@ class Solution {
public:
int sumOddLengthSubarrays(vector<int>& arr) {
int n = arr.size();
int ans = 0;
for (int i = 0; i < n; ++i) {
int s = 0;
for (int j = i; j < n; ++j) {
s += arr[j];
if ((j - i + 1) & 1) {
ans += s;
}
}
vector<int> f(n, arr[0]);
vector<int> g(n);
int ans = f[0];
for (int i = 1; i < n; ++i) {
f[i] = g[i - 1] + arr[i] * (i / 2 + 1);
g[i] = f[i - 1] + arr[i] * ((i + 1) / 2);
ans += f[i];
}
return ans;
}
Expand All @@ -151,14 +156,14 @@ public:
```go
func sumOddLengthSubarrays(arr []int) (ans int) {
n := len(arr)
for i := range arr {
s := 0
for j := i; j < n; j++ {
s += arr[j]
if (j-i+1)%2 == 1 {
ans += s
}
}
f := make([]int, n)
g := make([]int, n)
f[0] = arr[0]
ans = f[0]
for i := 1; i < n; i++ {
f[i] = g[i-1] + arr[i]*(i/2+1)
g[i] = f[i-1] + arr[i]*((i+1)/2)
ans += f[i]
}
return
}
Expand All @@ -169,15 +174,13 @@ func sumOddLengthSubarrays(arr []int) (ans int) {
```ts
function sumOddLengthSubarrays(arr: number[]): number {
const n = arr.length;
let ans = 0;
for (let i = 0; i < n; ++i) {
let s = 0;
for (let j = i; j < n; ++j) {
s += arr[j];
if ((j - i + 1) % 2 === 1) {
ans += s;
}
}
const f: number[] = Array(n).fill(arr[0]);
const g: number[] = Array(n).fill(0);
let ans = f[0];
for (let i = 1; i < n; ++i) {
f[i] = g[i - 1] + arr[i] * ((i >> 1) + 1);
g[i] = f[i - 1] + arr[i] * ((i + 1) >> 1);
ans += f[i];
}
return ans;
}
Expand All @@ -189,15 +192,14 @@ function sumOddLengthSubarrays(arr: number[]): number {
impl Solution {
pub fn sum_odd_length_subarrays(arr: Vec<i32>) -> i32 {
let n = arr.len();
let mut ans = 0;
for i in 0..n {
let mut s = 0;
for j in i..n {
s += arr[j];
if (j - i + 1) % 2 == 1 {
ans += s;
}
}
let mut f = vec![0; n];
let mut g = vec![0; n];
let mut ans = arr[0];
f[0] = arr[0];
for i in 1..n {
f[i] = g[i - 1] + arr[i] * ((i as i32) / 2 + 1);
g[i] = f[i - 1] + arr[i] * (((i + 1) as i32) / 2);
ans += f[i];
}
ans
}
Expand All @@ -208,15 +210,148 @@ impl Solution {

```c
int sumOddLengthSubarrays(int* arr, int arrSize) {
int ans = 0;
for (int i = 0; i < arrSize; ++i) {
int s = 0;
for (int j = i; j < arrSize; ++j) {
s += arr[j];
if ((j - i + 1) % 2 == 1) {
ans += s;
}
int n = arrSize;
int f[n];
int g[n];
int ans = f[0] = arr[0];
g[0] = 0;
for (int i = 1; i < n; ++i) {
f[i] = g[i - 1] + arr[i] * (i / 2 + 1);
g[i] = f[i - 1] + arr[i] * ((i + 1) / 2);
ans += f[i];
}
return ans;
}
```

<!-- tabs:end -->

<!-- solution:end -->

<!-- solution:start -->

### 方法二:动态规划(空间优化)

我们注意到,状态 $f[i]$ 和 $g[i]$ 的值只与 $f[i - 1]$ 和 $g[i - 1]$ 有关,因此我们可以使用两个变量 $f$ 和 $g$ 分别记录 $f[i - 1]$ 和 $g[i - 1]$ 的值,从而优化空间复杂度。

时间复杂度 $O(n)$,空间复杂度 $O(1)$。

<!-- tabs:start -->

#### Python3

```python
class Solution:
def sumOddLengthSubarrays(self, arr: List[int]) -> int:
ans, f, g = arr[0], arr[0], 0
for i in range(1, len(arr)):
ff = g + arr[i] * (i // 2 + 1)
gg = f + arr[i] * ((i + 1) // 2)
f, g = ff, gg
ans += f
return ans
```

#### Java

```java
class Solution {
public int sumOddLengthSubarrays(int[] arr) {
int ans = arr[0], f = arr[0], g = 0;
for (int i = 1; i < arr.length; ++i) {
int ff = g + arr[i] * (i / 2 + 1);
int gg = f + arr[i] * ((i + 1) / 2);
f = ff;
g = gg;
ans += f;
}
return ans;
}
}
```

#### C++

```cpp
class Solution {
public:
int sumOddLengthSubarrays(vector<int>& arr) {
int ans = arr[0], f = arr[0], g = 0;
for (int i = 1; i < arr.size(); ++i) {
int ff = g + arr[i] * (i / 2 + 1);
int gg = f + arr[i] * ((i + 1) / 2);
f = ff;
g = gg;
ans += f;
}
return ans;
}
};
```

#### Go

```go
func sumOddLengthSubarrays(arr []int) (ans int) {
f, g := arr[0], 0
ans = f
for i := 1; i < len(arr); i++ {
ff := g + arr[i]*(i/2+1)
gg := f + arr[i]*((i+1)/2)
f, g = ff, gg
ans += f
}
return
}
```

#### TypeScript

```ts
function sumOddLengthSubarrays(arr: number[]): number {
const n = arr.length;
let [ans, f, g] = [arr[0], arr[0], 0];
for (let i = 1; i < n; ++i) {
const ff = g + arr[i] * (Math.floor(i / 2) + 1);
const gg = f + arr[i] * Math.floor((i + 1) / 2);
[f, g] = [ff, gg];
ans += f;
}
return ans;
}
```

#### Rust

```rust
impl Solution {
pub fn sum_odd_length_subarrays(arr: Vec<i32>) -> i32 {
let mut ans = arr[0];
let mut f = arr[0];
let mut g = 0;
for i in 1..arr.len() {
let ff = g + arr[i] * ((i as i32) / 2 + 1);
let gg = f + arr[i] * (((i + 1) as i32) / 2);
f = ff;
g = gg;
ans += f;
}
ans
}
}
```

#### C

```c
int sumOddLengthSubarrays(int* arr, int arrSize) {
int ans = arr[0], f = arr[0], g = 0;
for (int i = 1; i < arrSize; ++i) {
int ff = g + arr[i] * (i / 2 + 1);
int gg = f + arr[i] * ((i + 1) / 2);
f = ff;
g = gg;
ans += f;
}
return ans;
}
Expand Down
Loading
Loading