[参考讲解]:灵茶山艾府大佬
LeetCode 6136. 算术三元组的数目
https://leetcode.cn/problems/number-of-arithmetic-triplets/
我这道题用暴力法过的,感觉很傻😂
暴力法(C++)
class Solution {
public:
int arithmeticTriplets(vector<int>& nums, int diff) {
int n = nums.size();
int ans = 0;
for (int i = 0; i < n - 2; i++) {
for (int j = i + 1; j < n - 1; j++) {
for (int k = j + 1; k < n; k++) {
if (nums[k] - nums[j] == diff && nums[j] - nums[i] == diff) {
ans++;
}
}
}
}
return ans;
}
};
哈希表(Python)
class Solution:
def arithmeticTriplets(self, nums: List[int], diff: int) -> int:
hashMap = defaultdict(int)
ans = 0
for x in nums:
hashMap[x] = 1
for x in nums:
if hashMap[x + diff] and hashMap[x + 2 * diff]:
ans += 1
return ans
三指针(Python)
class Solution:
def arithmeticTriplets(self, nums: List[int], diff: int) -> int:
ans = 0
n = len(nums)
for i in range(n - 2):
j = i + 1
while j < n - 1 and nums[j] - nums[i] < diff:
j += 1
k = j + 1
while k < n and nums[k] - nums[j] < diff:
k += 1
if k < n and nums[k] - nums[j] == diff and nums[j] - nums[i] == diff:
ans += 1
return ans
LeetCode 6139. 受限条件下可到达节点的数目
https://leetcode.cn/problems/reachable-nodes-with-restrictions/
深搜和广搜都是先建立图形,然后遍历,深搜用递归,广搜用队列。
从结果上看广搜表现效果更好一点。
DFS(Python)
class Solution:
def reachableNodes(self, n: int, edges: List[List[int]], restricted: List[int]) -> int:
# 先根据给出的 edges 生成图
graph = [[] for _ in range(n)]
for x, y in edges:
graph[x].append(y)
graph[y].append(x)
hashMap = {} # 存放已经遍历过的节点
restricted = set(restricted) # 转成 set in 操作的时间复杂度为 O(1)
def dfs(node):
if node in restricted or node in hashMap:
return
hashMap[node] = True
for nd in graph[node]:
dfs(nd)
dfs(0)
return len(hashMap)
BFS(Python)
class Solution:
def reachableNodes(self, n: int, edges: List[List[int]], restricted: List[int]) -> int:
# 默认列表
graph = defaultdict(list)
for a, b in edges:
graph[a].append(b)
graph[b].append(a)
# 转成 SET in 操作更快
restricted = set(restricted)
ans = 0
que = deque()
que.append(0)
# 访问过的数据装入 set
visited = set()
while que:
u = que.popleft()
visited.add(u)
ans += 1
for v in graph[u]:
if v not in visited and v not in restricted:
que.append(v)
return ans
LeetCode 6137. 检查数组是否存在有效划分
https://leetcode.cn/problems/check-if-there-is-a-valid-partition-for-the-array/
划分子问题一般都是动态规划。
动态规划(Python)
定义 dp[length]
表示 nums[0] ~ nums[length-1]
是否满足有效划分。
定义初始状态:dp[0] = True
,表示空数组为满足划分要求。
有三种情况, dp[i+1]
变为 True
:
dp[i-1] && nums[i] == nums[i-1]
i > 1 && dp[i-2] && nums[i] == nums[i-1] == nums[i-2]
i > 1 && dp[i-2] && nums[i] == nums[i-1] + 1 == nums[i-2] + 2
class Solution:
def validPartition(self, nums: List[int]) -> bool:
n = len(nums)
# dp[length] 表示 nums[0] ~ nums[length-1] 能否满足有效划分
dp = [False] * (n + 1)
# 初始状态
dp[0] = True
for i in range(1, n):
x = nums[i]
if dp[i-1] and x == nums[i-1]:
dp[i + 1] = True
if i > 1:
if dp[i-2] and x == nums[i-1] == nums[i-2]:
dp[i + 1] = True
if dp[i-2] and x == nums[i-1] + 1 == nums[i-2] + 2:
dp[i + 1] = True
return dp[-1]
简化一下:
class Solution:
def validPartition(self, nums: List[int]) -> bool:
n = len(nums)
# dp[length] 表示 nums[0] ~ nums[length-1] 能否满足有效划分
dp = [False] * (n + 1)
# 初始状态
dp[0] = True
for i in range(1, n):
x = nums[i]
if (dp[i-1] and x == nums[i-1]) or (i > 1 and (dp[i-2] and x == nums[i-1] == nums[i-2] or dp[i-2] and x == nums[i-1] + 1 == nums[i-2] + 2)):
dp[i + 1] = True
return dp[-1]
LeetCode 6138. 最长理想子序列
https://leetcode.cn/problems/longest-ideal-subsequence/
哈希表(Python)
class Solution:
def longestIdealString(self, s: str, k: int) -> int:
# 存储以每个字符为结尾时,最大的理想子序列长度
hashMap = [0] * 26
a = ord('a')
for c in s:
c = ord(c)
# 从上下不超过 k 个位置的字符找一个最大的加入理想子序列
hashMap[c] = max(hashMap[max(c - k, 0) : c + k + 1]) + 1
return max(hashMap)