题目地址:
https://www.lintcode.com/problem/linked-list-components/description
给定一个链表,题目保证链表中数字彼此不同,再给定一个数组 G G G;如果链表中的两个节点 a a a和 b b b, a a a在 b b b之前并且从 a a a到 b b b的路径上所有节点都属于 G G G(或者 b b b在 a a a之前并且从 b b b到 a a a的路径上所有节点都属于 G G G),那么我们说 a a a与 b b b等价。容易验证这是个等价关系。问链表里有多少个等价类。
因为要快速查询某个数是否在 G G G里,我们先将 G G G的所有数加进一个哈希表。接着从链表头开始遍历,遇到在 G G G中的数的时候记等价类个数加一,接着将指针不停向后移动直到走到不在 G G G里的数为止,然后重复上述过程。代码如下:
import java.util.HashSet;
import java.util.Set;
public class Solution {
/**
* @param head: the head
* @param G: an array
* @return: the number of connected components in G
*/
public int numComponents(ListNode head, int[] G) {
// Write your code here
int res = 0;
Set<Integer> set = new HashSet<>();
for (int i : G) {
set.add(i);
}
ListNode dummy = new ListNode(0), prev = dummy;
dummy.next = head;
while (prev.next != null) {
// 走到了G里的数,记等价类个数res加一,
// 并把prev向后移动直到走到链表末尾或者走到了某个G外的数为止
if (set.contains(prev.next.val)) {
res++;
while (prev.next != null && set.contains(prev.next.val)) {
prev = prev.next;
}
} else {
prev = prev.next;
}
}
return res;
}
}
class ListNode {
int val;
ListNode next;
ListNode(int x) {
val = x;
}
}
时间复杂度 O ( n ) O(n) O(n),空间 O ( 1 ) O(1) O(1)。