数据结构-链表练习

350 阅读3分钟

「这是我参与11月更文挑战的第20天,活动详情查看:2021最后一次更文挑战

在这里插入图片描述

再学习链表之后,一定要做题巩固,下面是关于链表比较常见的一些题目,上题目

1. 将两个升序链表合并为⼀个新的升序链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。

示例: 输⼊:1->2->4, 1->3->4 输出:1->1->2->3->4->4

实现思想:

  1. 首先确定解题的数据结构:这里使用单链表比较快速
  2. 假设我们把两个链表分别称作链表a和链表b。从链表头开始比较,链表a和链表b都是有序递增的,所以比较链表a和链表b的第一个元素的较小值就是合并后链表的最小值。合并后链表的第二位就是小节点的next.element,与大节点的element的比较大小,依次递归,直到递归到链表a和链表b均为null
  3. 确定边界条件:当递归到任意链表为null,直接将next后继指针指向另外的链表即可,不需要再继续递归了
function mergeTwoLists(a, b) {
    //代码1
    if (a === null) return b;
    if (b === null) return a;

    //代码2
    if (a.element <= b.element) {
        a.next = mergeTwoLists(a.next, b)
        return b
    } else {
        b.next = mergeTwoLists(b.next, a)
        return b
    }
}

代码解读: 代码1:如果链表一方不存在的情况下,直接返回另一个链表即可

2. 判断一个单链表是否有环

题目描述:给定一个链表,判断链表中是否有环。 为了表示给定链表中的环,我们使⽤整数pos来表示链表尾连接到链表中的位置(索引从0开始)。如> 果pos是-1 ,则在该链表中没有环。 输⼊:head = [3,2,0,-4],pos = 1 输出:true 解释:链表中有⼀个环,其尾部连接到第⼆个节点。

这里有两种解法:

1. 节点标记法

实现思想:给每一个已遍历过的节点加上一个标志,遍历链表,当出现下一个节点已被标记过的时候,说明链表中有环

function hasCircle(head) {
    while (head) {
        if (head.flag) return true;
        head.flag = true;
        head = head.next;
    }
    return false
}
2. 快慢指针(双指针)

这是实现这个问题最常用也是面试最想问的一个答案

实现思想:设置快慢两个指针,遍历单链表,快指针一次走两步,慢指针一次走一步,如果是单链表中存在和环,则快慢指针终会指向同一个节点,否则直到快指针指向null,快慢指针都不可能相遇.

function hasCircle2(head){
    //代码1
    if(!head || !head.next){
        return false
    }
    // 代码2
    let fast = head.next.next;
    let slow = head.next;
    // 代码3
    while(fast != slow){
        if(!fast || !fast.next) return false;
        fast = fast.next.next;
        slow = slow.next;
    }
    return true
} 

代码解读: 代码1:判断链表是否存在,并且是否有值 代码2:设置快指针fast是链表的第三个元素,慢指针是链表的第二个元素 代码3:循环判断快慢指针是否相等,判断链表中是否有

在这里插入图片描述