203.移除链表元素
思路一:在原链表上直接删除
代码:
/**
* Definition for singly-linked list.
* function ListNode(val, next) {
* this.val = (val===undefined ? 0 : val)
* this.next = (next===undefined ? null : next)
* }
*/
/**
* @param {ListNode} head
* @param {number} val
* @return {ListNode}
*/
var removeElements = function(head, val) {
// 删除头结点
while (head !== null && head.val === val) {
head = head.next;
}
if (head === null) return head;
// 删除非头部节点
let pre = head, cur = head.next;
while (cur) {
if (cur.val === val) {
pre.next = cur.next;
} else {
pre = pre.next;
}
cur = cur.next;
}
return head;
};
思路二:创建虚拟头结点
代码:
/**
* Definition for singly-linked list.
* function ListNode(val, next) {
* this.val = (val===undefined ? 0 : val)
* this.next = (next===undefined ? null : next)
* }
*/
/**
* @param {ListNode} head
* @param {number} val
* @return {ListNode}
*/
var removeElements = function(head, val) {
// 创建虚拟头节点
const data = new ListNode(0, head);
// 删除节点
let cur = data;
while (cur.next) {
if (cur.next.val === val) {
cur.next = cur.next.next;
} else {
cur = cur.next;
}
}
return data.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;
};
/**
* @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);
// 查找 直到index减为0跳出循环
while (index >= 0) {
cur = cur.next;
index--;
}
return cur;
};
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;
// 链表为空的情况下,头结点也是尾结点
if (!this.tail) {
this.tail = node;
}
this.size++;
};
/**
* @param {number} val
* @return {void}
*/
MyLinkedList.prototype.addAtTail = function(val) {
// 创建要插入的新节点
const node = new LinkNode(val, null);
this.size++;
// 当tail指针不为空时,修改指针指向
if (this.tail) {
this.tail.next = node;
this.tail = node;
return;
}
// 当tail指针为空即链表为空时,头结点也是尾结点
this.head = node;
this.tail = node; // 尾指针始终指向链表最后一个结点
};
/**
* @param {number} index
* @param {number} val
* @return {void}
*/
// 在链表中的第 index个节点之前添加值为 val的节点。
// 如果 index等于链表的长度,则该节点将附加到链表的末尾。如果 index大于链表长度,则不会插入节点。如果 index小于0,则在头部插入节点。
MyLinkedList.prototype.addAtIndex = function(index, val) {
if (index === this.size) {
this.addAtTail(val);
return;
}
if (index > this.size) return;
if (index <= 0) {
this.addAtHead(val);
return;
}
// 正常情况
// 获取插入位置的前一个 node
const curNode = this.getNode(index-1);
// 新节点的指针指向当前插入位置的节点
let node = new LinkNode(val, curNode.next);
// 插入位置的前一个node的指针指向新节点
curNode.next = node;
this.size++;
};
/**
* @param {number} index
* @return {void}
*/
// 如果索引 index有效,则删除链表中的第 index个节点。
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;
node.next = null;
}
this.size--;
};
206.反转链表
思路:双指针法
代码:
/**
* Definition for singly-linked list.
* function ListNode(val, next) {
* this.val = (val===undefined ? 0 : val)
* this.next = (next===undefined ? null : next)
* }
*/
/**
* @param {ListNode} head
* @return {ListNode}
*/
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指针
pre = cur;
cur = temp;
}
// 此时temp = cur = null
return pre;
};