第四天——链表(24. 两两交换链表中的节点 ,19.删除链表的倒数第N个节点,160. 链表相交,142.环形链表II

Tags
链表

24. 两两交换链表中的节点

学习链接

notion image

个人思路

还是用虚拟节点,
notion image
  1. cur→cur.next.next
  1. cur.next.next→cur.next
  1. cur移动

解题代码

/** * 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 dummy = new ListNode(null) dummy.next = head let cur = dummy while(cur.next && cur.next.next){ let two = cur.next.next let one = cur.next one.next = two.next cur.next = two two.next = one cur = one // 注意这里是跳到下一位,而不是cur.next } return dummy.next };
按图解释没啥问题
 

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

学习链接

个人想法

这道题只需要slow、fast双指针,中间间隔是n(拿到删除节点的上一个节点),然后到fast.next为空结束遍历,然后处理slow节点的删除即可+
 

解题代码

/** * 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 dummy = new ListNode(0,head) let slow = dummy let fast = dummy for(let i = 0; i < n; i++){ fast = fast.next } while(fast.next){ slow = slow.next fast = fast.next } slow.next = slow.next.next return dummy.next };
 

160. 链表相交

学习链接

个人思路

如果相交,这两个链表必然结尾相连,计算两个链表长度差,直到两个长度相同,然后比较val相同,next相同,证明相交

解题代码

 
/** * Definition for singly-linked list. * function ListNode(val) { * this.val = val; * this.next = null; * } */ const getLength = (head)=>{ let length = 0 let cur = head while(cur){ cur = cur.next length ++ } return length } /** * @param {ListNode} headA * @param {ListNode} headB * @return {ListNode} */ var getIntersectionNode = function(headA, headB) { let lengthA = getLength(headA) let lengthB = getLength(headB) if(lengthA < lengthB){ // 如果A比B短,交换A、B [headA, headB] = [headB , headA]; [lengthA, lengthB] = [lengthB, lengthA]; } let diff = lengthA - lengthB while(diff){ headA = headA.next diff -- } while(headA && headB){ if(headA === headB){ return headA } headA = headA.next headB = headB.next } return null };
 

142.环形链表II

 

学习链接

 

个人想法

这道题一开始没什么思路,直接看文章学习,发现是一个数学问题,使用双指针,fast一次走两步,slow一次走一步,如果有环必然在环内相交(追击问题)
 
notion image
但是怎么着环的入口呢
notion image
我们发现 如果相遇,slow必然走了x+y,fast走x+y+n*(y+z) (多走n圈)
所以就是 2(x + y) = x + y + n(y + z) => x + y = n(y + z)
因为我们要求x值,所以 x = N个环长度 - y
所以 如果在头结点设置一个指针index1,相遇节点设置一个index2 ,每次都走一步,两者必然在入口相交
因为x = N个环长度 - y 走完x 必然是一圈少y,我们从相遇节点出发,刚好走到环形入口节点
 

解题代码

/** * 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){ // 找到相遇节点,开始计算 let temp = slow let cur = head while(temp !== cur){ // 一直找到两个节点相等返回值 temp = temp.next cur = cur.next } return temp } } return null };
很巧妙的数学问题,要多学习