代码随想录的第四天
24. 两两交换链表中的节点
var swapPairs = function(head) {
let ret = new ListNode(0, head), temp = ret;
while (temp.next && temp.next.next) {
let temp1 = temp.next
let temp2 = temp.next.next.next
temp.next = temp.next.next
temp.next.next = temp1
temp1.next = temp2
temp = temp.next.next
}
return ret.next;
};
思路:
1、定义一个虚拟头节点,然后进行遍历(需要判断的是下一个节点和下下个节点,因为如果是奇数则不需要再次交换)
2、首先是虚拟节点指向第二个节点(注意,后续第二个节点需要指向第一个节点,指向第一个节点的链表需要临时保存),此时,temp.next就是第二个节点,然后第二个节点指向第一个节点(同理,保存指向第三个节点的链表),然后第一个节点(临时保存的节点)指向第三个节点,完成然后当前节点向后移动两位
19. 删除链表的倒数第 N 个结点
var removeNthFromEnd = function(head, n) {
let cur = new ListNode(0, head)
let fast = slow = cur
while (n >= 0) {
fast = fast.next
n--
}
while (fast) {
slow = slow.next
fast = fast.next
}
slow.next = slow.next.next
return cur.next
};
思路:
1、定义一个虚拟节点,然后定义两个快慢指针
2、首先先将快指针走出去n步,然后快慢指针一起走,直到快指针走到null,说明慢指针的下一个就是要删除的节点
面试题 02.07. 链表相交
/**
* Definition for singly-linked list.
* function ListNode(val) {
* this.val = val;
* this.next = null;
* }
*/
/**
* @param {ListNode} headA
* @param {ListNode} headB
* @return {ListNode}
*/
var getIntersectionNode = function(headA, headB) {
let curA = headA,curB = headB
let lenA = getLeng(curA)
let lenB = getLeng(curB)
if (lenA < lenB) {
[curA, curB] = [curB, curA];
[lenA, lenB] = [lenB, lenA]
}
let len = lenA - lenB
for (let i = 0; i < len; i++) {
curA = curA.next
}
while(curA && curA !== curB) {
curA = curA.next;
curB = curB.next;
}
return curA;
};
function getLeng (cur) {
let size = 0, head = cur
while (head) {
head = head.next
size++
}
return size
}
思路:
1、如果链表相交,那么相交后的长度和内容是一致的
2、所以,算出两个链表的长度差,然后更长的那个先走完长度差,然后开始一起走,遇到相同的即是相交的点,进行返回
142. 环形链表 II
var detectCycle = function(head) {
let slow = head
let fast = head
while (fast && fast.next) {
fast = fast.next.next
slow = slow.next
if (slow == fast) {
// 有环
let index1 = fast
let index2 = head
while (index1 !== index2) {
index1 = index1.next
index2 = index2.next
}
return index1
}
}
return null
};
思路:
1、首先先利用快慢指针证明有环存在
2、其次,环第一次相交的位置到环的入口和起始节点到环的入口的位置距离相同(不相同就一直跳过就行)