Skip to content

Commit 11df55b

Browse files
committed
feat: add solutions to lc problem: No.2245
No.2245.Maximum Trailing Zeros in a Cornered Path
1 parent 1c9ec93 commit 11df55b

File tree

7 files changed

+641
-107
lines changed

7 files changed

+641
-107
lines changed

solution/2200-2299/2245.Maximum Trailing Zeros in a Cornered Path/README.md

Lines changed: 234 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -65,67 +65,265 @@
6565

6666
<!-- 这里可写通用的实现逻辑 -->
6767

68+
**方法一:前缀和 + 枚举拐点**
69+
70+
首先我们要明确,对于一个乘积,尾随零的个数取决于因子中 $2$ 和 $5$ 的个数的较小值。另外,每一条转角路径应该覆盖尽可能多的数,因此,它一定是从某个边界出发,到达某个拐点,再到达另一个边界。
71+
72+
因此,我们可以创建四个二维数组 $r2$, $c2$, $r5$, $c5$ 来记录每一行和每一列中 $2$ 和 $5$ 的个数。其中:
73+
74+
- `r2[i][j]` 表示第 $i$ 行中从第 $1$ 列到第 $j$ 列的 $2$ 的个数;
75+
- `c2[i][j]` 表示第 $j$ 列中从第 $1$ 行到第 $i$ 行的 $2$ 的个数;
76+
- `r5[i][j]` 表示第 $i$ 行中从第 $1$ 列到第 $j$ 列的 $5$ 的个数;
77+
- `c5[i][j]` 表示第 $j$ 列中从第 $1$ 行到第 $i$ 行的 $5$ 的个数。
78+
79+
接下来,我们遍历二维数组 `grid`,对于每个数,我们计算它的 $2$ 和 $5$ 的个数,然后更新四个二维数组。
80+
81+
然后,我们枚举拐点 $(i, j)$,对于每个拐点,我们计算四个值,其中:
82+
83+
- `a` 表示从 $(i, 1)$ 右移到 $(i, j)$,再从 $(i, j)$ 拐头向上移动到 $(1, j)$ 的路径中 $2$ 的个数和 $5$ 的个数的较小值;
84+
- `b` 表示从 $(i, 1)$ 右移到 $(i, j)$,再从 $(i, j)$ 拐头向下移动到 $(m, j)$ 的路径中 $2$ 的个数和 $5$ 的个数的较小值;
85+
- `c` 表示从 $(i, n)$ 左移到 $(i, j)$,再从 $(i, j)$ 拐头向上移动到 $(1, j)$ 的路径中 $2$ 的个数和 $5$ 的个数的较小值;
86+
- `d` 表示从 $(i, n)$ 左移到 $(i, j)$,再从 $(i, j)$ 拐头向下移动到 $(m, j)$ 的路径中 $2$ 的个数和 $5$ 的个数的较小值。
87+
88+
每一次枚举,我们取这四个值的最大值,然后更新答案。
89+
90+
最后,我们返回答案即可。
91+
92+
时间复杂度 $O(m \times n)$,空间复杂度 $O(m \times n)$。其中 $m$ 和 $n$ 分别是二维数组 `grid` 的行数和列数。
93+
6894
<!-- tabs:start -->
6995

7096
### **Python3**
7197

7298
<!-- 这里可写当前语言的特殊实现逻辑 -->
7399

