学习目标:
- 24. 两两交换链表中的节点
- 19.删除链表的倒数第N个节点
- 面试题 02.07. 链表相交
- 142.环形链表II
解题记录:
24. 两两交换链表中的节点
虚拟头节点法
class Solution {
public ListNode swapPairs(ListNode head) {
//设置一个虚拟头结点,指向head
ListNode dummyHead = new ListNode(-1, head);
ListNode cur = dummyHead;//定义一个指针指向虚拟头节点
while(cur.next != null && cur.next.next != null) {//顺序不能反,否则会报空指针异常
ListNode tmp = cur.next.next.next;// 临时节点,保存两个节点后面的节点
ListNode firstNode = cur.next;// 临时节点,保存两个节点之中的第一个节点
ListNode secondNode = cur.next.next;// 临时节点,保存两个节点之中的第二个节点
cur.next = secondNode; // 步骤一
secondNode.next = firstNode;// 步骤二
firstNode.next = tmp; // 步骤三
cur = cur.next.next; // cur移动,准备下一轮交换
}
return dummyHead.next;
}
}
递归法
class Solution {
public ListNode swapPairs(ListNode head) {
//递归法
if(head == null || head.next == null) {
return head;
}
// 获取当前节点的下一个节点
ListNode next = head.next;
ListNode newNode = swapPairs(next.next);
// 这里进行交换
next.next = head;
head.next = newNode;
return next;
}
}
19.删除链表的倒数第N个节点
双指针法
class Solution {
public ListNode removeNthFromEnd(ListNode head, int n) {
//双指针法(快慢指针)
ListNode dummyHead = new ListNode(-1, head);
//快慢指针初始指向虚拟头节点
ListNode fastNode = dummyHead;
ListNode slowNode = dummyHead;
//删除倒数第n个节点,要找到第n个节点的前一个结点,所以快指针先多走一步
n = n + 1;
while((n--) > 0 && fastNode != null){
fastNode = fastNode.next;
}
//快慢指针同时走
while(fastNode != null) {
fastNode = fastNode.next;
slowNode = slowNode.next;
}
//删除第n个节点
slowNode.next = slowNode.next.next;
return dummyHead.next;
}
}
面试题 02.07. 链表相交
双指针法
public class Solution {
public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
//双指针法
ListNode curA = headA;
ListNode curB = headB;
int lenA = 0;
int lenB = 0;
int gap = 0;
while(curA != null) {
curA = curA.next;
lenA++;
}
while(curB != null) {
curB = curB.next;
lenB++;
}
curA = headA;
curB = headB;
// 让curA为最长链表的头,lenA为其长度
if(lenB > lenA) {
int tmpLen = lenA;
lenA = lenB;
lenB = tmpLen;
ListNode tmpNode = curA;
curA = curB;
curB = tmpNode;
}
// 求长度差
gap = lenA - lenB;
// 让curA和curB在同一起点上(末尾位置对齐)
while ((gap--) > 0) {
curA = curA.next;
}
// 遍历curA 和 curB,遇到相同则直接返回
while(curA != null) {
if(curA == curB) {
return curA;
}
curA = curA.next;
curB = curB.next;
}
return null;
}
}
142.环形链表II
双指针法(快慢指针)
public class Solution {
public ListNode detectCycle(ListNode head) {
//双指针法(快慢指针)
ListNode fast = head;
ListNode slow = head;
while(fast != null && fast.next != null) {
fast = fast.next.next;
slow = slow.next;
if(slow == fast) {// 有环
ListNode index1 = fast;
ListNode index2 = head;
// 两个指针,从头结点和相遇结点,各走一步,直到相遇,相遇点即为环入口
while(index1 != index2) {
index1 = index1.next;
index2 = index2.next;
}
return index1;
}
}
return null;
}
}
学习成果:
- 24. 两两交换链表中的节点
- 19.删除链表的倒数第N个节点
- 面试题 02.07. 链表相交
- 142.环形链表II