算法小知识-----10.12----- 链表组件

65 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 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;
}

image.png