代码随想录day4打卡
24两两交换链表中的节点
24两两交换链表中的节点
给你一个链表,两两交换其中相邻的节点,并返回交换后链表的头节点。你必须在不修改节点内部的值的情况下完成本题(即只能进行节点交换)。
这道题不难,常规方法就是维护多个指针,遍历一遍链表顺便把每两个节点翻转。不过迭代的思路虽然直接,但细节问题会比较多,写起来麻烦。
所以我直接用递归的方式来写,只要搞明白递归函数的定义,然后利用这个定义就可以完成这道题。
var swapPairs = function(head) {
//思路:递归
if(head == null || head.next == null) return head;
let next = head.next;
head.next = swapPairs(next.next);
next.next = head;
return next;
};
var swapPairs = function(head) {
//思路:非递归
let dummyHead = new ListNode(0);
dummyHead.next = head;
let cur = dummyHead;
while(cur.next && cur.next.next){
let next = cur.next.next;
cur.next.next = next.next;
next.next = cur.next;
cur.next = next;
cur = cur.next.next;
}
return dummyHead.next;
}
19删除链表的倒数第N个节点
19删除链表的倒数第N个节点
给你一个链表,删除链表的倒数第 n 个结点,并且返回链表的头结点。
要删除倒数第 n 个节点,就得获得倒数第 n + 1 个节点的引用。
获取单链表的倒数第 k 个节点,就是想考察 双指针技巧 中快慢指针的运用,一般都会要求你只遍历一次链表,就算出倒数第 k 个节点。
var removeNthFromEnd = function(head, n) {
//思路:双指针
let dummyHead = new ListNode(0);
dummyHead.next = head;
let fast = dummyHead;
let slow = dummyHead;
while(n--){
fast = fast.next;
}
while(fast.next){
fast = fast.next;
slow = slow.next;
}
slow.next = slow.next.next;
return dummyHead.next;
}
面试题0207链表相交
0207链表相交
给你两个单链表的头节点 headA 和 headB ,请你找出并返回两个单链表相交的起始节点。如果两个链表没有交点,返回 null 。
var getIntersectionNode = function(headA, headB) {
//思路:双指针
let pA = headA, pB = headB;
while(pA != pB){ //如果相交,最后一定会相等
pA = pA == null ? headB : pA.next;
pB = pB == null ? headA : pB.next;
}
return pA;
}
142环形链表II
142环形链表
给定一个链表的头节点 head ,返回链表开始入环的第一个节点。 如果链表无环,则返回 null。
如果链表中有某个节点,可以通过连续跟踪 next 指针再次到达,则链表中存在环。 为了表示给定链表中的环,评测系统内部使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。如果 pos 是 -1,则在该链表中没有环。注意:pos 不作为参数进行传递,仅仅是为了标识链表的实际情况。
不允许修改 链表。
var detectCycle = function(head) {
let slow = head, fast = head;
while(fast != null && fast.next != null) {//快慢指针
slow = slow.next;//慢指针走一步
fast = fast.next.next;//快指针走两步
if(slow == fast) {//如果快慢指针相遇
let pre = head;//pre指向头节点
while(pre != slow) {//遍历链表
pre = pre.next;//pre走一步
slow = slow.next;//slow走一步
}
return pre;//返回pre
}
}
return null
}