74100
```python
75-
101+
class Solution:
102+
def maxTrailingZeros(self, grid: List[List[int]]) -> int:
103+
m, n = len(grid), len(grid[0])
104+
r2 = [[0] * (n + 1) for _ in range(m + 1)]
105+
c2 = [[0] * (n + 1) for _ in range(m + 1)]
106+
r5 = [[0] * (n + 1) for _ in range(m + 1)]
107+
c5 = [[0] * (n + 1) for _ in range(m + 1)]
108+
for i, row in enumerate(grid, 1):
109+
for j, x in enumerate(row, 1):
110+
s2 = s5 = 0
111+
while x % 2 == 0:
112+
x //= 2
113+
s2 += 1
114+
while x % 5 == 0:
115+
x //= 5
116+
s5 += 1
117+
r2[i][j] = r2[i][j - 1] + s2
118+
c2[i][j] = c2[i - 1][j] + s2
119+
r5[i][j] = r5[i][j - 1] + s5
120+
c5[i][j] = c5[i - 1][j] + s5
121+
ans = 0
122+
for i in range(1, m + 1):
123+
for j in range(1, n + 1):
124+
a = min(r2[i][j] + c2[i - 1][j], r5[i][j] + c5[i - 1][j])
125+
b = min(r2[i][j] + c2[m][j] - c2[i][j], r5[i][j] + c5[m][j] - c5[i][j])
126+
c = min(r2[i][n] - r2[i][j] + c2[i][j], r5[i][n] - r5[i][j] + c5[i][j])
127+
d = min(
128+
r2[i][n] - r2[i][j - 1] + c2[m][j] - c2[i][j],
129+
r5[i][n] - r5[i][j - 1] + c5[m][j] - c5[i][j],
130+
)
131+
ans = max(ans, a, b, c, d)
132+
return ans
76133
```
77134

78135
### **Java**
79136

80137
<!-- 这里可写当前语言的特殊实现逻辑 -->
81138

82139
```java
140+
class Solution {
141+
public int maxTrailingZeros(int[][] grid) {
142+
int m = grid.length, n = grid[0].length;
143+
int[][] r2 = new int[m + 1][n + 1];
144+
int[][] c2 = new int[m + 1][n + 1];
145+
int[][] r5 = new int[m + 1][n + 1];
146+
int[][] c5 = new int[m + 1][n + 1];
147+
for (int i = 1; i <= m; ++i) {
148+
for (int j = 1; j <= n; ++j) {
149+
int x = grid[i - 1][j - 1];
150+
int s2 = 0, s5 = 0;
151+
for (; x % 2 == 0; x /= 2) {
152+
++s2;
153+
}
154+
for (; x % 5 == 0; x /= 5) {
155+
++s5;
156+
}
157+
r2[i][j] = r2[i][j - 1] + s2;
158+
c2[i][j] = c2[i - 1][j] + s2;
159+
r5[i][j] = r5[i][j - 1] + s5;
160+
c5[i][j] = c5[i - 1][j] + s5;
161+
}
162+
}
163+
int ans = 0;
164+
for (int i = 1; i <= m; ++i) {
165+
for (int j = 1; j <= n; ++j) {
166+
int a = Math.min(r2[i][j] + c2[i - 1][j], r5[i][j] + c5[i - 1][j]);
167+
int b = Math.min(r2[i][j] + c2[m][j] - c2[i][j], r5[i][j] + c5[m][j] - c5[i][j]);
168+
int c = Math.min(r2[i][n] - r2[i][j] + c2[i][j], r5[i][n] - r5[i][j] + c5[i][j]);
169+
int d = Math.min(r2[i][n] - r2[i][j - 1] + c2[m][j] - c2[i][j], r5[i][n] - r5[i][j - 1] + c5[m][j] - c5[i][j]);
170+
ans = Math.max(ans, Math.max(a, Math.max(b, Math.max(c, d))));
171+
}
172+
}
173+
return ans;
174+
}
175+
}
176+
```
83177

