817. 链表组件

798 阅读1分钟

题目介绍

力扣817题:leetcode-cn.com/problems/li…

image.png

方法:线性扫描

我们对链表进行一次扫描,一个组件在链表中对应一段极长的连续节点,因此如果当前的节点在列表 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 中。