下面是Java C++题解leetcode817链表组件的完整攻略:
题目描述
给定链表头结点 head,该链表上的每个结点都有一个唯一的整型值。
同时给定列表 G,该列表是上述链表中整型值的一个子集。
返回列表 G 中组件的个数,这里的组件定义为:链表中一段最长连续节点的值(即链表的子段)在列表 G 中出现次数与该段中节点数目相同。(例如,如果组件中的节点数目为 2,且其中的值恰好为 G 中的两个值,这样的组件是合法的)
示例 1:
输入:
head: 0->1->2->3
G = [0, 1, 3]
输出: 2
解释:
链表中,0 和 1 是相连接的,且 G 中有它们都在链表中出现过。
同时,3 不在链表 G 中,所以不是组件。
示例 2:
输入:
head: 0->1->2->3->4
G = [0, 3, 1, 4]
输出: 2
解释:
链表中,0 和 1 是相连接的,3 和 4 是相连接的,且 G 中有它们都在链表中出现过。
注意:
如果 N 是给定链表 head 的长度,范围在 [1, 10000]。
链表中每个节点的值范围在 [0, N - 1]。
1 <= G.length <= 10000
G 是链表中所有结点的值的一个子集。
## 解题思路
这道题让我们求链表 G 组件的个数,那么我们先遍历链表,用 HashMap 把链表中的值添加进去,然后再遍历一次链表,分割链表,找到组件的个数。
HashMap 的 key 存储链表中的值,value 值为 true,代表它在链表中存在。
对于链表的遍历,我们可以通过设置一个变量 `previous`,用来判断当前的节点和前一个节点是否都在集合 G 中,如果是,那么它们是同一组件的一部分,继续遍历,直到不在集合 G 中,说明已经遍历到一个组件的结束位置,计数器加 1 即可。
## 代码实现
我们可以分为两步来分别实现算法:
1. 遍历链表,用 HashMap 存储链表中的值;
2. 遍历链表,分割链表,找到组件的个数。
下面是代码实现(Java 语言):
```java
public int numComponents(ListNode head, int[] G) {
Set<Integer> set = new HashSet<>();
for (int g : G) {
set.add(g);
}
int count = 0;
boolean previousExist = false;
while (head != null) {
if (set.contains(head.val)) {
if (previousExist == false) {
count++;
}
previousExist = true;
} else {
previousExist = false;
}
head = head.next;
}
return count;
}
下面是代码实现(C++ 语言):
class Solution {
public:
int numComponents(ListNode* head, vector<int>& G) {
set<int> values(G.begin(), G.end());
int count = 0;
bool previousExist = false;
while (head != nullptr) {
if (values.count(head->val)) {
if (previousExist == false) {
count++;
}
previousExist = true;
} else {
previousExist = false;
}
head = head->next;
}
return count;
}
};
示例说明
示例 1
输入:
head: 0->1->2->3
G = [0, 1, 3]
输出:
2
解释:
链表中,0 和 1 是相连接的,且 G 中有它们都在链表中出现过。同时,3 不在链表 G 中,所以不是组件。所以一共有 2 个组件。
示例 2
输入:
head: 0->1->2->3->4
G = [0, 3, 1, 4]
输出:
2
解释:
链表中,0 和 1 是相连接的,3 和 4 是相连接的,且 G 中有它们都在链表中出现过。所以一共有 2 个组件。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Java C++题解leetcode817链表组件示例 - Python技术站