Data structure: initialization, search and merge operations of union lookup, pointing to several sample questions of offer: circle of friends, similar strings, redundant edges and longest continuous sequence

definition

A union search set is a tree-shaped data structure used to represent the merging and query of some disjoint sets. The node of each tree points to its parent node, and the root node of the tree points to itself;

initialization:

//单独形成集合,每个节点的祖先为自己
int fa[size];
for(int i=0;i<size;i++)
	fa[i]=i;

Find:

int findfather(int fa[], int x)
{
    
    
	if(fa[x]!=x)     //如果自己的祖先不是自己,说明不是集合的祖先
		fa[x]=findfather(fa,fa[x]);  //查找集合的祖先,并进行压缩
	return fa[x];
}

merge:

bool unionn(int fa[],int i, int j)
    {
    
    
        int fa_i=findfa(fa,i);
        int fa_j=findfa(fa,j);
        if(fa_i!=fa_j)	
        {
    
    
            fa[fa_i]=fa_j;	//若两个节点祖先不同,不在同一个集合;则将其合并,其中一个祖先设为另一个的祖先,
            return true;     //刚建立集合,返回true
        }
        return false;   //之前就存在集合,返回false
    }

a few sample questions

Sword Finger offer II 116 Moments

def findfather(fa,i):
    if fa[i]!=i:
        fa[i]=findfather(fa,fa[i])
    return fa[i]
def union(fa,i,j):
    fa_i=findfather(fa,i)
    fa_j=findfather(fa,j)
    if fa_i!=fa_j:
        fa[i]=fa_j
        return True
    return False



if __name__=='__main__':
    n=int(input())
    M=[]
    for i in range(n):
        m=[int(j) for j in input().split(',')]
        M.append(m)

    fa=[-1]*n
    for i in range(n):
        fa[i]=i
    count=n
    for i in range(n):
        for j in range(i+1,n):
            if M[i][j]==1 and union(fa, i, j):
                count-=1
    print(count)

Tencent's 2021 School Recruitment Moments

#include<iostream>
using namespace std;

int findfa(int fa[],int x)
{
    
    
    if(fa[x]!=x)
        fa[x]=findfa(fa,fa[x]);
    return fa[x];
}
void unionn(int fa[],int x, int y)
{
    
    
    int fa_x=findfa(fa,x);
    int fa_y=findfa(fa,y);
    if(fa_x!=fa_y)
        fa[fa_x]=fa_y;

}

int main()
{
    
    
    int T;
    cin>>T;
    while(T--)
    {
    
    
        int fa[100001];
        int n;
        cin>>n;
        for(int i=0;i<100001;i++)
            fa[i]=i;
        while(n--)
        {
    
    
            int x,y;
            cin>>x>>y;
            unionn(fa,x,y);
        }
        vector<int> nums(100001);
        int max_len=0;
        for(int i=0;i<100001;i++)
        {
    
    
            int k=findfa(fa,i);
            nums[k]++;
            max_len=max(max_len,nums[k]);
        }
        cout<<max_len<<endl;
    }
    return 0;
}

Sword finger offer II 117 Similar strings

class Solution {
    
    
public:
    // 通过统计不同字符串的个数,判断是否相似
    bool similarity(string s1, string s2)
    {
    
    
        
        int diff=0;
        for(int i=0;i<s1.length();i++)
        {
    
    
            if(s1[i]!=s2[i])
                diff++;
        }
        if(diff<=2)
            return true;
        else
            return false;
    }
    //查找
    int findfateher(int fa[],int i)
    {
    
    
        if(fa[i]!=i)
            fa[i]=findfateher(fa,fa[i]);
        return fa[i];
    }
    //合并
    bool unionn(int fa[], int i, int j)
    {
    
    
        int fa_i=findfateher(fa,i);
        int fa_j=findfateher(fa,j);
        if(fa_i!=fa_j)
        {
    
    
            fa[fa_i]=fa_j;
            return true;
        }    
        return false;

    }
    int numSimilarGroups(vector<string>& strs) {
    
    
        int n=strs.size();
        int fa[n];
        for(int i=0;i<n;i++)
        {
    
    
            fa[i]=i;
        }
        //初始化,每个字符串都是独立的,所以存在n个字符组
        int nums=n;
        for(int i=0;i<n;i++)
        {
    
    
            for(int j=i+1;j<n;j++)
            {
    
       
                //判断两个字符串是否相似,并且之前是否已经联通,字符组数量减一
                if(similarity(strs[i],strs[j])&&unionn(fa,i,j))
                {
    
    
                    nums--;
                }
            }
        }
        return nums;
    }
};

Sword finger offer II 118 extra edge

class Solution {
    
    
public:
    // 查找
    int findfa(int fa[], int i)
    {
    
    
        if(fa[i]!=i)
            fa[i]=findfa(fa,fa[i]);
        return fa[i];
    }
    // 合并
    bool unionn(int fa[],int i, int j)
    {
    
    
        int fa_i=findfa(fa,i);
        int fa_j=findfa(fa,j);
        if(fa_i!=fa_j)
        {
    
    
            fa[fa_i]=fa_j;
            return true;     //若之前不存在连接,则建立连接,返回true
        }
        return false;   //之前存在连接,返回false
    }
    vector<int> findRedundantConnection(vector<vector<int>>& edges) {
    
    
        int n=edges.size();
        int maxleaf=0;
        //查找最大节点的值
        for(int i=0;i<n;i++)
        {
    
    
            maxleaf=max(maxleaf,edges[i][0]);
            maxleaf=max(maxleaf,edges[i][1]);
        }
        int fa[maxleaf+1];  //此处记的加1,因为从1开始到n;
        for(int i=0;i<maxleaf+1;i++)
        {
    
    
            fa[i]=i;
        }
        int i;
        for(auto edge:edges)
        {
    
    
            if(!unionn(fa,edge[0],edge[1]))   //判断是否形成环
               return edge;
        }
        return  vector<int> {
    
    };
    }
};

Sword finger offer II 119 longest continuous sequence

class Solution {
    
    
public:
    int findfa(unordered_map<int,int>& fa, int i)
    {
    
    
        if(fa[i]!=i)
            fa[i]=findfa(fa,fa[i]);
        return fa[i];
    }
    void unionn(unordered_map<int,int>& fa, unordered_map<int,int>& count,int i, int j)
    {
    
    
        int fa_i=findfa(fa,i);
        int fa_j=findfa(fa,j);
        if(fa_i!=fa_j)
        {
    
    
            fa[fa_i]=fa_j;
            count[fa_j]=count[fa_j]+count[fa_i];
        }
    }
    int longestConsecutive(vector<int>& nums) {
    
    
        unordered_map<int,int> fa;
        unordered_map<int,int> count;
        set<int> all;
        for(int i=0;i<nums.size();i++)
        {
    
    
            fa[nums[i]]=nums[i];
            count[nums[i]]=1;
            all.insert(nums[i]);
        }
        for(int i=0;i<nums.size();i++)
        {
    
    
            if(all.count(nums[i]-1)==1)
            {
    
    
                unionn(fa,count,nums[i],nums[i]-1);
            }
            if(all.count(nums[i]+1)==1)
            {
    
    
                unionn(fa,count,nums[i],nums[i]+1);
            }
        }
        int len=0;
        for(int i=0;i<nums.size();i++)
        {
    
    
            len=max(len,count[nums[i]]);
        }
        return len;
    }
};

Guess you like

Origin blog.csdn.net/weixin_42213421/article/details/124293811