24. 两两交换链表中的节点
用虚拟头结点。循环时需要把第一个和下一轮循环的第一个用临时节点保存下来,第二个不用因为首次修改指针就指向了第二个节点。然后依次对next进行赋值。
循环条件是在下两个操作数之前,对cur指针的next和next.next判空。注意顺序,如果next已经为空,再访问next.next会报空指针异常。
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode() {}
* ListNode(int val) { this.val = val; }
* ListNode(int val, ListNode next) { this.val = val; this.next = next; }
* }
*/
class Solution {
public ListNode swapPairs(ListNode head) {
ListNode dummyhead = new ListNode();
dummyhead.next = head;
ListNode temp1 = new ListNode();
ListNode temp2 = new ListNode();
ListNode cur = new ListNode();
cur = dummyhead;
while(cur.next != null && cur.next.next !=null){
temp1 = cur.next;
temp2 = cur.next.next.next;
cur.next = cur.next.next;
cur.next.next = temp1;
cur.next.next.next = temp2;
cur = cur.next.next;
}
return dummyhead.next;
}
}
自己有一个细节没有注意到是,返回的时候不要返回head节点,因为,head节点已经指向了整个链表的第二个节点,所以是不完整的链表。除非原来链表是空链表或者只有一个节点,否则都会报错。
19.删除聊表倒数第n个节点
快慢指针指向虚拟头节点,然后让快指针先移动n步,再让快慢指针同时后移,直至快指针的next为空,再操作慢指针。
此处和视频讲解略有不同,因为不判断next直接令fast.next赋值给next会有空指针异常,所以写法如下,这也令fast不必多移动一步。
class Solution {
public ListNode removeNthFromEnd(ListNode head, int n) {
ListNode dummyhead = new ListNode();
ListNode fast = new ListNode();
ListNode slow = new ListNode();
dummyhead.next = head;
fast = dummyhead;
slow = dummyhead;
while(n > 0 && fast != null){
fast = fast.next;
n--;
}
while(fast.next != null){
fast = fast.next;
slow = slow.next;
}
slow.next = slow.next.next;
return dummyhead.next;
}
}
面试题 02.07. 链表相交
第一个错误点是,一开始cur指针遍历完长度,没有赋值回去。
另外一个注意点是,next是空的话可以访问,但是想通过空的next访问next不行,自己对空指针异常了解不够。
public class Solution {
public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
ListNode curA = headA;
ListNode curB = headB;
int alen = 0;
int blen = 0;
while(curA !=null){
alen++;
curA =curA.next;
}
while(curB != null){
blen++;
curB = curB.next;
}
//遍历完别忘了往回赋值,指针已经指向尾部了
curA = headA;
curB = headB;
if( blen > alen){
int temp = alen;
alen = blen;
blen = temp;
ListNode tmp = new ListNode();
tmp = curA;
curA = curB;
curB = tmp;
}
int gap = alen - blen;
while(gap > 0){
curA = curA.next;
gap--;
}
while(curA != null){
if(curA == curB){
return curA;
}
curA = curA.next;
curB = curB.next;
}
return null;
}
}
142.环形链表II
快慢指针。重点理解相遇之后慢指针重回头节点,然后快慢指针各走一步。而不是按照原来速度。
/**
* Definition for singly-linked list.
* class ListNode {
* int val;
* ListNode next;
* ListNode(int x) {
* val = x;
* next = 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){
slow = head;
while(slow !=fast){
fast = fast.next;
slow = slow.next;
}
return slow;
}
}
return null;
}
}