差分|递归
lc889
class Solution {
public:
TreeNode* constructFromPrePost(vector<int>& preorder, vector<int>& postorder) {
reverse(postorder.begin(),postorder.end()); //翻转后,后序相当于:根右左
int n = preorder.size();
unordered_map<int,int> pre_id,pos_id;
for(int i = 0;i < n;i++){
pre_id[preorder[i]] = i;
pos_id[postorder[i]] = i;
}
//以前序遍历为主进行分治,区间内第一个点(值x)为根,后面的点为直系左孩子l,下标lid(这里只是一种情况,不具唯一性)
//获取x在翻转后序中的下标lid,后面(lid+1)就是x的直系右孩子,设为r
//获取r在先序中的下标rid,即可划分区间分治,这里是闭区间
auto build = [&](this auto&& build,int left,int right)->TreeNode*{
if(left > right) return nullptr;
int x = preorder[left];
if(left == right) return new TreeNode(x); //叶子节点
int lid = pos_id[x];
int r,rid = right + 1; //如果后序中,l后面没有元素,说明x没有右孩子
if(lid < n-1){
r = postorder[lid + 1];
rid = pre_id[r];
}
return new TreeNode(x,build(left+1,rid-1),build(rid,right));
};
return build(0,n-1);
}
};
lc1110
后序检查
class Solution {
public:
vector<TreeNode*> delNodes(TreeNode* root, vector<int>& to_delete) {
unordered_set<int>ma;
for(int p:to_delete) ma.insert(p);
vector<TreeNode*>res;
function<TreeNode*(TreeNode*)>dfs=[&](TreeNode* root)->TreeNode*
{
if(!root) return nullptr;
root->left=dfs(root->left);
root->right=dfs(root->right);
if(!ma.count(root->val))
return root;
//走不到后面了
if(root->left) res.push_back(root->left);
if(root->right) res.push_back(root->right);
return nullptr;
};
if(dfs(root)) res.push_back(root);
return res;
}
};
lc849
一次线性遍历-模拟选择
max(左右端点,中间memo mx_d)
class Solution {
public:
int maxDistToClosest(vector<int>& seats) {
int first = -1, last = -1;
int d = 0, n = seats.size();
for (int i = 0; i < n; ++i) {
if (seats[i] == 1) {
if (last != -1) {
d = max(d, i - last);
}
if (first == -1) {
first = i;
}
last = i;
}
}
return max({d / 2, max(first, n - last - 1)});
}
};
lc1249
计数模拟左右括号的消耗
不用固化的用栈
class Solution {
public:
string minRemoveToMakeValid(string s) {
int left = 0;
int right = count(begin(s), end(s), ')');
string ans = "";
for (auto& c : s) {
if (c == '(') {
if (right > 0) {
ans += c;
left++;
right--;
}
} else if (c == ')') {
if (left > 0) {
ans += c;
left--;
} else {
right--;
}
} else {
ans += c;
}
}
return ans;
}
};
lc3346
差分统计每个数±k区间的覆盖次数
结合原数计数和操作次数
ans = max(ans, min(sum_d, cnt[x] + numOperations));
class Solution {
public:
int maxFrequency(vector<int>& nums, int k, int numOperations) {
unordered_map<int, int> cnt;
map<int, int> diff;
for (int x : nums) {
cnt[x]++;
diff[x]; // 把 x 插入 diff,以保证下面能遍历到 x
diff[x - k]++; // 把 [x-k, x+k] 中的每个整数的出现次数都加一
diff[x + k + 1]--;
}
int ans = 0, sum_d = 0;
for (auto& [x, d] : diff) {
sum_d += d;
ans = max(ans, min(sum_d, cnt[x] + numOperations));
}
return ans;
}
};