lcr155
中序遍历二叉搜索树,用++前驱指针串成双向链表++,再把首尾节点相连形成循环链表,返回最小节点
class Solution
{
public:
Node* treeToDoublyList(Node* root)
{
if (!root) return nullptr;
Node* ret = nullptr;
Node* pre = nullptr;
// 记录中序遍历的前一个节点
int mn=INT_MAX;
auto dfs=\&(this auto&& dfs,Node* node)
{
if (!node) return;
dfs(node->left); // 中序遍历先左子树
if(node->val<mn) {
mn=node->val;
ret=node;
}
// 构建双向链表
node->left = pre;
if (pre) pre->right = node;
pre = node;
dfs(node->right);
};
dfs(root);
// 构建循环链表(首尾相连)
pre->right = ret;
ret->left = pre;
return ret;
}
};
lc3108
在n个节点的带权无向图中,对每个查询的起点 s_i 和终点 t_i ,++求两点间旅途的边权按位与的最小值++(无旅途则返回-1,旅途可重复走边/节点)
dfs
DFS遍历图划分连通块,++计算每个连通块内所有边权的按位与值,查询两点是否连通并返回对应结果++(连通返回按位与值,不连通返回-1)
class Solution {
public:
vector<int> minimumCost(int n, vector<vector<int>>& edges, vector<vector<int>>& query) {
vector<vector<pair<int,int>>> g(n);
for(auto& v:edges)
{
gv\[0].push_back({v1,v2});
gv\[1].push_back({v0,v2});
}
vector<int> cc_and;
vector<int> ids(n,-1);
auto dfs=\&(auto&& dfs,int x)->int
{
idsx=cc_and.size();
int and_=-1;
for(auto& nex,val:gx)
{
and_&=val;
if(idsnex==-1)
{
and_&=dfs(dfs,nex);
}
}
return and_;
};
for(int i=0;i<n;i++)
{
if(idsi==-1)
cc_and.push_back(dfs(dfs,i));
}
vector<int> ans;
for(auto& q:query)
{
++if(q0==q1) ans.push_back(0);++
else
{
ans.push_back(idsq\[0]!=idsq\[1]?-1:cc_andids\[q\[0]]);
}
}
return ans;
}
};
++并查集合并图中节点,维护连通块内所有边权的按位与值++
查询两点连通性并返回对应连通块的按位与值(不连通则返回-1)
class Solution {
public:
vector<int> fa;
vector<int> and_;
int find(int x)
{
if(fax!=x)
{
fax=find(fax);
}
return fax;
}
vector<int> minimumCost(int n, vector<vector<int>>& edges, vector<vector<int>>& query) {
for(int i=0;i<n;i++)
{
fa.push_back(i);
and_.push_back(-1);
}
for(auto& v:edges)
{
int fx=find(v0);
int fy=find(v1);
and_fy&=v2;
if(fx!=fy)
{
and_fy&=and_fx;
fafx=fy;
}
}
vector<int> ans;
for(auto& q:query)
{
++if(q0==q1) ans.push_back(0);++
else
{
ans.push_back(find(q0)==find(q1)?and_find(q\[0)]:-1);
}
}
return ans;
}
};