LeetCode 817. 链表组件
难度: m i d d l e \color{orange}{middle} middle
题目描述
给定链表头结点 h e a d head head,该链表上的每个结点都有一个 唯一的整型值 。同时给定列表 n u m s nums nums,该列表是上述链表中整型值的一个子集。
返回列表 n u m s nums nums 中组件的个数,这里对组件的定义为:链表中一段最长连续结点的值(该值必须在列表 n u m s nums nums 中)构成的集合。
示例 1:
输入: head = [0,1,2,3], nums = [0,1,3]
输出: 2
解释: 链表中,0 和 1 是相连接的,且 nums 中不包含 2,所以 [0, 1] 是 nums 的一个组件,同理 [3] 也是一个组件,故返回 2。
示例 2:
输入: head = [0,1,2,3,4], nums = [0,3,1,4]
输出: 2
解释: 链表中,0 和 1 是相连接的,3 和 4 是相连接的,所以 [0, 1] 和 [3, 4] 是两个组件,故返回 2。
提示:
- 链表中节点数为 n n n
- 1 < = n < = 1 0 4 1 <= n <= 10^{4} 1<=n<=104
- 0 < = N o d e . v a l < n 0 <= Node.val < n 0<=Node.val<n
- N o d e . v a l Node.val Node.val 中所有值 不同
- 1 < = n u m s . l e n g t h < = n 1 <= nums.length <= n 1<=nums.length<=n
- 0 < = n u m s [ i ] < n 0 <= nums[i] < n 0<=nums[i]<n
- n u m s nums nums 中所有值 不同
算法
(哈希表)
- 首先对数组
nums
构建哈希表。 - 然后线性遍历链表,如果发现链表中有连续的一段都出现在哈希表中,则答案增加
1
。
复杂度分析
-
时间复杂度:构建哈希表的时间复杂度为 O ( m ) O(m) O(m),遍历链表的时间复杂度为 O ( n ) O(n) O(n)。故总时间复杂度为 O ( n + m ) O(n + m) O(n+m)
-
空间复杂度 : O ( 1 ) O(1) O(1),需要额外的空间存放哈希表。
C++ 代码
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode() : val(0), next(nullptr) {}
* ListNode(int x) : val(x), next(nullptr) {}
* ListNode(int x, ListNode *next) : val(x), next(next) {}
* };
*/
class Solution {
public:
int numComponents(ListNode* head, vector<int>& nums) {
unordered_set<int> S(nums.begin(), nums.end());
int res = 0, s = 0;
for (auto p = head; p; p = p->next) {
if (S.count(p->val)) s ++;
else {
if (s) {
s = 0;
res ++;
}
}
}
if (s) res ++;
return res;
}
};