178+
### **C++**
179+
180+
```cpp
181+
class Solution {
182+
public:
183+
int maxTrailingZeros(vector<vector<int>>& grid) {
184+
int m = grid.size(), n = grid[0].size();
185+
vector<vector<int>> r2(m + 1, vector<int>(n + 1));
186+
vector<vector<int>> c2(m + 1, vector<int>(n + 1));
187+
vector<vector<int>> r5(m + 1, vector<int>(n + 1));
188+
vector<vector<int>> c5(m + 1, vector<int>(n + 1));
189+
for (int i = 1; i <= m; ++i) {
190+
for (int j = 1; j <= n; ++j) {
191+
int x = grid[i - 1][j - 1];
192+
int s2 = 0, s5 = 0;
193+
for (; x % 2 == 0; x /= 2) {
194+
++s2;
195+
}
196+
for (; x % 5 == 0; x /= 5) {
197+
++s5;
198+
}
199+
r2[i][j] = r2[i][j - 1] + s2;
200+
c2[i][j] = c2[i - 1][j] + s2;
201+
r5[i][j] = r5[i][j - 1] + s5;
202+
c5[i][j] = c5[i - 1][j] + s5;
203+
}
204+
}
205+
int ans = 0;
206+
for (int i = 1; i <= m; ++i) {
207+
for (int j = 1; j <= n; ++j) {
208+
int a = min(r2[i][j] + c2[i - 1][j], r5[i][j] + c5[i - 1][j]);
209+
int b = min(r2[i][j] + c2[m][j] - c2[i][j], r5[i][j] + c5[m][j] - c5[i][j]);
210+
int c = min(r2[i][n] - r2[i][j] + c2[i][j], r5[i][n] - r5[i][j] + c5[i][j]);
211+
int d = min(r2[i][n] - r2[i][j - 1] + c2[m][j] - c2[i][j], r5[i][n] - r5[i][j - 1] + c5[m][j] - c5[i][j]);
212+
ans = max({ans, a, b, c, d});
213+
}
214+
}
215+
return ans;
216+
}
217+
};
218+
```
219+
220+
### **Go**
221+
222+
```go
223+
func maxTrailingZeros(grid [][]int) (ans int) {
224+
m, n := len(grid), len(grid[0])
225+
r2 := get(m+1, n+1)
226+
c2 := get(m+1, n+1)
227+
r5 := get(m+1, n+1)
228+
c5 := get(m+1, n+1)
229+
for i := 1; i <= m; i++ {
230+
for j := 1; j <= n; j++ {
231+
x := grid[i-1][j-1]
232+
s2, s5 := 0, 0
233+
for ; x%2 == 0; x /= 2 {
234+
s2++
235+
}
236+
for ; x%5 == 0; x /= 5 {
237+
s5++
238+
}
239+
r2[i][j] = r2[i][j-1] + s2
240+
c2[i][j] = c2[i-1][j] + s2
241+
r5[i][j] = r5[i][j-1] + s5
242+
c5[i][j] = c5[i-1][j] + s5
243+
}
244+
}
245+
for i := 1; i <= m; i++ {
246+
for j := 1; j <= n; j++ {
247+
a := min(r2[i][j]+c2[i-1][j], r5[i][j]+c5[i-1][j])
248+
b := min(r2[i][j]+c2[m][j]-c2[i][j], r5[i][j]+c5[m][j]-c5[i][j])
249+
c := min(r2[i][n]-r2[i][j]+c2[i][j], r5[i][n]-r5[i][j]+c5[i][j])
250+
d := min(r2[i][n]-r2[i][j-1]+c2[m][j]-c2[i][j], r5[i][n]-r5[i][j-1]+c5[m][j]-c5[i][j])
251+
ans = max(ans, max(a, max(b, max(c, d))))
252+
}
253+
}
254+
return
255+
}
256+
257+
func get(m, n int) [][]int {
258+
f := make([][]int, m)
259+
for i := range f {
260+
f[i] = make([]int, n)
261+
}
262+
return f
263+
}
264+
265+
func max(a, b int) int {
266+
if a > b {
267+
return a
268+
}
269+
return b
270+
}
271+
272+
func min(a, b int) int {
273+
if a < b {
274+
return a
275+
}
276+
return b
277+
}
84278
```
85279

86280
### **TypeScript**
87281

