Skip to content

Commit ccc354f

Browse files
authored
feat: add solutions to lc problem: No.1458 (#3354)
No.1458.Max Dot Product of Two Subsequences
1 parent 3b44422 commit ccc354f

File tree

8 files changed

+177
-124
lines changed

8 files changed

+177
-124
lines changed

solution/1400-1499/1458.Max Dot Product of Two Subsequences/README.md

+60-45
Original file line numberDiff line numberDiff line change
@@ -80,17 +80,16 @@ tags:
8080

8181
### 方法一:动态规划
8282

83-
定义 $dp[i][j]$ 表示 $nums1$ 前 $i$ 个元素和 $nums2$ 前 $j$ 个元素得到的最大点积
83+
我们定义 $f[i][j]$ 表示 $\textit{nums1}$ 的前 $i$ 个元素和 $\textit{nums2}$ 的前 $j$ 个元素构成的两个子序列的最大点积。初始时 $f[i][j] = -\infty$
8484

85-
那么有
85+
对于 $f[i][j]$,我们有以下几种情况
8686

87-
$$
88-
dp[i][j]=max(dp[i-1][j], dp[i][j - 1], max(dp[i - 1][j - 1], 0) + nums1[i] \times nums2[j])
89-
$$
87+
1. 不选 $\textit{nums1}[i-1]$ 或者不选 $\textit{nums2}[j-1]$,即 $f[i][j] = \max(f[i-1][j], f[i][j-1])$;
88+
2. 选 $\textit{nums1}[i-1]$ 和 $\textit{nums2}[j-1]$,即 $f[i][j] = \max(f[i][j], \max(0, f[i-1][j-1]) + \textit{nums1}[i-1] \times \textit{nums2}[j-1])$。
9089

91-
答案为 $dp[m][n]$。
90+
最终答案即为 $f[m][n]$。
9291

93-
时间复杂度 $O(m \times n)$,空间复杂度 $O(m \times n)$。其中 $m$ 和 $n$ 分别是数组 $nums1$ 和 $nums2$ 的长度。
92+
时间复杂度 $O(m \times n)$,空间复杂度 $O(m \times n)$。其中 $m$ 和 $n$ 分别是数组 $\textit{nums1}$ 和 $\textit{nums2}$ 的长度。
9493

9594
<!-- tabs:start -->
9695

@@ -100,12 +99,12 @@ $$
10099
class Solution:
101100
def maxDotProduct(self, nums1: List[int], nums2: List[int]) -> int:
102101
m, n = len(nums1), len(nums2)
103-
dp = [[-inf] * (n + 1) for _ in range(m + 1)]
104-
for i in range(1, m + 1):
105-
for j in range(1, n + 1):
106-
v = nums1[i - 1] * nums2[j - 1]
107-
dp[i][j] = max(dp[i - 1][j], dp[i][j - 1], max(dp[i - 1][j - 1], 0) + v)
108-
return dp[-1][-1]
102+
f = [[-inf] * (n + 1) for _ in range(m + 1)]
103+
for i, x in enumerate(nums1, 1):
104+
for j, y in enumerate(nums2, 1):
105+
v = x * y
106+
f[i][j] = max(f[i - 1][j], f[i][j - 1], max(0, f[i - 1][j - 1]) + v)
107+
return f[m][n]
109108
```
110109

111110
#### Java
@@ -114,18 +113,18 @@ class Solution:
114113
class Solution {
115114
public int maxDotProduct(int[] nums1, int[] nums2) {
116115
int m = nums1.length, n = nums2.length;
117-
int[][] dp = new int[m + 1][n + 1];
118-
for (int[] e : dp) {
119-
Arrays.fill(e, Integer.MIN_VALUE);
116+
int[][] f = new int[m + 1][n + 1];
117+
for (var g : f) {
118+
Arrays.fill(g, Integer.MIN_VALUE);
120119
}
121120
for (int i = 1; i <= m; ++i) {
122121
for (int j = 1; j <= n; ++j) {
123-
dp[i][j] = Math.max(dp[i - 1][j], dp[i][j - 1]);
124-
dp[i][j] = Math.max(
125-
dp[i][j], Math.max(0, dp[i - 1][j - 1]) + nums1[i - 1] * nums2[j - 1]);
122+
int v = nums1[i - 1] * nums2[j - 1];
123+
f[i][j] = Math.max(f[i - 1][j], f[i][j - 1]);
124+
f[i][j] = Math.max(f[i][j], Math.max(f[i - 1][j - 1], 0) + v);
126125
}
127126
}
128-
return dp[m][n];
127+
return f[m][n];
129128
}
130129
}
131130
```
@@ -137,15 +136,16 @@ class Solution {
137136
public:
138137
int maxDotProduct(vector<int>& nums1, vector<int>& nums2) {
139138
int m = nums1.size(), n = nums2.size();
140-
vector<vector<int>> dp(m + 1, vector<int>(n + 1, INT_MIN));
139+
int f[m + 1][n + 1];
140+
memset(f, 0xc0, sizeof f);
141141
for (int i = 1; i <= m; ++i) {
142142
for (int j = 1; j <= n; ++j) {
143143
int v = nums1[i - 1] * nums2[j - 1];
144-
dp[i][j] = max(dp[i - 1][j], dp[i][j - 1]);
145-
dp[i][j] = max(dp[i][j], max(0, dp[i - 1][j - 1]) + v);
144+
f[i][j] = max(f[i - 1][j], f[i][j - 1]);
145+
f[i][j] = max(f[i][j], max(0, f[i - 1][j - 1]) + v);
146146
}
147147
}
148-
return dp[m][n];
148+
return f[m][n];
149149
}
150150
};
151151
```
@@ -155,45 +155,60 @@ public:
155155
```go
156156
func maxDotProduct(nums1 []int, nums2 []int) int {
157157
m, n := len(nums1), len(nums2)
158-
dp := make([][]int, m+1)
159-
for i := range dp {
160-
dp[i] = make([]int, n+1)
161-
for j := range dp[i] {
162-
dp[i][j] = math.MinInt32
158+
f := make([][]int, m+1)
159+
for i := range f {
160+
f[i] = make([]int, n+1)
161+
for j := range f[i] {
162+
f[i][j] = math.MinInt32
163163
}
164164
}
165165
for i := 1; i <= m; i++ {
166166
for j := 1; j <= n; j++ {
167167
v := nums1[i-1] * nums2[j-1]
168-
dp[i][j] = max(dp[i-1][j], dp[i][j-1])
169-
dp[i][j] = max(dp[i][j], max(0, dp[i-1][j-1])+v)
168+
f[i][j] = max(f[i-1][j], f[i][j-1])
169+
f[i][j] = max(f[i][j], max(0, f[i-1][j-1])+v)
170170
}
171171
}
172-
return dp[m][n]
172+
return f[m][n]
173+
}
174+
```
175+
176+
#### TypeScript
177+
178+
```ts
179+
function maxDotProduct(nums1: number[], nums2: number[]): number {
180+
const m = nums1.length;
181+
const n = nums2.length;
182+
const f = Array.from({ length: m + 1 }, () => Array.from({ length: n + 1 }, () => -Infinity));
183+
for (let i = 1; i <= m; ++i) {
184+
for (let j = 1; j <= n; ++j) {
185+
const v = nums1[i - 1] * nums2[j - 1];
186+
f[i][j] = Math.max(f[i - 1][j], f[i][j - 1]);
187+
f[i][j] = Math.max(f[i][j], Math.max(0, f[i - 1][j - 1]) + v);
188+
}
189+
}
190+
return f[m][n];
173191
}
174192
```
175193

176194
#### Rust
177195

178196
```rust
179197
impl Solution {
180-
#[allow(dead_code)]
181198
pub fn max_dot_product(nums1: Vec<i32>, nums2: Vec<i32>) -> i32 {
182-
let n = nums1.len();
183-
let m = nums2.len();
184-
let mut dp = vec![vec![i32::MIN; m + 1]; n + 1];
185-
186-
// Begin the actual dp process
187-
for i in 1..=n {
188-
for j in 1..=m {
189-
dp[i][j] = std::cmp::max(
190-
std::cmp::max(dp[i - 1][j], dp[i][j - 1]),
191-
std::cmp::max(dp[i - 1][j - 1], 0) + nums1[i - 1] * nums2[j - 1],
192-
);
199+
let m = nums1.len();
200+
let n = nums2.len();
201+
let mut f = vec![vec![i32::MIN; n + 1]; m + 1];
202+
203+
for i in 1..=m {
204+
for j in 1..=n {
205+
let v = nums1[i - 1] * nums2[j - 1];
206+
f[i][j] = f[i][j].max(f[i - 1][j]).max(f[i][j - 1]);
207+
f[i][j] = f[i][j].max(f[i - 1][j - 1].max(0) + v);
193208
}
194209
}
195210

196-
dp[n][m]
211+
f[m][n]
197212
}
198213
}
199214
```

solution/1400-1499/1458.Max Dot Product of Two Subsequences/README_EN.md

+66-39
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,18 @@ Their dot product is -1.</pre>
6464

6565
<!-- solution:start -->
6666

67-
### Solution 1
67+
### Solution 1: Dynamic Programming
68+
69+
We define $f[i][j]$ to represent the maximum dot product of two subsequences formed by the first $i$ elements of $\textit{nums1}$ and the first $j$ elements of $\textit{nums2}$. Initially, $f[i][j] = -\infty$.
70+
71+
For $f[i][j]$, we have the following cases:
72+
73+
1. Do not select $\textit{nums1}[i-1]$ or do not select $\textit{nums2}[j-1]$, i.e., $f[i][j] = \max(f[i-1][j], f[i][j-1])$;
74+
2. Select $\textit{nums1}[i-1]$ and $\textit{nums2}[j-1]$, i.e., $f[i][j] = \max(f[i][j], \max(0, f[i-1][j-1]) + \textit{nums1}[i-1] \times \textit{nums2}[j-1])$.
75+
76+
The final answer is $f[m][n]$.
77+
78+
The time complexity is $O(m \times n)$, and the space complexity is $O(m \times n)$. Here, $m$ and $n$ are the lengths of the arrays $\textit{nums1}$ and $\textit{nums2}$, respectively.
6879

6980
<!-- tabs:start -->
7081

@@ -74,12 +85,12 @@ Their dot product is -1.</pre>
7485
class Solution:
7586
def maxDotProduct(self, nums1: List[int], nums2: List[int]) -> int:
7687
m, n = len(nums1), len(nums2)
77-
dp = [[-inf] * (n + 1) for _ in range(m + 1)]
78-
for i in range(1, m + 1):
79-
for j in range(1, n + 1):
80-
v = nums1[i - 1] * nums2[j - 1]
81-
dp[i][j] = max(dp[i - 1][j], dp[i][j - 1], max(dp[i - 1][j - 1], 0) + v)
82-
return dp[-1][-1]
88+
f = [[-inf] * (n + 1) for _ in range(m + 1)]
89+
for i, x in enumerate(nums1, 1):
90+
for j, y in enumerate(nums2, 1):
91+
v = x * y
92+
f[i][j] = max(f[i - 1][j], f[i][j - 1], max(0, f[i - 1][j - 1]) + v)
93+
return f[m][n]
8394
```
8495

8596
#### Java
@@ -88,18 +99,18 @@ class Solution:
8899
class Solution {
89100
public int maxDotProduct(int[] nums1, int[] nums2) {
90101
int m = nums1.length, n = nums2.length;
91-
int[][] dp = new int[m + 1][n + 1];
92-
for (int[] e : dp) {
93-
Arrays.fill(e, Integer.MIN_VALUE);
102+
int[][] f = new int[m + 1][n + 1];
103+
for (var g : f) {
104+
Arrays.fill(g, Integer.MIN_VALUE);
94105
}
95106
for (int i = 1; i <= m; ++i) {
96107
for (int j = 1; j <= n; ++j) {
97-
dp[i][j] = Math.max(dp[i - 1][j], dp[i][j - 1]);
98-
dp[i][j] = Math.max(
99-
dp[i][j], Math.max(0, dp[i - 1][j - 1]) + nums1[i - 1] * nums2[j - 1]);
108+
int v = nums1[i - 1] * nums2[j - 1];
109+
f[i][j] = Math.max(f[i - 1][j], f[i][j - 1]);
110+
f[i][j] = Math.max(f[i][j], Math.max(f[i - 1][j - 1], 0) + v);
100111
}
101112
}
102-
return dp[m][n];
113+
return f[m][n];
103114
}
104115
}
105116
```
@@ -111,15 +122,16 @@ class Solution {
111122
public:
112123
int maxDotProduct(vector<int>& nums1, vector<int>& nums2) {
113124
int m = nums1.size(), n = nums2.size();
114-
vector<vector<int>> dp(m + 1, vector<int>(n + 1, INT_MIN));
125+
int f[m + 1][n + 1];
126+
memset(f, 0xc0, sizeof f);
115127
for (int i = 1; i <= m; ++i) {
116128
for (int j = 1; j <= n; ++j) {
117129
int v = nums1[i - 1] * nums2[j - 1];
118-
dp[i][j] = max(dp[i - 1][j], dp[i][j - 1]);
119-
dp[i][j] = max(dp[i][j], max(0, dp[i - 1][j - 1]) + v);
130+
f[i][j] = max(f[i - 1][j], f[i][j - 1]);
131+
f[i][j] = max(f[i][j], max(0, f[i - 1][j - 1]) + v);
120132
}
121133
}
122-
return dp[m][n];
134+
return f[m][n];
123135
}
124136
};
125137
```
@@ -129,45 +141,60 @@ public:
129141
```go
130142
func maxDotProduct(nums1 []int, nums2 []int) int {
131143
m, n := len(nums1), len(nums2)
132-
dp := make([][]int, m+1)
133-
for i := range dp {
134-
dp[i] = make([]int, n+1)
135-
for j := range dp[i] {
136-
dp[i][j] = math.MinInt32
144+
f := make([][]int, m+1)
145+
for i := range f {
146+
f[i] = make([]int, n+1)
147+
for j := range f[i] {
148+
f[i][j] = math.MinInt32
137149
}
138150
}
139151
for i := 1; i <= m; i++ {
140152
for j := 1; j <= n; j++ {
141153
v := nums1[i-1] * nums2[j-1]
142-
dp[i][j] = max(dp[i-1][j], dp[i][j-1])
143-
dp[i][j] = max(dp[i][j], max(0, dp[i-1][j-1])+v)
154+
f[i][j] = max(f[i-1][j], f[i][j-1])
155+
f[i][j] = max(f[i][j], max(0, f[i-1][j-1])+v)
144156
}
145157
}
146-
return dp[m][n]
158+
return f[m][n]
159+
}
160+
```
161+
162+
#### TypeScript
163+
164+
```ts
165+
function maxDotProduct(nums1: number[], nums2: number[]): number {
166+
const m = nums1.length;
167+
const n = nums2.length;
168+
const f = Array.from({ length: m + 1 }, () => Array.from({ length: n + 1 }, () => -Infinity));
169+
for (let i = 1; i <= m; ++i) {
170+
for (let j = 1; j <= n; ++j) {
171+
const v = nums1[i - 1] * nums2[j - 1];
172+
f[i][j] = Math.max(f[i - 1][j], f[i][j - 1]);
173+
f[i][j] = Math.max(f[i][j], Math.max(0, f[i - 1][j - 1]) + v);
174+
}
175+
}
176+
return f[m][n];
147177
}
148178
```
149179

150180
#### Rust
151181

152182
```rust
153183
impl Solution {
154-
#[allow(dead_code)]
155184
pub fn max_dot_product(nums1: Vec<i32>, nums2: Vec<i32>) -> i32 {
156-
let n = nums1.len();
157-
let m = nums2.len();
158-
let mut dp = vec![vec![i32::MIN; m + 1]; n + 1];
159-
160-
// Begin the actual dp process
161-
for i in 1..=n {
162-
for j in 1..=m {
163-
dp[i][j] = std::cmp::max(
164-
std::cmp::max(dp[i - 1][j], dp[i][j - 1]),
165-
std::cmp::max(dp[i - 1][j - 1], 0) + nums1[i - 1] * nums2[j - 1],
166-
);
185+
let m = nums1.len();
186+
let n = nums2.len();
187+
let mut f = vec![vec![i32::MIN; n + 1]; m + 1];
188+
189+
for i in 1..=m {
190+
for j in 1..=n {
191+
let v = nums1[i - 1] * nums2[j - 1];
192+
f[i][j] = f[i][j].max(f[i - 1][j]).max(f[i][j - 1]);
193+
f[i][j] = f[i][j].max(f[i - 1][j - 1].max(0) + v);
167194
}
168195
}
169196

170-
dp[n][m]
197+
f[m][n]
171198
}
172199
}
173200
```

solution/1400-1499/1458.Max Dot Product of Two Subsequences/Solution.cpp

+6-5
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,15 @@ class Solution {
22
public:
33
int maxDotProduct(vector<int>& nums1, vector<int>& nums2) {
44
int m = nums1.size(), n = nums2.size();
5-
vector<vector<int>> dp(m + 1, vector<int>(n + 1, INT_MIN));
5+
int f[m + 1][n + 1];
6+
memset(f, 0xc0, sizeof f);
67
for (int i = 1; i <= m; ++i) {
78
for (int j = 1; j <= n; ++j) {
89
int v = nums1[i - 1] * nums2[j - 1];
9-
dp[i][j] = max(dp[i - 1][j], dp[i][j - 1]);
10-
dp[i][j] = max(dp[i][j], max(0, dp[i - 1][j - 1]) + v);
10+
f[i][j] = max(f[i - 1][j], f[i][j - 1]);
11+
f[i][j] = max(f[i][j], max(0, f[i - 1][j - 1]) + v);
1112
}
1213
}
13-
return dp[m][n];
14+
return f[m][n];
1415
}
15-
};
16+
};
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,18 @@
11
func maxDotProduct(nums1 []int, nums2 []int) int {
22
m, n := len(nums1), len(nums2)
3-
dp := make([][]int, m+1)
4-
for i := range dp {
5-
dp[i] = make([]int, n+1)
6-
for j := range dp[i] {
7-
dp[i][j] = math.MinInt32
3+
f := make([][]int, m+1)
4+
for i := range f {
5+
f[i] = make([]int, n+1)
6+
for j := range f[i] {
7+
f[i][j] = math.MinInt32
88
}
99
}
1010
for i := 1; i <= m; i++ {
1111
for j := 1; j <= n; j++ {
1212
v := nums1[i-1] * nums2[j-1]
13-
dp[i][j] = max(dp[i-1][j], dp[i][j-1])
14-
dp[i][j] = max(dp[i][j], max(0, dp[i-1][j-1])+v)
13+
f[i][j] = max(f[i-1][j], f[i][j-1])
14+
f[i][j] = max(f[i][j], max(0, f[i-1][j-1])+v)
1515
}
1616
}
17-
return dp[m][n]
18-
}
17+
return f[m][n]
18+
}

0 commit comments

Comments
 (0)