两两交换链表中的节点
题目:给你一个链表,两两交换其中相邻的节点,并返回交换后链表的头节点。你必须在不修改节点内部的值的情况下完成本题(即,只能进行节点交换)。
思路:虚拟头节点,临时节点
class Solution {
public ListNode swapPairs(ListNode head) {
ListNode dummyHead = new ListNode(-1,head);
ListNode cur = dummyHead;
while(cur.next != null && cur.next.next != null){
ListNode temp = cur.next;
ListNode temp1 = cur.next.next.next;
cur.next = cur.next.next;
cur.next.next = temp;
cur.next.next.next = temp1;
cur = cur.next.next;
}
return dummyHead.next;
}
}
删除链表的倒数第N个节点
题目:给你一个链表,删除链表的倒数第 n 个结点,并且返回链表的头结点。
思路:虚拟头节点,双指针,快指针先走n步,再快慢指针一起走,当快指针到达最后一个节点时,慢指针刚好停在需要删除节点的前一个节点。
class Solution {
public ListNode removeNthFromEnd(ListNode head, int n) {
ListNode dummyHead = new ListNode(-1,head);
ListNode fast = dummyHead;
ListNode slow = dummyHead;
for(int i = 0;i<n;i++){
fast = fast.next;
}
while(fast.next != null){
fast = fast.next;
slow = slow.next;
}
slow.next = slow.next.next;
return dummyHead.next;
}
}
链表相交
题目:给你两个单链表的头节点 headA 和 headB ,请你找出并返回两个单链表相交的起始节点。如果两个链表没有交点,返回 null 。
图示两个链表在节点 c1 开始相交:
思路:首先得到两个链表的长度,然后计算出长度差X,让长链先走X步,然后两个链的节点相等时就是交点。
public class Solution {
public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
ListNode curA = headA;
ListNode curB = headB;
//计算长度
int lenA = 0;
int lenB = 0;
while(curA != null){
curA = curA.next;
lenA++;
}
while(curB != null){
curB = curB.next;
lenB++;
}
curA = headA;
curB = headB;
//让curA是长链
if(lenA<lenB){
//互换
int tempLen = lenB;
lenB = lenA;
lenA = tempLen;
//节点互换
ListNode tempNode = curB;
curB = curA;
curA = tempNode;
}
//计算长链比短链差多少
int g = lenA-lenB;
//两个链剩余位置相同
while(g-->0){
curA = curA.next;
}
while(curA != null){
if(curA == curB){
return curA;
}
curA = curA.next;
curB = curB.next;
}
return null;
}
}
环形链表II
题目:给定一个链表的头节点 head ,返回链表开始入环的第一个节点。 如果链表无环,则返回 null。
如果链表中有某个节点,可以通过连续跟踪 next 指针再次到达,则链表中存在环。 为了表示给定链表中的环,评测系统内部使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。如果 pos 是 -1,则在该链表中没有环。注意:pos 不作为参数进行传递,仅仅是为了标识链表的实际情况。
不允许修改 链表。
思路:可以使用快慢指针法,分别定义 fast 和 slow 指针,从头结点出发,fast指针每次移动两个节点,slow指针每次移动一个节点,如果 fast 和 slow指针在途中相遇 ,说明这个链表有环。
- 为什么fast指针和slow指针一定会相遇呢?
- 这是因为fast是走两步,slow是走一步,其实相对于slow来说,fast是一个节点一个节点的靠近slow的,所以fast一定可以和slow重合。
详细思路可以看代码随想录中的介绍
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(fast == slow){
slow = head;
while(slow != fast){
slow = slow.next;
fast = fast.next;
}
return fast;
}
}
return null;
}
}