这是跟着代码随想录的顺序学习算法的第五天。
因为后续打算往前端方向发展,所以开始改用JS刷题了。
以下是学习题解时自己的一些理解与笔记,有错误欢迎指正与讨论。
链表
参考相关链接:
203. 移除链表元素
707. 设计链表
代码随想录
笔记
- 链表的
head
需要特别注意,是否能够被操作到,可以增加虚节点,同时也要注意最后的返回结果可能会受虚节点影响。 - 注意
index
是从0
开始还是从1
开始。
链表定义:
class ListNode {
constructor(value, next) {
this.val = value;
this.next = next;
}
}
203. 移除链表元素
增加一个虚拟头节点 ret
,此时原链表的入口就变成了 ret.next
, 接着,增加一个新的变量 cur
,用变量通过链表的入口来历遍链表,遇到 val
,就删除节点,否则就往下历遍。
添加虚拟节点
var removeElements = function(head, val) {
const ret = new ListNode(0, head); // const
let cur = ret; // let
while(cur.next) {
if(cur.next.val === val) {
cur.next = cur.next.next;
continue;
}
cur = cur.next;
}
return ret.next;
};
707. 设计链表
注意尾指针添加新尾部节点需要先让新节点连上链表,再让尾指针指向新节点。
MyLinkedList.prototype.addAtTail = function(val) {
const node = new LinkNode(val, null);
this._size++;
if(this._tail) {
this._tail.next = node; // _tail.next 需要先指向 node 才能把 node 连接到链表中
this._tail = node; // 使得_tail 指向链表末尾
return;
}
this._tail = node;
this._head = node;
};
代码随想录的 JS
版本:
class LinkNode {
constructor(val, next) {
this.val = val;
this.next = next;
}
}
/**
* Initialize your data structure here.
* 单链表 储存头尾节点 和 节点数量
*/
var MyLinkedList = function() {
this._size = 0;
this._tail = null;
this._head = null;
};
/**
* 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;
};
MyLinkedList.prototype.get = function(index) {
if(index < 0 || index >= this._size) return -1;
// 获取当前节点
return this.getNode(index).val;
};
/**
* Add a node of value val before the first element of the linked list. After the insertion, the new node will be the first node of the linked list.
* @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;
}
};
/**
* Append a node of value val to the last element of the linked list.
* @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;
};
/**
* Add a node of value val before the index-th node in the linked list. If index equals to the length of linked list, the node will be appended to the end of linked list. If index is greater than the length, the node will not be inserted.
* @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++;
};
/**
* Delete the index-th node in the linked list, if the index is valid.
* @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--;
};