leetcode 单 :
第一题https://leetcode.cn/problems/number-of-arithmetic-triplets/数据范围不大,可以直接枚举
class Solution {
public:
int arithmeticTriplets(vector<int>& nums, int diff) {
int count = 0;
for(int i = 0; i < nums.size(); i ++){
for(int j = 0; j < nums.size(); j ++){
for(int k = 0; k < nums.size(); k ++){
if(nums[i] + diff == nums[j] && nums[j] + diff == nums[k]) count ++;
}
}
}
return count;
}
};
当然我们可以用哈希表来优化,unordered_map 来存储出现的数,在利用 count 来检阅其中是否存在 nums[i] - diff 与 nums[i] + diff 即可
class Solution {
public:
int arithmeticTriplets(vector<int>& nums, int diff) {
int n = nums.size();
unordered_set<int> st;
for (int x : nums) st.insert(x);
int ans = 0;
for (int i = 0; i < n; i++) if (st.count(nums[i] - diff) > 0 && st.count(nums[i] + diff) > 0) ans++;
return ans;
}
};
第二题https://leetcode.cn/problems/reachable-nodes-with-restrictions/bfs() 来解决,用 unordered_map 来模拟邻接链表,同时利用 set 的 count 函数查找
class Solution {
public:
int reachableNodes(int n, vector<vector<int>>& edges, vector<int>& rest) {
unordered_map<int, vector<int>> ans;
unordered_set<int> kp(rest.begin(), rest.end());
for(int i = 0; i < edges.size(); i ++){
ans[edges[i][0]].push_back(edges[i][1]);
ans[edges[i][1]].push_back(edges[i][0]);
}
queue<int> res;
res.push(0);
int count = 1;
while(!res.empty()){
int t = res.front();
res.pop();
for(auto c : ans[t]){
if(kp.count(c)) continue;
count ++;
res.push(c);
}
kp.insert(t);
}
return count;
}
};
第三题https://leetcode.cn/problems/check-if-there-is-a-valid-partition-for-the-array/递推,设dp[j]表示 nums[j+1] 即从 0 到 j 的连续子数组能否进行划分。由于每次可以切出 2 个或 3 个,因此dp[j]只能由 dp[j-2] 或 dp[j-3] 转移而来。
class Solution {
public:
bool validPartition(vector<int>& nums) {
int n = nums.size();
vector<bool> ans(n + 1);
ans[0] = true;
for(int i = 1; i <= n; i ++){
if(i >= 2){
if(nums[i - 2] == nums[i - 1]) ans[i] = ans[i] || ans[i - 2];
}
if(i >= 3){
if(nums[i - 3] == nums[i - 2] && nums[i - 2] == nums[i - 1]){
ans[i] = ans[i] || ans[i - 3];
}
if(nums[i - 3] + 1 == nums[i - 2] && nums[i - 2] + 1 == nums[i - 1]){
ans[i] = ans[i] || ans[i - 3];
}
}
}
return ans[n];
}
};
第四题https://leetcode.cn/problems/longest-ideal-subsequence/
设 f(c) 表示从头开始遍历过程中,以字符 c 结尾的最长理想字符串的长度。
初始时,f(c)=0。
转移时,对于当前位置 c:=s(i),找到下标 [c−k,c+k] 内的 f 的最大值 m,转移 f(c)=m+1。
最终答案为 max(f(c))
class Solution {
public:
int longestIdealString(string s, int k) {
int n = s.size();
vector<int> ans(26);
for(int i = 0; i < n; i ++){
int t = s[i] - 'a';
int zhon = 0;
for(int j = max(0, t - k); j <= min(25, t + k); j ++){
zhon = max(zhon, ans[j]);
}
ans[t] = zhon + 1;
}
int res = 0;
for(int i = 0; i < 26; i ++) res = max(res, ans[i]);
return res;
}
};
leetcode 双 :
第一题https://leetcode.cn/problems/merge-similar-items/用map存储合并数据,因其有序,直接拷贝至vector即可
class Solution {
public:
vector<vector<int>> mergeSimilarItems(vector<vector<int>>& items1, vector<vector<int>>& items2) {
map<int, int> ans;
for(auto c : items1) ans[c[0]] += c[1];
for(auto c : items2) ans[c[0]] += c[1];
vector<vector<int>> res;
for(auto it = ans.begin(); it != ans.end(); it ++){
res.push_back({it -> first, it -> second});
}
return res;
}
};
第二题https://leetcode.cn/problems/count-number-of-bad-pairs/将题目中的公式变形,可以转为求 nums[i] - i != nums[j] - j 的数对数量。
使用哈希表存储,再通过总数对数量,减去哈希表中相同数字组成数对的数量。
class Solution {
public:
long long countBadPairs(vector<int>& nums) {
long long sum = 0, n = nums.size();
map<int, int>mp;
for(int i = 0; i < n; i++) mp[i - nums[i]]++;
for(map<int, int>::iterator it = mp.begin(); it != mp.end(); it++) {
sum += (long long)it->second * (long long)(it->second - 1) / 2;
}
return n * (n - 1) / 2 - sum;
}
};
第三题https://leetcode.cn/problems/task-scheduler-ii/按顺序遍历任务数组,使用变量 day 记录天数,即完成当前任务后的下一天。天数从 0 开始。
使用哈希表记录上一次完成同种任务的 day。
遍历时,如果发现上一次完成同种任务时的间隔天数不足 space,则重置 day:=last(t)+space+1。
class Solution {
public:
long long taskSchedulerII(vector<int>& tasks, int space) {
unordered_map<int, long long> ans;
long long res = 0;
for(auto c : tasks){
if(ans.find(c) != ans.end() && res <= space + ans[c]){
res = space + ans[c] + 1;
}
ans[c] = res;
res ++;
}
return res;
}
};
第四题https://leetcode.cn/problems/minimum-replacements-to-sort-the-array/假设b以及b后面的序列都已经处理好了 满足非递减,那么a需要被分解
a = a1+a2+…+ak;且a1<=a2<=…<=ak
那么我们需要a1最大 a1最大肯定是平均分 a1max = a/k
本题需要k尽量小 巧合的是 当k最小,a1max才最大
于是我们每次可以找到最小的k 从而计算出a1max
最小的k肯定是a/b上取整
class Solution {
public:
long long minimumReplacement(vector<int>& nums) {
long long res = 0;
for(int i = nums.size() - 2, b = nums.back();i >= 0; i --){
int a = nums[i];
int k = (a + b - 1) / b;
res += k - 1;
b = a / k;
}
return res;
}
};
acwing :
第一题https://www.acwing.com/problem/content/4506/枚举即可
#include <bits/stdc++.h>
using namespace std;
int main(){
int a, b, n;
cin >> a >> b >> n;
int count = 0;
for(int i = 0; i <= a; i ++){
for(int j = 0; j <= b; j ++){
if(i + j == n){
count ++;
}
}
}
cout << count << endl;
return 0;
}
第二题https://www.acwing.com/problem/content/4507/用栈简单模拟即可
#include <bits/stdc++.h>
using namespace std;
int main(){
string a;
cin >> a;
stack<char> ans;
int count = 0;
for(int i = 0; i < a.size(); i ++){
if(!ans.empty() && a[i] == ans.top()){
ans.pop();
count ++;
}
else ans.push(a[i]);
}
if(count & 1) cout << "Yes" << endl;
else cout << "No" << endl;
return 0;
}