本题要注意的条件:
为了更好的操作链表,我定义了一个虚拟的头节点 dummyHead 指向链表。如下图所示
注意点:
- 不能写成 while(cur.next.next && null cur.next != null ) 如果是偶数个节点的话,此时就会出现空指针异常的情况。
- 也不能写成 while(cur.next != null || cur.next.next != null),也会出现空指针异常,当 节点为偶数个时候,那么 cur.next = null ,不满足就判断第二个条件,此时 cur.next.next就会出现空指针异常,因为 cur.next = null
本题思路:
class Solution {
public ListNode removeNthFromEnd(ListNode head, int n) {
// 使用一个虚拟头节点好操作一点
ListNode dummyHead = new ListNode(0);
dummyHead.next = head;
ListNode tmp = dummyHead;
ListNode cur = head;
int size = 0;
while(cur != null){
size++;
cur = cur.next;
}
int index = size - n;
while(index-- != 0){
tmp = tmp.next;
}
tmp.next = tmp.next.next;
return dummyHead.next;
}
}
本题注意点: 值相同,但不一定节点是同一个
本题思路:
public class Solution {
public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
// 首先遍历两个链表,算出长度
int sizeA = 0;
int sizeB = 0;
ListNode A = headA;
ListNode B = headB;
while(A != null){
sizeA++;
A = A.next;
}
while(B != null){
sizeB++;
B = B.next;
}
int res = Math.abs(sizeA-sizeB);
if( sizeA > sizeB){
while(res-- != 0){
headA = headA.next;
}
}else{
while(res-- != 0){
headB = headB.next;
}
}
// 此时 两个链表长度相等,就可以开始同时遍历
while(headA != null){
if(headA.val == headB.val && headA == headB){
return headA;
}
headA = headA.next;
headB = headB.next;
}
return headA;
}
}
本题思路:使用快慢指针来解决这道题,下面来详细介绍下这个思想
看完上图,大家可能有以下几个疑问?
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 meet = fast;
ListNode start = head;
while( meet != start){
meet = meet.next;
start = start.next;
}
return meet;
}
}
return null;
}
}