代码随想录算法训练营第三天 | 203.移除链表元素、707.设计链表、206.反转链表

52 阅读2分钟

我正在参加「掘金·启航计划」

203.移除链表元素

代码随想录移除链表元素 (programmercarl.com)

自己看到题目的第一想法

删除链表中元素很简单,但是太久没有刷题了。居然忘了怎么建立链表节点。

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

思路也是十分简单的,遍历节点,如果节点的下一个节点值为val,那么就将next指向下一个节点的下一个节点。建立虚拟头节点便于让头节点与其他的节点保持同样的处理逻辑(这个一刷时用到了,就记住了)

自己实现过程中遇到哪些困难

自己运行的时候第一次出错了,发现把cur = cur.next写进if判断外了,也就是所有循环都会执行。

707.设计链表

自己看到题目的第一想法

当时就是想着这么多方法一个一个实现,题目看起来并不困难,但是实践起来就会发现,需要考虑的情况有很多。

  1. 获取节点值时索引无效的情况(索引为负或索引超过链表长度)
  2. addAtHead时链表没有元素的情况
  3. addAtTail时链表没有元素的情况
  4. addAtIndex的三种情况
  5. deleteAtIndex时索引无效的情况以及删头节点的情况

看完代码随想录之后的想法

看完题解后发现题目还能更简洁,可以封装一个getNode函数,用于获取index的节点,这样很多地方都可以不用重复逻辑了。

自己实现过程中遇到哪些困难

完成整个代码后提交执行

image.png

不出意外出错了,在明确node.next = new LinkNode(val,node.next)创建新节点的方法没有错误后,我开始找制造函数,结果发现是construct拼错了(其实是中午休息了一个小时后再找到的)

206.反转链表

双指针方法实现

通过定义两个指针,实现反转。在使用一个临时变量储存下一个节点。

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

实现起来还是比较简单的,注意一下临界点的判断就好了。

看完代码随想录之后的想法

又多了一种解法——递归法!

递归法的逻辑与双指针法相似,但是最好还是要画图理解。一开始没有理解head为什么可以作为结束的判断,后来发现传参是不一样的。

总结

今天刷了三个链表相关的题,1,3比较简单。2主要是要考虑的东西很多,很容易出错。明天要独立再做一遍!