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.

Example 1:

Input:
head: 0->1->2->3
G = [0, 1, 3]
Output: 2
Explanation:
0 and 1 are connected, so [0, 1] and [3] are the two connected components.

Example 2:

Input:
head: 0->1->2->3->4
G = [0, 3, 1, 4]
Output: 2
Explanation:
0 and 1 are connected, 3 and 4 are connected, so [0, 1] and [3, 4] are the two connected components.

Note:

  • If N is the length of the linked list given by head1 <= N <= 10000.
  • The value of each node in the linked list will be in the range [0, N - 1].
  • 1 <= G.length <= 10000.
  • G is a subset of all values in the linked list.

这道题给了我们一个链表,又给了我们一个结点值数组,里面不一定包括了链表中所有的结点值。让我们返回结点值数组中有多少个相连的组件,因为缺失的结点值会将原链表断开,实际上就是让我们求有多少个相连的子链表,题目中给的例子很好的说明题意。这道题并不需要什么特别高深的技巧,难懂的算法,直接按题目的要求来找就可以了。首先,为了快速的在结点值数组中查找某个结点值是否存在,我们可以将所有的结点值放到一个HashSet中,这样我们就能在常数级的时间复杂度中查找。然后我们就可以来遍历链表了,对于遍历到的每个结点值,我们只有两种情况,在或者不在HashSet中。不在HashSet中的情况比较好办,说明此时断开了,而在HashSet中的结点,有可能是该连续子链表的起始点,或者是中间的某个点,而我们的计数器对该子链表只能自增1,所以我们需要想办法来hanlde这种情况。博主最先想到的办法是先处理不在HashSet中的结点,处理方法就是直接跳到下一个结点。那么对于在HashSet中的结点,我们首先将计数器res自增1,然后再来个循环,将之后所有在集合中的结点都遍历完,这样才不会对同一个子链表多次增加计数器,参见代码如下:

解法一:

class Solution {
public:
int numComponents(ListNode* head, vector<int>& G) {
int res = ;
unordered_set<int> nodeSet(G.begin(), G.end());
while (head) {
if (!nodeSet.count(head->val)) {
head = head->next;
continue;
}
++res;
while (head && nodeSet.count(head->val)) {
head = head->next;
}
}
return res;
}
};

我们可以稍稍修改代码,使其更加简洁,我们在遍历的时候进行判断,如果当前结点在集合中,并且当前结点是尾结点或者下一个结点不在集合中的时候,我们让计数器自增1,通过这种操作,我们不会多加也不会漏加计数器,参见代码如下:

解法二:

class Solution {
public:
int numComponents(ListNode* head, vector<int>& G) {
int res = ;
unordered_set<int> nodeSet(G.begin(), G.end());
while (head) {
if (nodeSet.count(head->val) && (!head->next || !nodeSet.count(head->next->val))) {
++res;
}
head = head->next;
}
return res;
}
};

参考资料:

https://leetcode.com/problems/linked-list-components/description/

https://leetcode.com/problems/linked-list-components/solution/

https://leetcode.com/problems/linked-list-components/discuss/123842/C++JavaPython-Easy-and-Concise-Solution-with-Explanation

LeetCode All in One 题目讲解汇总(持续更新中...)

