代码随想录的第三天

78 阅读2分钟

代码随想录的第三天

203. 移除链表元素

原链表删除
var removeElements = function(head, val) {
    while (head !== null && head.val === val) {
        head = head.next
    }
    let cur = head
    while (cur !== null && cur.next !== null) {
        if (cur.next.val === val) {
            cur.next = cur.next.next
        } else {
            cur = cur.next
        }
    }
    return head
}
定义虚拟头节点
var removeElements = function(head, val) {
    let firstNode = new ListNode()
    firstNode.next = head
    let cur = firstNode
    while (cur !== null && cur.next !== null) {
        if (cur.next.val === val) {
            cur.next = cur.next.next
        } else {
            cur = cur.next
        }
    }
    return firstNode.next
};

思路:

1、其实就是找到相同节点,让上一个指针指向下下个指针,跳过去中间完成删除

2、判断头节点是不是第一个,如果是就一直删除;或者就是定义一个虚拟的头节点,然后最后再将头节点去掉

707. 设计链表

单指针:

var MyLinkedList = function() {
    this.size = 0
    this.head = new ListNode(0)
};

function ListNode(val, next) {
    this.val = (val === undefined ? 0 : val)
    this.next = (next === undefined ? null : next)
}

/** 
 * @param {number} index
 * @return {number}
 */
MyLinkedList.prototype.get = function(index) {
    if (index < 0 || index >= this.size) return -1
    let cur = this.head
    while (index >= 0) {
        cur = cur.next
        index--
    }
    return cur.val
};

/** 
 * @param {number} val
 * @return {void}
 */
MyLinkedList.prototype.addAtHead = function(val) {
    this.addAtIndex(0, val);
};

/** 
 * @param {number} val
 * @return {void}
 */
MyLinkedList.prototype.addAtTail = function(val) {
    this.addAtIndex(this.size, val);
};

/** 
 * @param {number} index 
 * @param {number} val
 * @return {void}
 */
MyLinkedList.prototype.addAtIndex = function(index, val) {
    if (index > this.size) {
        return -1
    }
    index = Math.max(0, index)
    this.size++
    let cur = this.head
    while (index > 0) {
        cur = cur.next
        index--
    }
    let toAdd = new ListNode(val)
    toAdd.next = cur.next
    cur.next = toAdd
};

/** 
 * @param {number} index
 * @return {void}
 */
MyLinkedList.prototype.deleteAtIndex = function(index) {
    if (index < 0 || index >= this.size) return -1
    this.size--
    let cur = this.head
    while (index > 0) {
        cur = cur.next
        index--
    }
    cur.next = cur.next.next
};

/**
 * Your MyLinkedList object will be instantiated and called as such:
 * var obj = new MyLinkedList()
 * var param_1 = obj.get(index)
 * obj.addAtHead(val)
 * obj.addAtTail(val)
 * obj.addAtIndex(index,val)
 * obj.deleteAtIndex(index)
 */

思路:(暂时只研究单指针)

1、首先是定义指针

2、其次主要三个函数,一个增加节点,删除节点和查询节点

3、增加节点:超出总长度无法增加(因为在链表前加),总长度加一,然后找到需要增加的节点的位置,进行节点增加(注意:需要先将增加的节点指向下一个,再将原先节点指向新增节点)

4、删除节点:总长度减一,找到需要删除的节点,直接指向下下个节点

5、查询节点:找到第index节点然后输出val(为什么不能等于size,因为节点是从0开始的)

206. 反转链表

双指针法
var reverseList = function(head) {
    let node = null
    let cur = head
    while (cur) {
        const temp = cur.next
        cur.next = node
        node = cur
        cur = temp
    }
    return node
};

思路:

1、首先是定义一个虚拟的首节点

2、然后去进行循环链表

3、先将链表的首节点后的链表存储起来,因为后续的操作会影响后续的链表,然后将当前节点指向null,进行首节点的翻转;然后将node节点向后移动一位,将cur向后移动一位

递归
var reverseList = function(head) {
    return reverse (head, null)
};

function reverse (cur, pred) {
    if (cur === null) return pred
    const temp = cur.next
    cur.next = pred
    pred = cur
    cur = temp
    return reverse(cur, pred)
}

思路:

模拟双指针遍历,将当前节点的next暂存,然后当前节点指向定义的null,完成了链表的首节点的翻转,然后两个节点都向后走