817. Linked List Components

Description:
We are given head, the head node of a linked list containing unique integer values.

We are also given the list G, a subset of the values in the linked list.

Return the number of connected components in G, where two values are connected if they appear consecutively in the linked list.

Analysis:
给一个链表,每个结点中的值都不相同,这些值组成一个集合A,再给定一个集合G,如果G中两个元素在集合A中是连续出现,则这两个元素是相邻,求集合G中这样的序列的个数。

Solution:
解法1:遍历一遍链表,将(value,index)保存在哈希表中,这样加快查找下标的速度,再遍历集合G,判断相邻的两个值的下标,如果index相差1,则认为是相邻,继续判断;
当出现index相差不是1,则序列个数+1

解决2:利用并查集
(1)创建集合,利用哈希表创建,遍历链表,不在G中的元素初始化为-1,在的初始化为该值;
(2)遍历集合G,如果G中相邻的两个元素在集合中值都不是-1,则将这两个元素(集合)join合并,组成一个集合,遍历到结尾;
(3)最后遍历哈希表集合,如果哈希表中的值等于元素本身,则认为是一个集合的父结点,统计出个数返回,相当于只求出每个子集合的根结点即可;

Sol1:

int numComponents(ListNode* head, vector<int>& G) {
        int count = 0;
        ListNode *mov = head;
        unordered_set<int> st;
        for (int i = 0; i < G.size(); i ++)
            st.insert(G[i]);

        bool conti = false;
        while (mov) {
            if (mov && st.find(mov->val) == st.end()) {
                if (conti) {
                    ++ count;
                    conti = false;
                }
                mov = mov->next;
                continue;
            }
            if (mov == NULL)
                break;
            conti = true;
            mov = mov->next;
        }
        if (conti)
            ++ count;
        return count;
    }

Sol2:

int numComponents(ListNode* head, vector<int>& G) {
        unordered_map<int, int> ump;
        ListNode *mov = head;
        while (mov) {
            ump[mov->val] = -1;
            mov = mov->next;
        }
        for (int i = 0; i < G.size(); i ++) {
            ump[G[i]] = G[i];
        }
        ListNode *cur = head;
        int lid = cur->val;
        cur = cur->next;
        while (cur) {
            int rid = cur->val;
            if (ump[lid] != -1 && ump[rid] != -1) {
                join(ump, lid, rid);
            }
            cur = cur->next;
            lid = rid;
        }
        int cnt = 0;
        for (int i = 0; i < ump.size(); i ++) {
            if (ump[i] == i) {
                ++ cnt;
            }
        }
        return cnt;
    }
    int find(unordered_map<int, int> &umap, int val) {
        if (umap[val] == val) {
            return umap[val];
        }
        umap[val] = find(umap, umap[val]);
        return umap[val];
    }
    void join(unordered_map<int, int> &umap, int lid, int rid) {
        int llid = find(umap, lid);
        int rrid = find(umap, rid);
        if (llid == rrid)
            return;
        if (llid < rrid) {
            umap[rrid] = llid;
        } else {
            umap[llid] = rrid;
        }
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值