203. 移除链表元素
- 原链表上删除元素:需要注意的是删除头节点的操作和删除其他元素的操作是不一样的。判断完头节点后再从头节点向后依次遍历链表中元素。
/**
* @param {ListNode} head
* @param {number} val
* @return {ListNode}
*/
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;
};
- 设置一个虚拟头节点再进行删除操作:这种方式不用再考虑头节点的特殊性,因为设置了虚拟头节点,依次向后遍历链表元素即可了。
/**
* @param {ListNode} head
* @param {number} val
* @return {ListNode}
*/
var removeElements = function (head, val) {
let dummyHead = new ListNode(0, head);
let cur = dummyHead;
while (cur.next !== null) {
if (cur.next.val === val) {
cur.next = cur.next.next;
continue;
}
cur = cur.next;
}
return dummyHead.next;
707. 设计链表
这道题目设计链表的五个接口:
- 获取链表第index个节点的数值
- 在链表的最前面插入一个节点
- 在链表的最后面插入一个节点
- 在链表第index个节点前面插入一个节点
- 删除链表的第index个节点
首先要确定链表在JavaScript中的定义,构造一个ListNode类,再构造一个MyLinkedList类:
class LinkNode {
constructor(val, next) {
this.val = val;
this.next = next;
}
}
var MyLinkedList = function () {
this._size = 0;
this._head = null;
this._tail = null;
};
注意:
① index是从0开始还是从1开始;
② 头节点和尾节点的指定;
③ 链表元素个数,是否只有一个元素。
下面是具体的操作(先定义了一个获取index位置节点的函数,方便之后的操作):
/**
* Get the value of the index-th node in the linked list. If the index is invalid, return -1.
* @param {number} index
* @return {number}
*/
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;
const node = this.getNode(index);
if (index === 0) {
this._head = this._head.next;
if (index === this._size - 1) {
this._tail = this._head;
}
this._size--;
return;
}
let cur = this.getNode(index - 1);
cur.next = cur.next.next;
if (index === this._size - 1) {
this._tail = cur;
}
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)
*/
206. 反转链表
- 双指针法:因为要反转链表,所以当前元素的next指针就要指向它的前一个元素。由此首先定义一个cur指针,指向头结点,再定义一个pre指针,初始化为null。然后就要开始反转了,首先要把 cur->next 节点用tmp指针保存一下,也就是保存一下这个节点。
/**
* @param {ListNode} head
* @return {ListNode}
*/
var reverseList = function(head) {
let cur = head;
let pre = null;
while(cur){
temp = cur.next;
cur.next = pre;
pre = cur;
cur = temp;
}
return pre;
};
- 递归法:根据循环来写递归。同样是当cur为空的时候循环结束,不断将cur指向pre的过程。
/**
* @param {ListNode} head
* @return {ListNode}
*/
var reverseList = function(head) {
return reverse(head, null);
};
var reverse = function(cur, pre){
if(!cur) return pre;
let temp = cur.next;
cur.next = pre;
return reverse(temp, cur);
}