题目:24. 两两交换链表中的节点 - 力扣(LeetCode)
定义虚拟头节点起到忽略头节点的作用,定义临时节点指向虚拟头节点起到定位的作用,采用双指针的方法交换临时节点后两个节点,进行更新用于循环交换。
代码实现:
class Solution {
public ListNode swapPairs(ListNode head) {
ListNode pre = new ListNode(0, head); // 虚拟头节点
ListNode temp = pre; // 临时节点
while (temp.next != null && temp.next.next != null) {
ListNode start = temp.next; // 双指针 1
ListNode end = temp.next.next; // 双指针 2
temp.next = start.next; // 顺畅体现在这里!!!!!!!!(这里可以有掌声)
start.next = end.next;
end.next = start;
temp = start;
}
return pre.next;
}
}
题目:
删除倒数第n个节点,属于双指针的应用扩展,让前指针先移动n个节点。此后双指针start和end同时向后移动,直到start移动到尾部null时,此时end对应的就是要删除的节点。但要删除end处的节点,就应该将end到达要删除节点的前一节点位置,则循环判断条件设置为start.next != null。
代码实现:
class Solution {
public ListNode removeNthFromEnd(ListNode head, int n) {
ListNode dummyHead = new ListNode(0, head); // 虚拟头节点
ListNode start = dummyHead; // 双指针 1
ListNode end = dummyHead; // 双指针 2
for (int i = 0; i < n; i++) { // 两指针间隔为 n
start = start.next;
}
while (start.next != null) {
start = start.next;
end = end.next;
}
end.next = end.next.next; // 这里用 start 不合适,存在一种特殊情况:删除倒数第一个节点,返回的结果包含start节点
return dummyHead.next;
}
}
题目:
两链表相交的特性是尾部对其,因此可以围绕链表长度来做。遍历获取两链表长度,指定较为长的一条为基准,先遍历差值长度保证两遍历起始点相同,之后进行循环判等就行。没有相等的结果则输出null。
代码实现:
public class Solution {
public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
// 两个链表相交之后尾部是对齐的
// 求两链表的长度,分别计算起始位置,从各自起始位置依次向后遍历,判断两链表节点值是否相同
ListNode curA = new ListNode(0, headA);
ListNode curB = new ListNode(0, headB);
int lenA = 0;
int lenB = 0;
while (curA.next != null) {
curA = curA.next;
lenA++;
}
while (curB.next != null) {
curB = curB.next;
lenB++;
}
curA = headA;
curB = headB;
if (lenB > lenA) {
int temp = lenA;
lenA = lenB;
lenB = temp;
ListNode tempNode = curA;
curA = curB;
curB = tempNode;
}
int diff = lenA - lenB;
while (diff-- > 0) {
curA = curA.next;
}
while (curA != null) {
if (curA == curB) {
return curA;
}
curA = curA.next;
curB = curB.next;
}
return null;
}
}
题目:
双指针的拓展。前指针走两步,后指针走一步。如果链表有环则一定会相遇,需要知道一个结论:如果两节点相遇,则从相遇节点到环形入口和从头节点到环形入口的节点数是相同的。进行循环判断即可。
代码实现:
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
}
}
public class Solution {
public ListNode detectCycle(ListNode head) {
ListNode fast = head, slow = head;
while (true) {
if (fast == null || fast.next == null) {
return null;
}
fast = fast.next.next;
slow = slow.next;
if (slow == fast) break;
}
fast = head;
while (fast != slow) {
fast = fast.next;
slow = slow.next;
}
return fast;
}
}