参考文章与视频
链表理论基础:代码随想录 (programmercarl.com)
?定义链表:
class ListNode {
constructor (val) {
this.val = val;
this.next = null;
}
}
题目一:203.移除链表元素
题目描述
删除链表中等于给定值 val 的所有节点。
示例 1: 输入:head = [1,2,6,3,4,5,6], val = 6 输出:[1,2,3,4,5]
示例 2: 输入:head = [], val = 1 输出:[]
示例 3: 输入:head = [7,7,7,7], val = 7 输出:[]
第一思路
创建一个节点指向链表头部,如果当前节点的下一节点与给定val相等的节点就删除当前节点的下一节点。最后返回newNode.next。
var removeElements = function(head, val) {
let newHead = new ListNode(-1);
newHead.next = head;
let cur = newHead;
while(cur.next) {
if(cur.next.val == val) {
cur.next = cur.next.next;
}else{
cur = cur.next;
}
}
return newHead.next;
};
看完讲解
个人感觉直接声明一个节点指向链表头部操作起来更简便,因此不考虑另一种方法。
题目二:707.设计链表
题目描述
在链表类中实现这些功能:
- get(index):获取链表中第?index?个节点的值。如果索引无效,则返回-1。
- addAtHead(val):在链表的第一个元素之前添加一个值为?val?的节点。插入后,新节点将成为链表的第一个节点。
- addAtTail(val):将值为?val 的节点追加到链表的最后一个元素。
- addAtIndex(index,val):在链表中的第?index?个节点之前添加值为?val? 的节点。如果?index?等于链表的长度,则该节点将附加到链表的末尾。如果 index 大于链表长度,则不会插入节点。如果index小于0,则在头部插入节点。
- deleteAtIndex(index):如果索引?index 有效,则删除链表中的第?index 个节点。
看完讲解
这个看起来简单,但是要考虑全面,index=0;index=this.size;index>0等等情况。
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--;
};
题目三:206.反转链表
题目描述
题意:反转一个单链表。
示例: 输入: 1->2->3->4->5->NULL 输出: 5->4->3->2->1->NULL
第一思路
我们可以每次遍历到最后取节点但是这样时间复杂度肯定很高。我们需要实现原地反转。首先需要设置一个节点指向链表的头部,接下来遍历这个链表。同时设置两个指针,p1,p2。p1指向当前 节点,p2指向当前节点的下一节点。我们令p2指向p1就可以实现局部反转。
var reverseList = function(head) {
if(!head) return null;
let newHead = new ListNode(-1,head);
let p1 = head;
let p2 = head.next;
while(p2) {
p1.next = p2.next;
p2.next = newHead.next;
newHead.next = p2;
p2 = p1.next;
}
return newHead.next;
};
|