链表

前言


链表知识点回顾

链表知识点

反转链表_简单

反转一个单链表。
示例:
输入: 1->2->3->4->5->NULL 输出: 5->4->3->2->1->NULL

链表单次遍历,将当前节点指向前一节点。最后监听当前节点是否为null即可。

 * Definition for singly-linked list.
 * function ListNode(val) {
 *     this.val = val;
 *     this.next = null;
 * }
 */
/**
 * @param {ListNode} head
 * @return {ListNode}
 */
var reverseList = function(head) {
    if(!head || !head.next) return head;
    var prev=null;
    var cur = head;
    while(cur){
    	var next = cur.next;
		cur.next = prev;
		prev = cur;
		cur = next;
    }
    return prev;
};**

移除链表元素_简单

删除链表中等于给定值 val 的所有节点。
示例:
输入: 1->2->6->3->4->5->6, val = 6 输出: 1->2->3->4->5

var removeElements = function(head, val) {
    if(!head) return null 
    let resListNode = new ListNode(null)
    let prev = resListNode,curr = head
    prev.next = head
    while(curr){
        if(curr.val === val){
            prev.next = curr.next
            curr = curr.next
        }else{
            prev = curr
            curr= curr.next
        }
    }
    return resListNode.next
};

合并两个有序链表_简单

将两个有序链表合并为一个新的有序链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。
示例: 输入:1->2->4,1->3->4
输出:1->1->2->3->4->4

递归解法

设定递归终止条件,根据l1和l2两个链表的值大小,决定后续节点,递归实现。

/**
 * Definition for singly-linked list.
 * function ListNode(val) {
 *     this.val = val;
 *     this.next = null;
 * }
 */
/**
 * @param {ListNode} l1
 * @param {ListNode} l2
 * @return {ListNode}
 */
var mergeTwoLists = function (l1, l2) {
    if (!l2) return l1
    if (!l1) return l2
    if (l1.val < l2.val) {
        l1.next = mergeTwoLists(l1.next,l2)
        return l1
    } else {
        l2.next = mergeTwoLists(l1,l2.next)
        return l2
    }
};

链表遍历

额外声明一个返回链表,对原本两个链表进行遍历,得到的较小值存入返回链表中。最后拼接两个链表中多余的部分。

/**
 * Definition for singly-linked list.
 * function ListNode(val) {
 *     this.val = val;
 *     this.next = null;
 * }
 */
/**
 * @param {ListNode} l1
 * @param {ListNode} l2
 * @return {ListNode}
 */
var mergeTwoLists = function (l1, l2) {
    var pHead = new ListNode(-1)
    var node = pHead;
    while (l1 && l2) {
        if (l1.val <= l2.val) {
            node.next = l1;
            l1 = l1.next
        } else {
            node.next = l2;
            l2 = l2.next
        }
        node = node.next;
    }
    node.next = l1? l1:l2;
    return pHead.next;
};

重排链表_中等

给定一个单链表 L:L0→L1→…→Ln-1→Ln ,
将其重新排列后变为: L0→Ln→L1→Ln-1→L2→Ln-2→…
你不能只是单纯的改变节点内部的值,而是需要实际的进行节点交换。
示例 1: 给定链表 1->2->3->4, 重新排列为1->4->2->3.
示例 2: 给定链表 1->2->3->4->5, 重新排列为 1->5->2->4->3.

要将链表这样重排,可以分三个步骤,先将链表重中间位置切断,然后将后方链表反转,经过这样处理后再讲两个链表各自从初始节点相连。

/**
 * Definition for singly-linked list.
 * function ListNode(val) {
 *     this.val = val;
 *     this.next = null;
 * }
 */
/**
 * @param {ListNode} head
 * @return {void} Do not return anything, modify head in-place instead.
 */
var reorderList = function (head) {
    if (!head || !head.next) return head;
    let [low, rightNode] = [head, head.next]
    while (rightNode && rightNode.next) {
        [low, rightNode] = [low.next, rightNode.next.next]
    }
    //第二段链表
    rightNode = low.next
    //第一段链表
    low.next = null
    low = head
    //反转第二段链表
    let pre = null
    let cur = rightNode
    while (cur) {
        let next = cur.next
        cur.next = pre
        pre = cur
        cur = next
    }
    rightNode = pre
    //拼接两段链表
    while (rightNode) {
        let nextLeft = low.next
        let nextRight = rightNode.next
        low.next = rightNode
        rightNode.next = nextLeft
        low = nextLeft
        rightNode = nextRight
    }
};

两数相加_中等

给出两个 非空 的链表用来表示两个非负的整数。其中,它们各自的位数是按照 逆序 的方式存储的,并且它们的每个节点只能存储 一位 数字。如果,我们将这两个数相加起来,则会返回一个新的链表来表示它们的和。 您可以假设除了数字 0 之外,这两个数都不会以 0 开头。
示例:
输入:(2 -> 4 -> 3) + (5 -> 6 -> 4) 输出:7 -> 0 -> 8
原因:342 + 465 = 807

顺序遍历链表,取的当前数位之和与当前进位数值,循环执行,得到结果。

/**
 * Definition for singly-linked list.
 * function ListNode(val) {
 *     this.val = val;
 *     this.next = null;
 * }
 */
/**
 * @param {ListNode} l1
 * @param {ListNode} l2
 * @return {ListNode}
 */
var addTwoNumbers = function (l1, l2) {
    if (!l1) return l2
    if (!l2) return l1
    var res = new ListNode(null)
    var resNode = res
    let params = 0 //进位值
    let val = 0 //当前层的值
    while (l1 || l2) {
        let x = l1 ? l1.val : 0
        let y = l2 ? l2.val : 0
        val = (x + y + params) % 10
        params = Math.floor((x + y + params) / 10)
        resNode.next = new ListNode(val)
        resNode = resNode.next
        if (l1) l1 = l1.next
        if (l2) l2 = l2.next
    }
    if (params) {
        resNode.next = new ListNode(params)
    }
    return res.next
};

K个一组反转链表_困难

给你一个链表,每 k 个节点一组进行翻转,请你返回翻转后的链表。 k 是一个正整数,它的值小于或等于链表的长度。 如果节点总数不是 k
的整数倍,那么请将最后剩余的节点保持原有顺序。 示例: 给你这个链表:1->2->3->4->5 当 k = 2 时,应当返回:
2->1->4->3->5 当 k = 3 时,应当返回: 3->2->1->4->5 说明: 你的算法只能使用常数的额外空间。
你不能只是单纯的改变节点内部的值,而是需要实际进行节点交换。

var reverseKGroup = function (head, k) {
    if (!head) return head
    let cur = head, amount = 0
    //得到每次翻转的首位
    while (cur !== null && amount !== k) {
        cur = cur.next
        amount++
    }
    if (amount === k) {
    	//递归得到,翻转的连接节点
        cur = reverseKGroup(cur, k)
        while (k > 0) {
            let next = head.next
            head.next = cur
            cur = head
            head = next
            k--
        }
        //防止最后仅剩一位的特殊情况。
        head = cur
    }
    return head
};
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值