原题链接: https://leetcode.com/problems/linked-list-components/
1. 题目介绍
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.
给出一个链表。这个链表中,每个节点的 val 值都是独一无二的整数。
同样也给出一个数组G。数组G中的元素是链表所有节点 val 值的子集。
在链表中,如果某个节点的 val 值在数组G中,那么这个节点就被看作一个“组件”。“组件”还有一个特性,那就是相邻的“组件”,仍然被视为一个“组件”。
最终求整个链表一共有多少个“组件”?
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 head, 1 <= 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.
N是链表的长度,N的范围:1 <= N <= 10000.
每个节点的val 的范围: [0, N - 1]
1 <= G.length <= 10000. G中的元素是链表所有节点 val 值的子集。
2. 解题思路
首先使用 Hashset 存储数组 G 中的值。这个集合用于判断一个节点是不是“组件”。
然后使用指针 cur 遍历链表,如果 cur所指的节点是“组件”,那么就让 cur 一路冲过所有相邻的"组件",并且“组件”个数加一。如果 cur 所指向的节点不是“组件”,那么cur继续指向 cur.next,直至到链表结尾。
实现代码
class Solution {
public int numComponents(ListNode head, int[] G) {
HashSet<Integer> set = new HashSet<Integer>();
for(int i = 0 ; i < G.length ; i++ ){
set.add(G[i]);
}
ListNode cur = head;
int ans = 0;
while(cur != null){
if ( set.contains(cur.val) == true) {
//这里一定是先写cur != null,再写set.contains(cur.val) == true
while(cur != null && set.contains(cur.val) == true ){
cur = cur.next;
}
ans++;
}else{
cur = cur.next;
}
}
return ans;
}
}
更简洁的代码,来自 https://leetcode.com/problems/linked-list-components/solution/
在Leetcode的Solution中,给出了另外一份代码。代码的思路是,每找到一个自己是组件但是自己的next不是组件的节点,就为组件的总数加1。它的代码更加简洁,可以学习一下:
class Solution {
public int numComponents(ListNode head, int[] G) {
Set<Integer> Gset = new HashSet();
for (int x: G) Gset.add(x);
ListNode cur = head;
int ans = 0;
while (cur != null) {
if (Gset.contains(cur.val) &&
(cur.next == null || !Gset.contains(cur.next.val)))
ans++;
cur = cur.next;
}
return ans;
}
}