88282
```ts
89283
function maxTrailingZeros(grid: number[][]): number {
90-
let m = grid.length,
91-
n = grid[0].length;
92-
let r2 = Array.from({ length: m + 1 }, v => new Array(n + 1).fill(0)),
93-
c2 = Array.from({ length: m + 1 }, v => new Array(n + 1).fill(0)),
94-
r5 = Array.from({ length: m + 1 }, v => new Array(n + 1).fill(0)),
95-
c5 = Array.from({ length: m + 1 }, v => new Array(n + 1).fill(0));
96-
for (let i = 1; i <= m; i++) {
97-
for (let j = 1; j <= n; j++) {
98-
let cur = grid[i - 1][j - 1];
99-
let two = 0,
100-
five = 0;
101-
while (cur % 2 == 0) two++, (cur /= 2);
102-
while (cur % 5 == 0) five++, (cur /= 5);
103-
r2[i][j] = r2[i - 1][j] + two;
104-
c2[i][j] = c2[i][j - 1] + two;
105-
r5[i][j] = r5[i - 1][j] + five;
106-
c5[i][j] = c5[i][j - 1] + five;
284+
const m = grid.length;
285+
const n = grid[0].length;
286+
const r2 = Array.from({ length: m + 1 }, () => new Array(n + 1).fill(0));
287+
const c2 = Array.from({ length: m + 1 }, () => new Array(n + 1).fill(0));
288+
const r5 = Array.from({ length: m + 1 }, () => new Array(n + 1).fill(0));
289+
const c5 = Array.from({ length: m + 1 }, () => new Array(n + 1).fill(0));
290+
for (let i = 1; i <= m; ++i) {
291+
for (let j = 1; j <= n; ++j) {
292+
let x = grid[i - 1][j - 1];
293+
let s2 = 0;
294+
let s5 = 0;
295+
for (; x % 2 == 0; x = Math.floor(x / 2)) {
296+
++s2;
297+
}
298+
for (; x % 5 == 0; x = Math.floor(x / 5)) {
299+
++s5;
300+
}
301+
r2[i][j] = r2[i][j - 1] + s2;
302+
c2[i][j] = c2[i - 1][j] + s2;
303+
r5[i][j] = r5[i][j - 1] + s5;
304+
c5[i][j] = c5[i - 1][j] + s5;
107305
}
108306
}
109307
let ans = 0;
110-
function getMin(i0, j0, i1, j1, i3, j3, i4, j4): number {
111-
// 横向开始、结束,竖向开始、结束
112-
const two = c2[i1][j1] - c2[i0][j0] + r2[i4][j4] - r2[i3][j3];
113-
const five = c5[i1][j1] - c5[i0][j0] + r5[i4][j4] - r5[i3][j3];
114-
return Math.min(two, five);
115-
}
116-
for (let i = 1; i <= m; i++) {
117-
for (let j = 1; j <= n; j++) {
118-
const leftToTop = getMin(i, 0, i, j, 0, j, i - 1, j),
119-
leftToBotton = getMin(i, 0, i, j, i, j, m, j),
120-
rightToTop = getMin(i, j, i, n, 0, j, i, j),
121-
rightToBotton = getMin(i, j, i, n, i - 1, j, m, j);
122-
ans = Math.max(
123-
leftToTop,
124-
leftToBotton,
125-
rightToTop,
126-
rightToBotton,
127-
ans,
308+
for (let i = 1; i <= m; ++i) {
309+
for (let j = 1; j <= n; ++j) {
310+
const a = Math.min(
311+
r2[i][j] + c2[i - 1][j],
312+
r5[i][j] + c5[i - 1][j],
313+
);
314+
const b = Math.min(
315+
r2[i][j] + c2[m][j] - c2[i][j],
316+
r5[i][j] + c5[m][j] - c5[i][j],
317+
);
318+
const c = Math.min(
319+
r2[i][n] - r2[i][j] + c2[i][j],
320+
r5[i][n] - r5[i][j] + c5[i][j],
321+
);
322+
const d = Math.min(
323+
r2[i][n] - r2[i][j - 1] + c2[m][j] - c2[i][j],
324+
r5[i][n] - r5[i][j - 1] + c5[m][j] - c5[i][j],
128325
);
326+
ans = Math.max(ans, a, b, c, d);
129327
}
130328
}
131329
return ans;

0 commit comments

Comments
 (0)