Skip to content
On this page

707-设计链表

标签:设计 链表

题目信息

题目地址707. 设计链表

题目内容:

javascript
你可以选择使用单链表或者双链表,设计并实现自己的链表。

单链表中的节点应该具备两个属性:val和next。val是当前节点的值,next是指向下一个节点的指针/引用。

如果是双向链表,则还需要属性prev以指示链表中的上一个节点。假设链表中的所有节点下标从0开始。

实现MyLinkedList类:

MyLinkedList() 初始化MyLinkedList对象。
int get(int index) 获取链表中下标为 index 的节点的值。如果下标无效,则返回 -1
void addAtHead(int val) 将一个值为 val 的节点插入到链表中第一个元素之前。在插入完成后,新节点会成为链表的第一个节点。
void addAtTail(int val) 将一个值为 val 的节点追加到链表中作为链表的最后一个元素。
void addAtIndex(int index, int val) 将一个值为 val 的节点插入到链表中下标为 index 的节点之前。如果 index 等于链表的长度,那么该节点会被追加到链表的末尾。如果 index 比长度更大,该节点将 不会插入 到链表中。
void deleteAtIndex(int index) 如果下标有效,则删除链表中下标为 index 的节点。

示例:
    输入
    ["MyLinkedList", "addAtHead", "addAtTail", "addAtIndex", "get", "deleteAtIndex", "get"]
    [[], [1], [3], [1, 2], [1], [1], [1]]
    输出
    [null, null, null, null, 2, null, 3]

解释
    MyLinkedList myLinkedList = new MyLinkedList();
    myLinkedList.addAtHead(1);
    myLinkedList.addAtTail(3);
    myLinkedList.addAtIndex(1, 2);    // 链表变为 1->2->3
    myLinkedList.get(1);              // 返回 2
    myLinkedList.deleteAtIndex(1);    // 现在,链表变为 1->3
    myLinkedList.get(1);              // 返回 3

提示:
    0 <= index, val <= 1000
    请不要使用内置的LinkedList库。
    调用get、addAtHead、addAtTail、addAtIndex 和 deleteAtIndex的次数不超过2000。

题解

解法一

思路:

主要注意的是边界处理,在遍历的时候如何取值

实现中全部使用了虚拟头节点dummyHead,确保逻辑统一

代码实现:

javascript

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

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

/** 
 * @param {number} index
 * @return {number}
 */
MyLinkedList.prototype.get = function(index) {
    // 检索index的合法性
    if(index < 0 || index >= this.size) return -1
    // 使用虚拟头节点 保证找的到index值是cur.next
    const dummyHead = new ListNode(0, this.head)
    let curNode = dummyHead
    while(index--) {
        curNode = curNode.next
    }
    return curNode.next.val
};

/** 
 * @param {number} val
 * @return {void}
 */
MyLinkedList.prototype.addAtHead = function(val) {
    const newNode = new ListNode(val, null)
    newNode.next = this.head
    this.head = newNode
    this.size++
    // 如果头部也是尾部元素的话 需要额外处理下
    if(this.size === 1) {
        this.head.next = null
    }
};

/** 
 * @param {number} val
 * @return {void}
 */
MyLinkedList.prototype.addAtTail = function(val) {
    const dummyHead = new ListNode(0, this.head)
    let curNode = dummyHead
    // 找到最后一个元素:while循环截止后,curNode此时就指向最后一个元素,curNode.next就是要插入的位置
    while(curNode.next !== null) {
        curNode = curNode.next
    }
    const newNode = new ListNode(val, null)
    curNode.next = newNode
    this.size++
    // 如果头部也是尾部元素的话 需要额外处理下
    if(this.size === 1) {
        this.head = newNode
    }
};

/** 
 * @param {number} index 
 * @param {number} val
 * @return {void}
 */
MyLinkedList.prototype.addAtIndex = function(index, val) {
    // 检索index的合法性
    if(index > this.size) return
    if(index === 0) {
        this.addAtHead(val)
        return
    }
    if(index === this.size) {
        this.addAtTail(val)
        return
    }
    // 要插入索引为index的位置 就要先找到index位置前面的节点
    // 使用虚拟头节点保证index位置是curNode.next 指向的位置
    const dummyHead = new ListNode(0, this.head)
    let curNode = dummyHead
    while(index--) {
        curNode = curNode.next
    }
    const newNode = new ListNode(val, null)
    newNode.next = curNode.next
    curNode.next = newNode
    this.size++
};

/** 
 * @param {number} index
 * @return {void}
 */
MyLinkedList.prototype.deleteAtIndex = function(index) {
    if(index < 0 || index >= this.size) return
    const dummyHead = new ListNode(0, this.head)
    // 使用虚拟头节点保证index位置是curNode.next指向的位置
    let curNode = dummyHead
    while(index--) {
        curNode = curNode.next
    }
    curNode.next = curNode.next.next
    this.head = dummyHead.next
    this.size--
};

/**
 * 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)
 */