Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 319de8b

Browse files
committed
🐱(weekly): 第 157 场周赛
1 parent e338de4 commit 319de8b

File tree

1 file changed

+187
-1
lines changed

1 file changed

+187
-1
lines changed

docs/weekly/README.md

Lines changed: 187 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2167,4 +2167,190 @@ func findNumOfValidWords(words []string, puzzles []string) []int {
21672167
}
21682168
```
21692169

2170-
<!-- tabs:end -->
2170+
<!-- tabs:end -->
2171+
2172+
----
2173+
2174+
## 第 157 场周赛
2175+
2176+
[点击前往第 157 场周赛](https://leetcode-cn.com/contest/weekly-contest-157)
2177+
2178+
### 5213. 玩筹码
2179+
2180+
[原题链接](https://leetcode-cn.com/contest/weekly-contest-157/problems/play-with-chips/)
2181+
2182+
#### 暴力破解
2183+
2184+
```python
2185+
class Solution:
2186+
def minCostToMoveChips(self, chips: List[int]) -> int:
2187+
chip_set = set(chips)
2188+
res = float("inf")
2189+
for s in chip_set:
2190+
tmp = 0
2191+
for chip in chips:
2192+
if chip > s:
2193+
if (chip - s) % 2 == 1:
2194+
tmp += 1
2195+
elif chip < s:
2196+
if (s - chip) % 2 == 1:
2197+
tmp += 1
2198+
else:
2199+
pass
2200+
if tmp <= res:
2201+
res = tmp
2202+
return res
2203+
```
2204+
2205+
#### 统计奇偶
2206+
2207+
移动 2 位是无代价的,移动 1 位是有代价的,因此奇数位移动到奇数位或偶数位移动到偶数位是无代价移动,偶数位移动到奇数位或奇数位移动到偶数位需要花费代价 1。所以只要统计奇数位的筹码数和偶数位的筹码数,将少的一方移到多的一方即可。
2208+
2209+
```python
2210+
class Solution:
2211+
def minCostToMoveChips(self, chips: List[int]) -> int:
2212+
odd = 0
2213+
even = 0
2214+
2215+
for chip in chips:
2216+
if chip % 2 == 0:
2217+
even += 1
2218+
else:
2219+
odd += 1
2220+
2221+
return min(odd, even)
2222+
```
2223+
2224+
### 5214. 最长定差子序列
2225+
2226+
[原题链接](https://leetcode-cn.com/contest/weekly-contest-157/problems/longest-arithmetic-subsequence-of-given-difference/)
2227+
2228+
把每一个数**当前位置能构成的最长定差子序列长度**用字典 `dp` 记录下来,遍历 `arr` 时,根据 `difference` 求出在定差子序列中该数的前一个数 `pre = a - difference`,若 `pre` 存在 `dp` 中(已能构成定差子序列),则有 `dp[a] = max(dp[a], dp[pre] + 1)`,否则令 `dp[a] = 1`
2229+
2230+
```python
2231+
class Solution:
2232+
def longestSubsequence(self, arr: List[int], difference: int) -> int:
2233+
dp = dict()
2234+
for a in arr:
2235+
pre = a - difference
2236+
if pre in dp:
2237+
dp[a] = max(dp.get(a, 0), dp[pre] + 1)
2238+
else:
2239+
dp[a] = 1
2240+
return max([x for _, x in dp.items()])
2241+
```
2242+
2243+
### 5215. 黄金矿工
2244+
2245+
[原题链接](https://leetcode-cn.com/contest/weekly-contest-157/problems/path-with-maximum-gold/)
2246+
2247+
DFS 暴力挖矿。对挖过的格子进行标记,走到一个格子后,判断该格子四个方向的格子是否满足要求:
2248+
2249+
1. 不超过 `grid` 边界
2250+
2. 黄金数目不为 `0`
2251+
3. 没有被挖过
2252+
2253+
如果满足上述条件就继续 DFS 挖下去。
2254+
2255+
伪代码大概长这样:
2256+
2257+
```
2258+
dfs(v) // v 可以是 grid 的一个坑
2259+
在 v 上打访问标记
2260+
for u in v 的四个相邻坑位
2261+
if (u 没有越界) and (u 有黄金) and (u 没有被挖过) then
2262+
dfs(i)
2263+
```
2264+
2265+
具体实现:
2266+
2267+
```python
2268+
class Solution:
2269+
2270+
ans = 0
2271+
2272+
def getMaximumGold(self, grid: List[List[int]]) -> int:
2273+
2274+
n = len(grid)
2275+
m = len(grid[0])
2276+
2277+
"""
2278+
获取方向
2279+
"""
2280+
def get_directions(i, j, mark):
2281+
directions = []
2282+
if i - 1 >= 0 and grid[i - 1][j] != 0 and (not mark[i - 1][j]):
2283+
directions.append([i - 1, j])
2284+
if i + 1 < n and grid[i + 1][j] != 0 and (not mark[i + 1][j]):
2285+
directions.append([i + 1, j])
2286+
if j - 1 >= 0 and grid[i][j - 1] != 0 and (not mark[i][j - 1]):
2287+
directions.append([i, j - 1])
2288+
if j + 1 < m and grid[i][j + 1] != 0 and (not mark[i][j + 1]):
2289+
directions.append([i, j + 1])
2290+
2291+
return directions
2292+
2293+
"""
2294+
DFS
2295+
"""
2296+
def dfs(i, j, mark, count):
2297+
# 打上访问标记
2298+
mark[i][j] = True
2299+
# 获得可走方向
2300+
directions = get_directions(i, j, mark)
2301+
# 无路可走时返回
2302+
if len(directions) == 0:
2303+
self.ans = max(self.ans, count)
2304+
return
2305+
# 遍历方向
2306+
for direction in directions:
2307+
dfs(direction[0], direction[1], [x[:] for x in mark], count + grid[direction[0]][direction[1]]) # dfs
2308+
2309+
for i in range(n):
2310+
for j in range(m):
2311+
# 任意一个有黄金的单元格出发
2312+
if grid[i][j] != 0:
2313+
mark = [[False for _ in range(m)] for _ in range(n)]
2314+
dfs(i, j, mark, grid[i][j])
2315+
2316+
return self.ans
2317+
```
2318+
2319+
### 5216. 统计元音字母序列的数目
2320+
2321+
[原题链接](https://leetcode-cn.com/contest/weekly-contest-157/problems/count-vowels-permutation/)
2322+
2323+
长度为 `x` 的字符串是由**长度为 `x - 1` 的合法字符串**,根据其最后一个字母,追加一个符合规则的字母构成的。
2324+
2325+
因此,如果我们要求长度为 `x` 的字符串个数,只需要知道长度为 `x - 1` 的字符串中所有字符串最后一个字母的情况,从 `n = 1` 开始一直推算到 `n = x`
2326+
2327+
```python
2328+
class Solution:
2329+
def countVowelPermutation(self, n: int) -> int:
2330+
2331+
if n == 1:
2332+
return 5
2333+
2334+
map_dict = {"a": ["e"], "e": ["a", "i"], "i": ["a", "e", "o", "u"], "o": ["i", "u"], "u": ["a"]}
2335+
index = {"a": 0, "e": 1, "i": 2, "o": 3, "u": 4}
2336+
c = {0: "a", 1: "e", 2: "i", 3: "o", 4: "u"}
2337+
2338+
# aeiou 对应的个数
2339+
pre = [1, 1, 1, 1, 1]
2340+
2341+
res = 0
2342+
2343+
for i in range(2, n + 1):
2344+
cur = [0 for _ in range(5)]
2345+
for j in range(len(pre)):
2346+
cur_c = c[j] # 当前字母
2347+
cur_c_count = pre[j] # 当前字母数量
2348+
for map_c in map_dict[cur_c]: # 遍历可以跟随的字母
2349+
map_c_index = index[map_c]
2350+
cur[map_c_index] += cur_c_count
2351+
pre = cur
2352+
2353+
res = sum(cur)
2354+
2355+
return res % (10**9 + 7)
2356+
```

0 commit comments

Comments
 (0)