Leetcode 310. Minimun Height Trees使用set快速删除元素

2 篇文章 0 订阅
2 篇文章 0 订阅

set是C++STL中的一种集合类型,可以实现对元素的查找、添加、删除、修改。Set是一个集合,其中不能包含重复元素。删除set中的指定元素是一种很常见的操作,使用迭代器即可。例如:

void delete_set(set<int> &s,int m){
    set<int>::iterator it;
    for(it=s.begin();it!=s.end();){
        if( *it == m ){
            s.erase(it);
            break;
        }
    }
}

但是,这样的方式需要遍历整个集合,时间复杂度为O(n)。事实上,set的erase函数可以直接传入想要删除的元素作为参数,在O(1)时间内完成删除操作。例如:

set<int> s;
s.insert(5);
cout << s.size() << endl;//打印出1
s.erase(5);
cout << s.size() << endl;//打印出0

有关set的这个用法是本人在刷leetcode上的题310. Minimum Height Trees时搜到的。这里使用set保存图中每一个顶点的邻接点,在执行类拓扑排序的过程中可以很方便的实现删除顶点操作。之前使用vector一直报时间超时,换成set后直接通过。本题代码如下:

vector<int> findMinHeightTrees(int n, vector<pair<int, int>>& edges) {
        map<int,set<int>> graph;
        queue<int> q;
        vector<int> result;
        int *degree = new int[n];
        for(int i=0;i < n; i++)
            degree[i]=0;
        if( n == 1){
            result.push_back(0);
            return result;
        }
        int rest=n;
        for(int i=0;i < edges.size(); i++){
            degree[edges[i].first]++;
            degree[edges[i].second]++;
            if( graph.find(edges[i].first) == graph.end()){
                graph[edges[i].first] = set<int>();
            }
            if( graph.find(edges[i].second) == graph.end()){
                graph[edges[i].second] = set<int>(); 
            }
            graph[edges[i].first].insert(edges[i].second);
            graph[edges[i].second].insert(edges[i].first);
        }
        for(int i=0;i < n; i++){
            if( degree[i] == 1){
                q.push(i);
                rest--;
            }
        }
        while( rest > 0 ){
            queue<int> c;
            while( !q.empty() ){
                int p=q.front();
                q.pop();
                auto it = graph[p].begin();
                degree[*it]--;
                graph[*it].erase(p);
                if( degree[*it] == 1){
                    c.push(*it);
                    rest--;
                }
            }
            q=c;
        }
        while( !q.empty()){
            result.push_back(q.front());
            q.pop();
        }
        return result;
    }

这道题的思路和拓扑排序类似,依次处理度数为1的顶点并删除之,修改与被删除顶点邻接的顶点度数。反复执行以上过程直至剩余的顶点数量不超过2即所要获得的解。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值