KOKO-代码随想录算法训练营Day 4 【链表】24|19|160|142
文章目录
一、24两两交换链表中的结点
1.题目
https://leetcode.cn/problems/swap-nodes-in-pairs/
2.代码
public static ListNode swapPairs(ListNode head) {
if(head==null||head.next==null){
return head;
}
ListNode pre=new ListNode(-1,head);
ListNode cur=pre;
ListNode firstLode;
ListNode secondLode;
ListNode temp;
while (cur.next!=null&&cur.next.next!=null){
firstLode=cur.next;
secondLode=cur.next.next;
temp=cur.next.next.next;//第几个比较合理
//swap
cur.next=secondLode;
secondLode.next=firstLode;
firstLode.next=temp;
//新的cur指向first,即刚交换完的操作
cur=firstLode;
}
return pre.next;
}
3.总结
对于我来说,应该注意的是cur后面为firstNode,在交换位置后,只要知道谁是cur就可以,而不用纠结上一次secondNode,temp变到哪里去了
二、19.删除链表的倒数第N个节点
1.题目
https://leetcode.cn/problems/remove-nth-node-from-end-of-list/
2.代码
public ListNode removeNthFromEnd(ListNode head, int n) {
ListNode pre = new ListNode(-1,head);//头节点
ListNode fast=pre;
ListNode low=pre;
while (fast!=null){
if(n--<0){
low=low.next;
}
fast=fast.next;
}
low.next=low.next.next;
return pre.next;
}
3.总结
用快指针和慢指针之间差n去删除,先让快指针走n个,随后快指针和慢指针一起向后走到结束,即为倒数第n个元素全部-n即为正着数的第几个。
三. 面试题 02.07. 链表相交
1.题目:160
https://leetcode.cn/problems/intersection-of-two-linked-lists-lcci/description/
2.代码:
public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
if(headA==null||headB==null){
return null;
}
//求A的长度
ListNode nodeA=headA;
ListNode nodeB=headB;
int la=0,lb=0;
while (nodeA!=null){
la++;
nodeA=nodeA.next;
}
while (nodeB!=null){
lb++;
nodeB=nodeB.next;
}
// 保证a是长链表,在长度差的位置开始遍历
nodeA=headA;
nodeB=headB;
if(lb>la){
ListNode temp=nodeA;
nodeA=nodeB;
nodeB=temp;
int t=la;
la=lb;
lb=t;
}
int index=la-lb;
while(index-->0){
nodeA=nodeA.next;
}
while (nodeA!=null){
if(nodeA==nodeB){
return nodeA;
}
nodeA=nodeA.next;
nodeB=nodeB.next;
}
return null;
}
3.总结:
末端对齐,找到a比b多index个所对应的下标,从该位置一一比较a和b结点是否相等。总保证a>b
四.142.环形链表II
1.题目
https://leetcode.cn/problems/linked-list-cycle-ii/description/
2.代码
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(fast==slow){
ListNode index1=fast;//从相遇位置起index,=head到还入口的位置
ListNode index2=head;
while (index1!=index2){
index1=index1.next;
index2=index2.next;
}
return index1;
}
}
return null;
}
3.总结
快指针一次走两个,慢指针一次走一个,有环则必相遇。慢指针入环后,快指针在慢指针到达入口前追上慢指针,环内相遇点到环入口的距离应等于head到环入口的距离。2(x+y)=x+y+n(y+z) x:入口前,y:环内相遇,z:相遇点到环入口处的距离。
总结
倒数n,可以先快指针正数n,在慢指针随快指针到结束