持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第15天,点击查看活动详情
明明已经上了5天班了,为什么才周三!!!
链表组件
该题出自力扣的817题 —— 链表组件【中等题】
审题
给定链表头结点 head,该链表上的每个结点都有一个 唯一的整型值 。同时给定列表 nums,该列表是上述链表中整型值的一个子集。 返回列表 nums 中组件的个数,这里对组件的定义为:链表中一段最长连续结点的值(该值必须在列表 nums 中)构成的集合。
- 这道题感觉确实并不是特别困难,但是一些小边界需要注意的。就是给出一个链表,再给出一个数组,数组内存储着链表的部分节点,需要找出链表内的组件,并且如果是连续的话,视作一个组件
- 首先需要判断链表的节点是否存在于数组,那么如果使用暴力寻找:也就是每次找链表节点数据都遍历一次数组,那么时间复杂度将会来到O(n²),所以要转换一下数据结构,这边选择了List作为存储媒介,利用其中的contain方法,去判断是否存在
- 再开辟一个变量,存储是否连续子串,因为连续子串只会作为一个组件计入数
- 后续就是常规遍历链表了
- 那么也可以有个优化点,就是利用数组的随机访问,考虑到用例只有10000个,直接提前开辟这个数量的数组,可以使性能提高,相当于用空间换时间
编码
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;
}
}
public int numComponents(ListNode head, int[] nums) {
int num = 0;
boolean flag = false;
List<Integer> list = new ArrayList<>();
for (int a:nums) {
list.add(a);
}
while (head != null){
int val = head.val;
boolean contains = list.contains(val);
if (!contains && flag) {
num++;
flag = false;
}else if (contains){
flag = true;
}
head = head.next;
}
if (flag)num++;
return num;
}