【近日力扣】(链表合集2)删除链表的倒数第n个节点+相交链表+移除链表元素+合并两个排序的链表

一路摸索下来发现,链表题常规的解题方法有递归、迭代两种,可以优先考虑

删除链表的倒数第n个节点(简单)

  • 思路:首先得确定第 n 个节点在哪,先遍历出链表长度;然后长度和 n 相减,找到正数第几个节点,再次遍历,跳过那个节点即可。还要分三种情况——删除第一个节点、删除中间节点、删除末尾节点,会发现只有第一种需要另外考虑,若要删除第一个节点则直接返回第二个节点即可
var removeNthFromEnd = function(head, n) {
    let cur = head, sum = 0
    while (cur !== null) {
        cur = cur.next
        sum++
    }
    if (sum === n) {
        return head.next
    }
    cur = head
    while (sum - n) {
        if (sum - n === 1) {
            cur.next = cur.next.next
        } else {
            cur = cur.next
        }
        sum--
    }
    return head
};

相交链表(简单)

  • 哈希表:先遍历第一个链表,把链表的每一个节点都存到哈希表里,然后再遍历第二个链表,比对每一个节点是否在哈希表中存在。(哈希表里存的节点是引用,所以每个节点都对应这之后的链表,如果第二个链表中有节点和在哈希表里存在,意味着这个节点及之后的链表都相同,也就是相交于该节点)
var getIntersectionNode = function(headA, headB) {
    let cur = headA
    let map = new Map()
    while (cur !== null) {
        map.set(cur, cur)
        cur = cur.next
    }
    cur = headB
    while (cur !== null) {
        if (map.has(cur)) return cur
        cur = cur.next
    }
    return null
};

移除链表元素(简单)

  • 哈希表:此处用数组当哈希表。先遍历链表,存入不需移除的节点,然后再遍历数组,将每个节点取出,先令其指向 null,然后若下一个节点再指向下一节点,最后可拼接成所需链表,也就是直接返回数组第一个元素即可
var removeElements = function(head, val) {
    if (!head) return null
    let cur = head
    let arr = []
    while (cur !== null) {
        if (cur.val !== val) {
            arr.push(cur)
        }
        cur = cur.next
    }
    if (!arr.length) return null
    for (let i = 0; i < arr.length; i++) {
    	// 指向null,去除后续节点的影响
        arr[i].next = null
        // 如果下一个节点存在,再指向下一个节点
        if (arr[i +1]) arr[i].next = arr[i + 1]
    }
    return arr[0]
};
  • 递归:首先对头节点判断,如果头节点需删除,则返回下一节点,否则继续判断下一节点,如此反复,是一个递归过程
var removeElements = function(head, val) {
    if (!head) return null
    head.next = removeElements(head.next, val)
    return head.val === val ? head.next : head
};
  • 迭代:需要构造一个头节点,指向链表形成新链表。然后,遍历新链表,如果当前节点的下一节点为需移除的,则跳过并指向下下节点,否则指向下一节点,最后返回新链表的下一节点即可
var removeElements = function(head, val) {
    if (!head) return null
    let node = new ListNode(0)
    node.next = head
    let cur = node
    while (cur.next !== null) {
        if (cur.next.val === val) {
            cur.next = cur.next.next
        } else {
            cur = cur.next
        }
    }
    return node.next
};

合并两个排序的链表(简单)

  • 递归:先比较 l1、l2 的第一个节点大小,如果前者大返回前者,后者大同理,然后继续比较后续节点,是一个递归过程,注意终止条件,只要递归到其中一个为null时,返回另一个就行
var mergeTwoLists = function(l1, l2) {
    if (l1 === null) {
        return l2
    } else if (l2 === null) {
        return l1
    }
    if (l1.val <= l2.val) {
        l1.next = mergeTwoLists(l1.next, l2)
        return l1
    } else {
        l2.next = mergeTwoLists(l1, l2.next)
        return l2
    }
};

如果觉得对你有帮助的话,点个赞呗~

反正发文又不赚钱,交个朋友呗~

如需转载,请注明出处foolBirdd

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值