package LeetCode_817
/**
* 817. Linked List Components
* https://leetcode.com/problems/linked-list-components/
* You are given the head of a linked list containing unique integer values and an integer array nums that is a subset of the linked list values.
Return the number of connected components in nums where two values are connected if they appear consecutively in the linked list.
Example 1:
Input: head = [0,1,2,3], nums = [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], nums = [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.
Constraints:
The number of nodes in the linked list is n.
1 <= n <= 10^4
0 <= Node.val < n
All the values Node.val are unique.
1 <= nums.length <= n
0 <= nums[i] < n
All the values of nums are unique.
* */
//Definition for singly-linked list.
class ListNode(var `val`: Int) {
var next: ListNode? = null
}
class Solution {
/**
* Solution: Build graph + DFS to find out connected components;
* Time complexity:O(n), Space complexity:O(n);
* */
fun numComponents(head: ListNode?, G: IntArray): Int {
//1. build undirected graph by ListNode, u->v, if both u,v in G
var head_ = head
val graph = HashMap<Int, ArrayList<Int>>()
while (head_?.next != null) {
val u = head_.`val`
val v = head_.next?.`val` ?: -1
if (G.contains(u) && v != -1 && G.contains(v)) {
graph.putIfAbsent(u, ArrayList())
graph.putIfAbsent(v, ArrayList())
graph.get(u)?.add(v)
graph.get(v)?.add(u)
}
head_ = head_.next
}
var result = 0
val visited = HashSet<Int>()
//2. the count of connected components is the use times of DFS,
// because after DFS all node will be traversed, so result++.
for (item in G) {
if (visited.contains(item)) {
continue
}
dfs(item, graph, visited)
result++
}
return result
}
private fun dfs(current: Int, graph: HashMap<Int, ArrayList<Int>>, visited: HashSet<Int>) {
if (visited.contains(current)) {
return
}
visited.add(current)
if (graph.get(current) != null) {
for (next in graph.get(current)!!) {
dfs(next, graph, visited)
}
}
}
}