24两两交换链表中的节点
使用模拟头节点,整体思路如下图
class Solution {
public ListNode swapPairs(ListNode head) {
ListNode dummyhead = new ListNode(-1);
dummyhead.next = head;
ListNode cur = dummyhead;
ListNode temp;
ListNode first;
ListNode second;
while(cur.next!= null && cur.next.next !=null){
temp=cur.next.next.next;
first = cur.next;
second = cur.next.next;
cur.next=second;
second.next=first;
first.next=temp;
cur=first;
}
return dummyhead.next;
}
}
19删除链表的倒数第N个节点
新建一个虚拟头节点指向head,快慢指针都指向虚拟头节点,快指针比慢指针先走n个节点。
class Solution {
public ListNode removeNthFromEnd(ListNode head, int n) {
ListNode dummyhead = new ListNode(0); //这里用0或者-1对实质的创建无影响
dummyhead.next = head;
ListNode slow = dummyhead;
ListNode fast = dummyhead;
for(int i=0; i<=n; i++){
fast = fast.next;
}
// 只要快慢指针相差 n 个节点即可
while(fast!=null){ //终止条件
fast = fast.next;
slow = slow.next;
}
// 此时 slowIndex 的位置就是待删除元素的前一个位置。
// 具体情况可自己画一个链表长度为 3 的图来模拟代码来理解
// 检查 slowIndex.next 是否为 null,以避免空指针异常
if(slow.next != null){ //要删的是slow的下一个
slow.next = slow.next.next;
}
return dummyhead.next;
}
}
02.07. 链表相交
中间的两个if需要理解
public class Solution {
public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
// p1 指向 A 链表头结点,p2 指向 B 链表头结点
ListNode p1 = headA, p2 = headB;
while (p1 != p2) {
// p1 走一步,如果走到 A 链表末尾,转到 B 链表
if (p1 == null) p1 = headB;
else p1 = p1.next;
// p2 走一步,如果走到 B 链表末尾,转到 A 链表
if (p2 == null) p2 = headA;
else p2 = p2.next;
}
return p1;
}
}
142.环形链表II 较难
判断是否有环以及环的入口 画图及列公式
public class Solution {
public ListNode detectCycle(ListNode head) {
ListNode slow = head;
ListNode fast = head;
while(fast!=null && fast.next!=null){
slow = slow.next;
fast = fast.next.next;
if(slow == fast){
ListNode index1 = fast;
ListNode index2 = head;
//两个指针,从头结点和相遇结点,各走一步,直到相遇,相遇点即为环的入口
while(index1!=index2){
index1 = index1.next;
index2 = index2.next;
}
return index1;
}
}
return null;
}
}