题目介绍
力扣817题:leetcode-cn.com/problems/li…
方法:线性扫描
我们对链表进行一次扫描,一个组件在链表中对应一段极长的连续节点,因此如果当前的节点在列表 G 中,并且下一个节点不在列表 G 中,我们就找到了一个组件的尾节点,可以将答案加 1。
例如,当链表为 0 -> 1 -> 2 -> 3 -> 4 -> 5 -> 6 -> 7,G 为 [0, 2, 3, 5, 7] 时,我们扫描之后可以发现 0, 3, 5, 7 四个节点是组件的尾节点,那么答案就为 4。
代码如下:
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode() {}
* ListNode(int val) { this.val = val; }
* ListNode(int val, ListNode next) { this.val = val; this.next = next; }
* }
*/
class Solution {
public int numComponents(ListNode head, int[] nums) {
if(head == null || nums.length == 0) {
return 0;
}
Set<Integer> set = new HashSet();
for (int x: nums) {
set.add(x);
}
ListNode cur = head;
int result = 0;
while (cur != null) {
//如果当前节点在G集合中,并且下一个节点不在G集合中,则组件个数加一
if (set.contains(cur.val) && (cur.next == null || !set.contains(cur.next.val))) {
result++;
}
cur = cur.next;
}
return result;
}
}
复杂度分析
-
时间复杂度:O(N + |G|),其中 N 是链表中的节点个数。
-
空间复杂度:O(|G|),我们需要将 G 中的元素存储到无序集合中,用来快速判断一个节点是否出现在 G 中。