48 阅读6分钟

# 链表算法整理

## 1.移除链表元素

• leetcode.cn/problems/re…

• ``````var removeElements = function(head, val) {
let pre = node
let cur = pre.next
while(cur!==null) {
if(cur.val === val){
console.log("pre",pre.val)
pre.next = cur.next
cur = cur.next
}else{
cur = cur.next
pre = pre.next
}
}
return node.next
};
``````

## 2.设计链表 （坑惨了）

• 下次一定要细心一点 诶

• ``````lass LinkNode {
constructer(val ,next){
this.val = val
this.next = next
}
}
this._size = 0
this._tail = null
};
constructor(val, next) {
this.val = val;
this.next = next;
}
}

/**
* Initialize your data structure here.
* 单链表 储存头尾节点 和 节点数量
*/
this._size = 0;
this._tail = null;
};
/**
* @param {number} index
* @return {number}
*/
if(index < 0 || index >= this._size) return -1;
// 获取当前节点
return this.getNode(index).val;
};

/**
* @param {number} val
* @return {void}
*/
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}
*/
const node = new LinkNode(val, null);
this._size++;
if(this._tail) {
this._tail.next = node;
this._tail = node;
return;
}
this._tail = node;
};

/**
* @param {number} index
* @param {number} val
* @return {void}
*/
if(index < 0 || index >= this._size) return null;
// 创建虚拟头节点
while(index-- >= 0) {
cur = cur.next;
}
return cur;
};
if(index > this._size) return;
if(index <= 0) {
return;
}
if(index === this._size) {
return;
}
// 获取目标节点的上一个的节点
const node = this.getNode(index - 1);
this._size++;
};

/**
* @param {number} index
* @return {void}
*/
if(index < 0 || index >= this._size) return;
if(index === 0) {
// 如果删除的这个节点同时是尾节点，要处理尾节点
if(index === this._size - 1){
}
this._size--;
return;
}
// 获取目标节点的上一个的节点
const node = this.getNode(index - 1);
node.next = node.next.next;
// 处理尾节点
if(index === this._size - 1) {
this._tail = node;
}
this._size--;
};
``````

## 3.反转链表

• leetcode.cn/problems/re…

• 依然是找到他的前一个节点就好了，双指针，但是不习惯使用递归方法，尝试使用

• ``````var reverseList = function(head) {

let pre = null
while(cur!==null) {
let temp = cur.next
cur.next = pre
pre = cur
cur = temp
}
return pre

};
//记得return喔！！！！！！！！！
function reverse(pre,cur) {
if(!cur) return pre
let temp = cur.next
cur.next = pre
return reverse(cur, temp)
}

};
``````

## 4.两两交换链表的节点

• leetcode.cn/problems/sw…

• ``````var swapPairs = function(head) {
let pre = node
while(pre.next&& pre.next.next) {
let cur1 = pre.next
let cur2 = pre.next.next
pre.next = cur2
cur1.next = cur2.next
cur2.next = cur1
pre = cur1
}

return node.next
};
``````

## 5.删除链表的倒数第N个节点

• leetcode.cn/problems/re…

• 使用双指针方法，倒数第几个元素就让 fast节点先走几步，然后同时移动fast，slow指针slow指针指向的就是要删除的节点的前一个节点，此题印象比较深刻之前做过。

