目录
24.两两交换链表中的节点
代码实现
当前cur要在交换的两个之前才能实现操作
注意画个图看哪些链子断了,就需要拿中间变量去收集断了的值,断了是指没有和dummyhead这条链相连的节点。
public ListNode swapPairs(ListNode head) {
ListNode dummyhead=new ListNode();
dummyhead.next=head;//定义一个虚拟头节点
ListNode cur=dummyhead;
//cur.next.next==null就不遍历了
//先判断cur.next!=null再判断cur.next.next!=null
//因为当cur.next=null时还没判断,已经就开始判断cur.next.next就会出现空指针异常
//可以这样判断是因为是操作交换的两个数的前一位
while (cur.next!=null&&cur.next.next!=null){
ListNode tmp=new ListNode();
ListNode tmp3=new ListNode();
//要保存节点1和节点3,因为节点2断了1和3的节点
tmp=cur.next;
tmp3=cur.next.next.next;
cur.next=cur.next.next;//现在的cur.next已经指向了第二个节点(没变之前的第二个)
cur.next.next=tmp;
tmp.next=tmp3;
//tmp.next=tmp.next.next;这个位置已经找不到节点3了,画图理解
cur=cur.next.next;//cur指向变了的第二个,这里的cur才开始改变指向
//上面部分只是改变cur.next等的指向
}
return dummyhead.next;//不能return head,因为dummyhead.next会变,而head不会变,head.next变就不是head了
//dummyhead.next改变为头节点
}
19.删除链表倒数第N个节点
代码实现
使用双指针,当fast比slow多走n步时,当fast指向null时slow指向倒数第n个
由于删除增加操作要在删除节点位置前一个操作,所以fast应比slow多走n+1步,当fast指向null时slow指向倒数第n+1.
public ListNode removeNthFromEnd(ListNode head, int n) {
ListNode dummyhead=new ListNode();
dummyhead.next=head;
ListNode slow=new ListNode();
ListNode fast=new ListNode();
fast=dummyhead;
slow=dummyhead;
n++;
//只要fast比slow快n+1就行了,此时slow指向倒数第n个的前一个
while (n>0){
fast=fast.next;
n--;
}
while (fast!=null){
fast=fast.next;
slow=slow.next;
}
slow.next=slow.next.next;//进行删除
return dummyhead.next;
}
160.链表相交
代码实现
//先移到长链表实现同步移到
public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
ListNode curA=headA;
ListNode curB=headB;
int lenA=0;
int lenB=0;
//求链表A的长度
while (curA!=null){
lenA++;
curA=curA.next;
}
//求链表B的长度
while (curB!=null){
lenB++;
curB=curB.next;
}
curA=headA;
curB=headB;
//让curA成为最长链表的头,其长度为lenA
if (lenB>lenA){
//交换lenA,lenB
int tmplen=lenA;
lenA=lenB;
lenB=tmplen;
//交换curA,curB
ListNode tmpnode=curA;
curA=curB;
curB=tmpnode;
}
//求长度
int gap=lenA-lenB;
//让curA指向位置与curB指向B的末尾对其
while (gap>0){
curA=curA.next;
gap--;
}
//遍历curA和curB,遇到相同的则直接返回
while (curA!=null){
if (curA==curB){
return curA;
}
curA=curA.next;
curB=curB.next;
}
return null;
}
142.环形链表
代码实现
如何判断一个链表是否有环,用一个快指针一个慢指针,如果他们相遇就说明有环。
快指针每次走两步,慢指针每次走一步,相当于快指针每次以一个节点的速度靠近慢指针,所以成环时快慢指针一定相遇。
public ListNode detectCycle(ListNode head) {
ListNode slow=head;
ListNode fast=head;
while (fast!=null&&fast.next!=null){
//fast和slow的指向改变了
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;
}