24. 两两交换链表中的节点
1. 判断条件:最后必须剩两个节点,且写的时候要把cur.next!=null写在前面,避免后面发生空指针错误。2. 定义虚拟节点,cur在要交换的两个节点的前面一个节点,要提前把1节点和3节点的地址存储,即cur.next和cur.next.next.next
class Solution {
public ListNode swapPairs(ListNode head) {
ListNode dummy = new ListNode(-1,head);
ListNode cur = dummy;
while(cur.next!=null&&cur.next.next!=null)
{
ListNode temp= cur.next;
ListNode temp1= cur.next.next.next;
// ->2
cur.next=cur.next.next;
//2->1
cur.next.next=temp;
//1->3
cur.next.next.next=temp1;
//移动
cur=cur.next.next;
}
return dummy.next;
}
}
19.删除链表的倒数第N个节点
快慢指针,核心是保证快指针比慢指针多N个,当快指针到最后一个节点,慢指针到应删节点前一个节点,判断到最后一个节点的条件为 fast.next!=null
(使用虚拟头节点是为了消除头节点的特殊性,一般都要用)
class Solution {
public ListNode removeNthFromEnd(ListNode head, int n) {
ListNode dummy = new ListNode(-1,head);
ListNode slow = dummy;
ListNode fast = dummy;
//只要快慢指针相差 n 个结点即可
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 dummy.next;
}
}
面试题 02.07. 链表相交
此题需要计算链表长度,不用虚拟头节点,因为是两个链表相互比较,而不是一个链表里的不同节点进行操作。
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)
{
lenA++;
curA=curA.next;
}
//-------------------
while(curB!=null)
{
lenB++;
curB=curB.next;
}
curA = headA;
curB = headB;
if(lenB>lenA)
{
int tLen=lenA;
lenA=lenB;
lenB=tLen;
ListNode tNode=curA;
curA=curB;
curB=tNode;
}
//求长度差
int gap = lenA-lenB;
while(gap>0)
{
curA=curA.next;
gap--;
}
while(curA!=null)
{
if(curA==curB)
{
return curA;
}
curA=curA.next;
curB=curB.next;
}
return curA;
}
}
(变量只声明一次即可)
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= slow;
ListNode index2= head;
while(index1!=index2)
{
index1=index1.next;
index2=index2.next;
}
return index1;
}
}
return null;
}
}