24 两两交换链表中的节点
题目链接/文章讲解/视频讲解: https://programmercarl.com/0024.%E4%B8%A4%E4%B8%A4%E4%BA%A4%E6%8D%A2%E9%93%BE%E8%A1%A8%E4%B8%AD%E7%9A%84%E8%8A%82%E7%82%B9.html
注意:
1.设置虚拟头节点
2.while循环的条件(两个条件顺序不可变,一旦顺序改变,容易导致空指针异常)
3.具体交换节点的顺序
4.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 dummyHead = new ListNode(0,head);
let cur = dummyHead;
while(cur.next !== null && cur.next.next !== null){
let temp = cur.next;
let temp1 = cur.next.next.next;
cur.next = cur.next.next;
cur.next.next = temp;
temp.next = temp1;
cur = cur.next.next;
}
return dummyHead.next;
};
19 删除链表的倒数第N个节点
题目链接/文章讲解/视频讲解:https://programmercarl.com/0019.%E5%88%A0%E9%99%A4%E9%93%BE%E8%A1%A8%E7%9A%84%E5%80%92%E6%95%B0%E7%AC%ACN%E4%B8%AA%E8%8A%82%E7%82%B9.html
方法一:自己写的
有点笨拙的方法,先计算链表长度,再计算pre,cur的索引下标应该是多少,再遍历到preNode和curNode的对应位置,进行移除元素。一开始没设置虚拟头节点,如果删除的是第一个元素则删不掉。
/**
* 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 dummyHead = new ListNode(0,head);
let temp = head;
let length = 0;
while(temp !== null){
length++;
temp = temp.next;
}
let pre = length - n - 1;
let cur = length - n;
let preNode = dummyHead,curNode = dummyHead;
while(pre-- >= 0){
preNode = preNode.next;
}
while(cur-- >= 0){
curNode = curNode.next;
}
preNode.next = curNode.next;
return dummyHead.next;
};
较上面的方法省略了curNode
/**
* 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 dummyHead = new ListNode(0,head);
let temp = head;
let length = 0;
while(temp !== null){
length++;
temp = temp.next;
}
let pre = length - n - 1;
// let cur = length - n;
let preNode = dummyHead;
while(pre-- >= 0){
preNode = preNode.next;
}
// while(cur-- >= 0){
// curNode = curNode.next;
// }
preNode.next = preNode.next.next;
return dummyHead.next;
};
方法二:快慢指针
fast先走n步;当fast.next 指向空之前,slow和fast一起移动。
/**
* 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 dummyHead = new ListNode(0,head);
let fast = dummyHead,slow = dummyHead;
while(n--){
fast = fast.next;
}
while(fast.next !== null){
slow = slow.next;
fast = fast.next;
}
slow.next = slow.next.next;
return dummyHead.next;
};
较上一个快慢指针,更改了条件判断(fast先走了n+1步,fast指向空时即停)
/**
* 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 dummyHead = new ListNode(0,head);
let fast = dummyHead,slow = dummyHead;
while(n-- >= 0){
fast = fast.next;
}
while(fast !== null){
slow = slow.next;
fast = fast.next;
}
slow.next = slow.next.next;
return dummyHead.next;
};
02.07 链表相交
题目链接/文章讲解:https://programmercarl.com/%E9%9D%A2%E8%AF%95%E9%A2%9802.07.%E9%93%BE%E8%A1%A8%E7%9B%B8%E4%BA%A4.html
/**
* Definition for singly-linked list.
* function ListNode(val) {
* this.val = val;
* this.next = null;
* }
*/
/**
* @param {ListNode} headA
* @param {ListNode} headB
* @return {ListNode}
*/
//求链表长度的函数
var getListLen = function(head){
let length = 0,cur = head;
while(cur){
length++;
cur = cur.next;
}
return length;
}
var getIntersectionNode = function(headA, headB) {
let curA = headA,curB = headB;
let lengthA = getListLen(headA);
let lengthB = getListLen(headB);
//让curA是最长链表的头节点
if(lengthA < lengthB){
[curA,curB] = [curB,curA];
[lengthA,lengthB] = [lengthB,lengthA];
}
let i = lengthA - lengthB;
// 让curA和curB在同一起点上(末尾位置对齐)
while(i--){
curA = curA.next;
}
// 遍历curA 和 curB,遇到相同则直接返回
while(curA && curA !== curB){
curA = curA.next;
curB = curB.next;
}
return curA;
};
142 环形链表Ⅱ
题目链接/文章讲解/视频讲解:https://programmercarl.com/0142.%E7%8E%AF%E5%BD%A2%E9%93%BE%E8%A1%A8II.html
/**
* 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 fast = head,slow = head;
while(fast !== null && fast.next !== null){
fast = fast.next.next;
slow = slow.next;
//快慢指针相遇了,代表有环
if(fast === slow){
index1 = fast;
index2 = head;
while(index1 !== index2){
index1 = index1.next;
index2 = index2.next;
}
return index1;
}
}
return null;
};
注意:本题主要考察什么时候才是快慢指针相遇的时候,可以看视频讲解。