1. 题目与解析
给定链表头结点
head,该链表上的每个结点都有一个 唯一的整型值 。同时给定列表nums,该列表是上述链表中整型值的一个子集。 返回列表nums中组件的个数,这里对组件的定义为:链表中一段最长连续结点的值(该值必须在列表nums中)构成的集合。
输入: head = [0,1,2,3], nums = [0,1,3]
输出: 2
解释: 链表中,0 和 1 是相连接的,且 nums 中不包含 2,所以 [0, 1] 是 nums 的一个组件,同理 [3] 也是一个组件,故返回 2。
输入: head = [0,1,2,3,4], nums = [0,3,1,4]
输出: 2
解释: 链表中,0 和 1 是相连接的,3 和 4 是相连接的,所以 [0, 1] 和 [3, 4] 是两个组件,故返回 2。
分析题目,我们可以知道,题目的两个输入为一个链表以及一个集合,我们需要计算最长的连续节点的值。换一种方式理解,我们可以将题目翻译为,nums几何中的每个数字都会点亮head链表中对应的节点,我们需要求解的是被点亮的最长的连续子链表的长度,这样题目就可以理解了。
分析完题目,确定方法,首先,使用一个set来统计nums中所含有的所有元素的种类,以供后续遍历使用:
Set<Integer> set = new HashSet<>();
for (int num: nums) {
set.add(num);
}
之后,我们需要在上诉set的基础上进行一遍遍历求解,遍历的过程中,我们使用一个标记位标记当前是否为点亮状态,之后更新当前的点亮长度以及最长的点亮长度,最后得到我们所需要的结果:
ListNode tmp = head;
boolean flg = false;
int ans = 0;
while (tmp != null) {
if (set.contains(tmp.val)) {
flg = true;
} else {
if (flg) {
ans++;
}
flg = false;
}
tmp = tmp.next;
}
if (flg) {
ans++;
}
return ans;
2. 题解
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode() {}
* ListNode(int val) { this.val = val; }
* ListNode(int val, ListNode next) { this.val = val; this.next = next; }
* }
*/
class Solution {
public int numComponents(ListNode head, int[] nums) {
Set<Integer> set = new HashSet<>();
for (int num: nums) {
set.add(num);
}
ListNode tmp = head;
boolean flg = false;
int ans = 0;
while (tmp != null) {
if (set.contains(tmp.val)) {
flg = true;
} else {
if (flg) {
ans++;
}
flg = false;
}
tmp = tmp.next;
}
if (flg) {
ans++;
}
return ans;
}
}