• ``````var removeNthFromEnd = function(head, n) {
let pre = node
let rear = node
while(n>0){
n--
rear = rear.next
}
while(rear.next!== null) {
rear = rear.next
pre = pre.next
}
pre.next = pre.next.next
return node.next
};
```# 链表算法整理
``````

## 1.移除链表元素

• leetcode.cn/problems/re…

• ``````var removeElements = function(head, val) {
let pre = node
let cur = pre.next
while(cur!==null) {
if(cur.val === val){
console.log("pre",pre.val)
pre.next = cur.next
cur = cur.next
}else{
cur = cur.next
pre = pre.next
}
}
return node.next
};
``````

## 2.设计链表 （坑惨了）

• 下次一定要细心一点 诶

• ``````lass LinkNode {
constructer(val ,next){
this.val = val
this.next = next
}
}
this._size = 0
this._tail = null
};
constructor(val, next) {
this.val = val;
this.next = next;
}
}

/**
* Initialize your data structure here.
* 单链表 储存头尾节点 和 节点数量
*/
this._size = 0;
this._tail = null;
};
/**
* @param {number} index
* @return {number}
*/
if(index < 0 || index >= this._size) return -1;
// 获取当前节点
return this.getNode(index).val;
};

/**
* @param {number} val
* @return {void}
*/
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}
*/
const node = new LinkNode(val, null);
this._size++;
if(this._tail) {
this._tail.next = node;
this._tail = node;
return;
}
this._tail = node;
};

/**
* @param {number} index
* @param {number} val
* @return {void}
*/
if(index < 0 || index >= this._size) return null;
// 创建虚拟头节点
while(index-- >= 0) {
cur = cur.next;
}
return cur;
};
if(index > this._size) return;
if(index <= 0) {
return;
}
if(index === this._size) {
return;
}
// 获取目标节点的上一个的节点
const node = this.getNode(index - 1);
this._size++;
};

/**
* @param {number} index
* @return {void}
*/
if(index < 0 || index >= this._size) return;
if(index === 0) {
// 如果删除的这个节点同时是尾节点，要处理尾节点
if(index === this._size - 1){
}
this._size--;
return;
}
// 获取目标节点的上一个的节点
const node = this.getNode(index - 1);
node.next = node.next.next;
// 处理尾节点
if(index === this._size - 1) {
this._tail = node;
}
this._size--;
};
``````

## 3.反转链表

• leetcode.cn/problems/re…

• 依然是找到他的前一个节点就好了，双指针，但是不习惯使用递归方法，尝试使用

• ``````var reverseList = function(head) {

let pre = null
while(cur!==null) {
let temp = cur.next
cur.next = pre
pre = cur
cur = temp
}
return pre

};
//记得return喔！！！！！！！！！
function reverse(pre,cur) {
if(!cur) return pre
let temp = cur.next
cur.next = pre
return reverse(cur, temp)
}

};
``````

## 4.两两交换链表的节点

• leetcode.cn/problems/sw…

• ``````var swapPairs = function(head) {
let pre = node
while(pre.next&& pre.next.next) {
let cur1 = pre.next
let cur2 = pre.next.next
pre.next = cur2
cur1.next = cur2.next
cur2.next = cur1
pre = cur1
}

return node.next
};
``````

## 5.删除链表的倒数第N个节点

• leetcode.cn/problems/re…

• 使用双指针方法，倒数第几个元素就让 fast节点先走几步，然后同时移动fast，slow指针slow指针指向的就是要删除的节点的前一个节点，此题印象比较深刻之前做过。

• ``````var removeNthFromEnd = function(head, n) {
let pre = node
let rear = node
while(n>0){
n--
rear = rear.next
}
while(rear.next!== null) {
rear = rear.next
pre = pre.next
}
pre.next = pre.next.next
return node.next
};
``````

## 6.链表相交

• leetcode.cn/problems/in…

• 俩种思路：

• 使用set，把一条链表的节点全部加入到set中，然后看便利第二条链表

• 两条相交的链表尾部从相交开始就是一样的 也就是说两条链表的长度差一定小于交点之前的长度差。

平衡两条链表的长度，一起next即可找到交点

``````var getIntersectionNode = function(headA, headB) {
// let visited = new Set()
// }
// }
// return null

let len = 0
len++
}
return len
}
console.log(len1)
console.log(len2)
if(len1 < len2){
[len1,len2] = [len2,len1];

}
let sub = len1 - len2
console.log(sub)
while(sub > 0) {
sub--
}
}
return null
};
``````

## 7. 环形链表

• leetcode.cn/problems/li…

• 首先需要判断是否有环，此题印象比较深，一快一慢指针同时出发，如果有环一定可以相遇

• 其次找到环的起点：

• 借助一下随想录的图，假设fast的速度是slow的两倍，而且最终他们相遇了，且肯定还是在圆中，不然不可能相遇，基于这个情况下可以列出等式 2（x+y) = n(y+z) + x+y,那么x+y = n(y+z)
• 1.可能这个圈很大，那么n最小也就是1：x = y
• 2.可能这个圈很小，x = n(y+z) -z: 这个等式的意思就是再说一样的速度走的话，一个人a从x起点开始走，另一个b从他们的交点开始走，a走直线，b就是在圆中走，a走到环的入口处，b走了n个圆距离-y，b的起点是交点，交点-y还是入口处
• 所以可知找到交点 即可找到入口~！上代码
• ``````var detectCycle = function(head) {