[LeetCode] Linked List Components 链表组件的更多相关文章

  1. LeetCode 817. Linked List Components (链表组件)

    题目标签:Linked List 题目给了我们一组 linked list, 和一组 G, 让我们找到 G 在 linked list 里有多少组相连的部分. 把G 存入 hashset,遍历 lin ...

  2. Java实现 LeetCode 817 链表组件(暴力)

    817. 链表组件 给定一个链表(链表结点包含一个整型值)的头结点 head. 同时给定列表 G,该列表是上述链表中整型值的一个子集. 返回列表 G 中组件的个数,这里对组件的定义为:链表中一段最长连 ...

  3. 817. Linked List Components - LeetCode

    Question 817. Linked List Components Solution 题目大意:给一个链表和该链表元素组成的一个子数组,求子数组在链表中组成多少个片段,每个片段中可有多个连续的元 ...

  4. [CareerCup] 2.3 Delete Node in a Linked List 删除链表的节点

    2.3 Implement an algorithm to delete a node in the middle of a singly linked list, given only access ...

  5. LeetCode 61:旋转链表 Rotate List

    ​给定一个链表,旋转链表,将链表每个节点向右移动 k 个位置,其中 k 是非负数. Given a linked list, rotate the list to the right by k pla ...

  6. Linked List Sorting (链表)

    Linked List Sorting (链表)   A linked list consists of a series of structures, which are not necessari ...

  7. LeetCode Linked List Cycle II 和I 通用算法和优化算法

    Linked List Cycle II Given a linked list, return the node where the cycle begins. If there is no cyc ...

  8. Spring学习(十四)----- Spring Auto Scanning Components —— 自动扫描组件

    一.      Spring Auto Scanning Components —— 自动扫描组件 1.      Declares Components Manually——手动配置componen ...

  9. LeetCode:删除排序链表中的重复元素【83】

    LeetCode:删除排序链表中的重复元素[83] 题目描述 给定一个排序链表,删除所有重复的元素,使得每个元素只出现一次. 示例 1: 输入: 1->1->2 输出: 1->2 示 ...

随机推荐

  1. 第十三节:实际开发中使用最多的监视锁Monitor、lock语法糖的扩展、混合锁的使用(ManualResetEvent、SemaphoreSlim、ReaderWriterLockSlim)

    一. 监视锁(Monitor和lock) 1. Monitor类,限定线程个数的一把锁,两个核心方法: Enter:锁住某个资源. Exit:退出某一个资源. 测试案例:开启5个线程同时对一个变量进行 ...

  2. oldboy s21day10

    #!/usr/bin/env python # -*- coding:utf-8 -*-   # 1.写函数,函数可以支持接收任意数字(位置传参)并将所有数据相加并返回. ''' def func(* ...

  3. SpringBoot系列: 制作Docker镜像的全过程

    本文主要参考了 https://segmentfault.com/a/1190000016449865 , 感谢作者的付出. 另外,  在本文中, 演示了Windows+Maven+Docker To ...

  4. [物理学与PDEs]第1章习题7 载流线圈的磁场

    设一半径为 $R$ 的圆周电路上的电流强度为 $I$. 试计算在通过圆心垂直于圆周所在平面的直线上, 由该圆周电路产生的磁场的磁感强度. 解答: 由对称性知在该直线 $l$ 上, ${\bf B}$ ...

  5. SSH框架之hibernate《三》

    Hibernate03     一.多表设计         1.1多表设计的总则             问题:我们为什么要学习多表映射?             答:                ...

  6. Linux性能工具图册-便于查阅

    该图表示了,Linux系统哪种问题用哪种工具

  7. CSS盒模型(Box Model)

    阅读目录 1. 什么是CSS盒模型 2. IE盒模型和W3C盒模型 3. CSS3属性box-sizing 4. 关于盒模型的使用 在最初接触CSS的时候,对于CSS盒模型的不了解,撞了很多次的南墙呀 ...

  8. HttpUtility.UrlEncode编码重写

    1. 某些系统方法,例如.NET系统方法HttpUtility.UrlEncode会将‘=’编码成‘%3d’,而不是%3D,导致加密签名通不过验证,请开发者注意检查. 2.Java 1.3和早期版本中 ...

  9. ubuntu 16.04 安装 kubelet、kubeadm 和 kubectl

    解决了***之后,就开始K8S安装的正式旅程,本次记录  kubelet.kubeadm 和 kubectl 的安装: apt-get update && apt-get instal ...

  10. Mysql --数据的增删改

    插入数据 INSERT 更新数据 UPDATE 删除数据 DELETE 一. 在mysql管理软件中,可以通过SQL语句中的DML语言来实现数据的操作,包括 1.使用insert实现数据的插入 2.u ...