两两交换链表中的的节点
主要思路:
- 操作两个节点一定要使当前指针在节点前一个
- 用变量先接收将来会被断联系的节点
- 先将下一个作为2,2后面接1,1后面接3如此循环
- 因为每次跳两个节点,所以current.next&¤t.next.next不能为空
- current往后移动两个节点
- 最后返回虚拟头结点的next
完整代码
/**
* 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 swapPairs = function(head) {
let virtualNode = new ListNode(0,head)
let current = virtualNode
let temp1=null
let temp2=null
while(current.next&¤t.next.next){
temp1=current.next
temp2=current.next.next.next
current.next = current.next.next
current.next.next=temp1
current.next.next.next=temp2
current=current.next.next
}
return virtualNode.next
};
删除链表的倒数第N个节点
主要思路:
- 利用双快慢指针,快指针先移动n步,快慢指针再一起移动直到快指针到头,此时快慢指针正好相差n步,而快指针又在链尾,慢指针就在倒数第n个
完整代码
/**
* 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} n
* @return {ListNode}
*/
var removeNthFromEnd = function(head, n) {
let vhead = new ListNode(0,head)
let currentSlow =vhead
let fast =vhead
// fast先移动
while(n > 0){
fast = fast.next
n--
}
// fast与slow一起移动
while(fast.next){
currentSlow=currentSlow.next
fast=fast.next
}
console.log(fast.val,currentSlow.val)
// 最后进行删除操作
currentSlow.next = currentSlow.next.next
return vhead.next
};
环形链表2
主要思路:
- 此题实际上一道初中追逐问题
- 转换成数学模型可以得出slow在第一圈一定会被快他一倍的fast追上,同时又因为后半圈一z定会等于slow进入圈走的x
完整代码:
/**
* Definition for singly-linked list.
* function ListNode(val) {
* this.val = val;
* this.next = null;
* }
*/
/**
* @param {ListNode} head
* @return {ListNode}
*/
var detectCycle = function(head) {
if(!head||!head.next) return null
let slow = head.next
let fast = head.next.next
while(fast&&fast.next){
slow = slow.next
fast=fast.next.next
if(slow===fast){
slow = head//找到x+y
while(slow!==fast){//从头再走x步,又因为x=z所以slow=fast时就是入口
slow=slow.next
fast=fast.next
}
return slow
}
}
return null
};