代码随想录算法训练营第三天| 链表

32 阅读2分钟

LeetCode 203.移除链表元素

📖 考察点

链表理解

📖 题意理解

删除链表中值为val的节点,返回新的头结点

💡 解题思路

虚拟头结点

思路一:

思路二:

🔑 关键点总结

💻 代码实现

JavaScript

var removeElements = function(head, val) {
    const ret = new ListNode(0,head);
    let cur = ret;
    while(cur.next){
        if(cur.next.val === val){
            cur.next =  cur.next.next;
            continue;
        }
        cur = cur.next;
    }
    return ret.next;
};

Rust

pub fn remove_elements(head: Option<Box<ListNode>>, val: i32) -> Option<Box<ListNode>> {
	let mut dummy = Box::new(ListNode{val:0,next:head});
	let mut curr = &mut dummy;
	while let Some(next_node) = &mut curr.next {
		if next_node.val ==val {
			curr.next = next_node.next.take();
		}else {
			curr = curr.next.as_mut().unwrap();
		}
	}
	dummy.next
}

⏱️ 复杂度分析

📚 总结与反思

什么情况应该使用虚拟头结点?(增删改)


LeetCode 206.反转链表

📖 考察点

链表理解

📖 题意理解

反转链表的节点

💡 解题思路

思路一:存数组,然后重新连接

思路二:通过记录前后节点,改变指针的指向

🔑 关键点总结

💻 代码实现

JavaScript

var reverseList = function(head) {
    if(!head||!head.next)return head;
    let pre = null,cur = head,temp =null;
    while(cur){ 
        temp = cur.next;
        cur.next = pre;
        pre = cur;
        cur = temp;
    }
    return pre;
};

Rust

pub fn reverse_list(head: Option<Box<ListNode>>) -> Option<Box<ListNode>> {
    if head.is_none() || head.as_ref().unwrap().next.is_none(){
			return head;
		}
		let mut pre: Option<Box<ListNode>> = None;
		let mut cur = head;
		while let Some(mut node) = cur.take() {
			cur = node.next.take();
			node.next = pre;
			pre = Some(node);
		}
		pre
}

⏱️ 复杂度分析

📚 总结与反思

Option<T> 的 take() 方法是一个非常实用的方法,它的核心作用是取出 Option 中的值(将其从原 Option 中移走),并在原位置留下 None

用通俗的话讲,take() 就像 "拿走" Option 里的内容,同时把原容器清空(设为 None)。


LeetCode 707.设计链表

📖 考察点

链表基础

📖 题意理解

💻 代码实现

JavaScript

class LinkNode {
    constructor(val, next) {
        this.val = val;
        this.next = next;
    }
}



var MyLinkedList = function(val,next) {
    this._size = 0;
    this._tail = null;
    this._head = null;
};
MyLinkedList.prototype.getNode = function(index) {
    if(index < 0 || index >= this._size) return null;
    // 创建虚拟头节点
    let cur = new LinkNode(0, this._head);
    // 0 -> head
    while(index-- >= 0) {
        cur = cur.next;
    }
    return cur;
};


/** 
 * @param {number} index
 * @return {number}
 */
MyLinkedList.prototype.get = function(index) {
    if(index<0||index>=this._size)return -1;
    return this.getNode(index).val
};

/** 
 * @param {number} val
 * @return {void}
 */
MyLinkedList.prototype.addAtHead = function(val) {
    const node = new LinkNode(val,this._head);
    this._head = node;
    this._size++;
    if(!this._tail){
        this._tail = node;
    }
};

/** 
 * @param {number} val
 * @return {void}
 */
MyLinkedList.prototype.addAtTail = function(val) {
    const node = new LinkNode(val,null);
    this._size++;
    if(this._tail){
        this._tail.next = node;
        this._tail = node;
        return;
    }
    this._tail = node;
    this._head = node;
};

/** 
 * @param {number} index 
 * @param {number} val
 * @return {void}
 */
MyLinkedList.prototype.addAtIndex = function(index, val) {
    if(index>this._size)return;
    if(index<=0){
        this.addAtHead(val);
        return;
    }
    if(index === this._size) {
        this.addAtTail(val);
        return;
    }
    const node = this.getNode(index-1);
    node.next = new LinkNode(val,node.next);
    this._size++;
};

/** 
 * @param {number} index
 * @return {void}
 */
MyLinkedList.prototype.deleteAtIndex = function(index) {
    if(index<0 || index>=this._size)return;
    if(index===0){
        this._head=this._head.next;
        if(index === this._size-1){
            this._tail = this._head
        }
        this._size--;
    return;
    }
    const node = this.getNode(index-1);
    node.next = node.next.next;
    if(index === this._size-1){
        this._tail = node;
    }
    this._size--;

};


⏱️ 复杂度分析

📚 总结与反思