算法

算法 - 链表

2021-03-01  本文已影响0人  羽晞yose

链表

数组 VS 链表

数组:增删非首尾元素时往往需要移动元素
链表:增删非首尾元素,不需要移动元素,只需要更改 next 指针即可

JS中的链表

遍历链表

const a = { val: 'a' }
const b = { val: 'b' }
const c = { val: 'c' }
const d = { val: 'd' }
a.next = b
b.next = c
c.next = d

// 遍历链表
let p = a
while (p) {
    console.log(p.val)
    p.next
}

// 插入
const e = { val: 'e' }
c.next = e
e.next = d

// 删除
c.next = d

删除链表中的节点

leeCode第237题

const deleteNode = function(node) {
    node.val = node.next.val // 将值改为链表的下一项的值
    node.next = node.next.next // 将本身的指向改为下一项的指向
}

反转链表

leeCode第206题

/**
 * @param {ListNode} head
 * @return {ListNode}
 */
function ListNode(val, next = null) {
    this.val = val;
    this.next = next;
}

/**
 * 将一个数组转为链表
 * @param {array} arr
 * @return {ListNode}
 */
const getListFromArray = (arr) => {
    let dummy = new ListNode()
    let pre = dummy;
    arr.forEach(x => pre = pre.next = new ListNode(x));
    return dummy.next;
}

const reverseList = function(head) {
    let p1 = head
    let p2 = null

    while (p1) {
        const tmp = p1.next
        p1.next = p2
        p2 = p1
        p1 = tmp

        console.log(p1, p2)
    }

    return p2
};

let listNodes = getListFromArray([1, 2, 3, 4, 5])

const res = reverseList(listNodes)
console.log(listNodes, res)

此解法为双指针迭代,还有一种为迭代
播放量最多也最好懂的答案

两数相加

leeCode第206题

将数组转为链表上面已经提供了,下面就不再提供了

var addTwoNumbers = function(l1, l2) {
    let head = null, tail = null;
    let carry = 0;

    while (l1 || l2) {
        const v1 = l1 ? l1.val : 0 // 因为两个链表长度不需要一样,所以可能对应不上
        const v2 = l2 ? l2.val : 0
        const val = v1 + v2 + carry
        carry = ~~(val / 10) // 取出10位数,不太直观就是将结果toString()取索引0

        if (!head) {
            head = tail = new ListNode(val % 10); // 创建链,头尾一致
        } else {
            tail.next = new ListNode(val % 10);
            tail = tail.next;
        }

        if (l1) l1 = l1.next
        if (l2) l2 = l2.next
    }

    // 判断最后是否存在carry,有的话需要补到链表最后位
    if (carry > 0) {
        tail.next = new ListNode(carry);
    }

    return head
};

const l1 = getListFromArray([2,4,3])
const l2 = getListFromArray([5,6,4])
addTwoNumbers(l1, l2)

删除排序链表中的重复元素

leeCode第83题

/**
 * @param {ListNode} head
 * @return {ListNode}
 */
const deleteDuplicates = function(head) {
    let p = head
    while (p && p.next) {
        if (p.val === p.next.val) { // 当前与下一个值相同,则删除下一个值
            p.next = p.next.next
        } else {
            p = p.next
        }
    }
    return head
}

const duplicateLink = getListFromArray([1,1,1,2,3,3])
console.log(deleteDuplicates(duplicateLink))

环形链表

leeCode第141题

/**
 * @param {ListNode} head
 * @return {boolean}
 */
const hasCycle = function(head) {
    let p1 = head
    let p2 = head
    while(p1 && p2 && p2.next) {
        p1 = p1.next
        p2 = p2.next.next
        if (p1 === p2) {
            return true
        }
    }

    return false
}

这道题实在不知道要怎么模拟,要模拟就必须在最后一位重写指向,入参就跟题目对不上了,只能去leeCode上去校验

上一篇 下一篇

猜你喜欢

热点阅读