203 移除链表元素
题目
求解
借助虚拟头节点,找到满足条件的节点,并进行删除
var removeElements = function(head, val) { const dummyHead = new ListNode(0); dummyHead.next= head; let tmp = dummyHead; while(tmp.next !== null){ if(tmp.next.val==val){ tmp.next=tmp.next.next; }else{ tmp=tmp.next; } } return dummyHead.next; };
707 设计链表
题目
求解
定义节点
每个节点包含数据和指向下个节点的指针
class LinkNode{ constructor(val,next){ this.val=val; this.next=next; } }
定义单链表
包含链表的长度,链表的头、尾节点
// 单链表 var MyLinkedList = function() { // this._size=0; this._head=null; this._tail=null; };
获取索引为index的节点
题目中不要求改功能,但借助该函数可减少后续代码量
-
首先需要判断index是否合法,为负值或者超出链表范围则返回null
-
借助虚拟头节点,寻找第index个节点
MyLinkedList.prototype.getNode = function(index){ if(index<0||index>=this._size){ return null; } let tmp = new LinkNode(0,this._head); while(index-->=0){ tmp=tmp.next; } return tmp; }
获取索引为index的节点的值
借助getNode函数,可快速找到该节点并返回数据
MyLinkedList.prototype.get = function(index) { if(index<0||index>=this._size)return -1; return this.getNode(index).val; };
在头部插入值为val的节点
设计一个值为val的节点,将它作为新的头节点,将它的下一个节点指向原头节点,同时更新链表长度
const node = new LinkNode(val,this._head); this._head = node; this._size++;
需要特别考虑:
-
原链表为空时,head和tail均为null,新插入的节点既是头节点也是尾节点
MyLinkedList.prototype.addAtHead = function(val) { // 在头部插入一个元素 并更新头节点,链表长度,如果原列表为空更新尾节点 const node = new LinkNode(val,this._head); // 插入 this._head = node; this._size++; if(!this._tail){ //没有尾节点 this._tail=node; } };
在尾部插入值为val的节点
设计一个值为val的节点,将它插到尾节点之后,并作为新的头尾点,同时更新链表长度
需要特别考虑:
-
当原链表为空时,tail为null,新节点既是尾节点也是头节点
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; };
在链表中的第 index
个节点之前添加值为 val
的节点
如果 index
等于链表的长度,则该节点将附加到链表的末尾。如果 index
大于链表长度,则不会插入节点。如果index
小于0,则在头部插入节点。
-
当
index>this._size
,不插入节点 -
当
index<=0
,addAtHead(val) -
当
index=this._size
,addAtTail -
当
0<index<this._size
,找到index的前一个节点并在后面插入新的节点
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++; };
删除索引为index的节点
-
首先判断index是否合法,若不合法无需操作
-
index=0
时,对头节点进行更新。同时index=this._size-1
时,也是尾节点,对尾节点也进行更新 -
index!==0
时,找到index-1
个节点,删除它的后一个节点,如果index=this._size-1
对尾节点进行更新 -
this._size--
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 prenode = this.getNode(index-1); prenode.next=prenode.next.next; if(index===this._size-1){ this._tail = prenode; } this._size--; };
206反转链表
题目
求解
定义指针cur
来进行遍历链表,定义新的头指针prev
作为反转后链表的头节点
var reverseList = function(head) { // 对每个节点来说,下一个节点变成上一个 // 定义cur表示当前节点,另他的下一个节点指向当前节点,不要让后面的节点丢失 let prev = null; let cur = head; while(cur){ const next = cur.next; cur.next = prev ; prev = cur; cur = next; } return prev; };