打了三场,算是发现力扣的一点小规律了,上次考两个搜索,这次考两个线性dp,奈何没把线性dp学明白。

暴力做法:三重循环可做
哈希做法:将nums放入set,查找num + diff和num - diff是否都在set里。
class Solution:
def arithmeticTriplets(self, nums: List[int], diff: int) -> int:
# 用哈希表做映射,判断nums[j] - diff 和 nums[j] + diff 是否在哈希表里
s = set(nums)
ans = 0
for num in nums:
if num - diff in s and num + diff in s:
ans += 1
return ans
# return sum(num - diff in s and num + diff in s for num in nums)


建一个无向图,然后用bfs来判断有多少可达到点
class Solution {
public:
static const int N = 1e5 + 7;
int vis[N];
vector<int> tree[N];
int reachableNodes(int n, vector<vector<int>>& edges, vector<int>& restricted) {
for (auto rs: restricted) {
vis[rs] = 1;
}
// 建图
for (int i = 0; i < edges.size(); ++i) {
tree[edges[i][0]].push_back(edges[i][1]);
tree[edges[i][1]].push_back(edges[i][0]);
}
queue<int> q;
q.push(0);
int ans = 0;
while(!q.empty()) {
int cur = q.front(); q.pop();
ans++;
vis[cur] = 1;
for (int i = 0; i < tree[cur].size(); ++i) {
if (vis[tree[cur][i]] == 0) {
q.push(tree[cur][i]);
}
}
}
return ans;
}
};

这题比赛时,完全看不出来是dp,dp是做少了,做题时一点思路没有,又止步于第三题了。
本题巧妙运用了python中数组-1下标的思想,来作为边界条件
class Solution:
def validPartition(self, nums: List[int]) -> bool:
length = len(nums)
dp = [False] * length + [True] # 利用dp[-1]作为边界条件,其实dp[-1]为
for i in range(length):
# 当nums[i, i + 1]为对子时
if i > 0 and dp[i - 2] and nums[i] == nums[i - 1]:
dp[i] = True
# 当nums[i, i - 1, i - 2]为炸时
if i > 1 and dp[i - 3] and nums[i] == nums[i - 1] == nums[i - 1] == nums[i - 2]:
dp[i] = True
# 当nums[i, i - 1, i - 2]为顺子时
if i > 1 and dp[i - 3] and nums[i] == nums[i - 1] + 1 == nums[i - 2] + 2:
dp[i] = True
return dp[-2]

利用dp[i]表示以字符i结尾的最长理想字符串长度。
于是转移方程为dp[i] = max(dp[left : right]) + 1, left是i - c,right是i + c,并且注意不能越界。
class Solution:
def longestIdealString(self, s: str, k: int) -> int:
dp = [0] * 26
for c in s:
i = ord(c) - ord('a')
left = max(0, i - k)
right = min(26, i + k + 1)
dp[i] = max(dp[left : right]) + 1
return max(dp)