24. 两两交换链表中的节点
关键词:两两交换相邻节点、不改变内部值
不修改节点内部的值的情况下,就是改变链表的下一指向
class Solution {
public ListNode swapPairs(ListNode head) {
ListNode dumyHead = new ListNode();
dumyHead.next = head;
ListNode cur = dumyHead;
//奇偶两种情况判断逻辑不同
while(cur.next!=null && cur.next.next!=null){
ListNode temp = cur.next;
ListNode temp1 = cur.next.next.next;
cur.next = temp.next;
cur.next.next = temp;
temp.next = temp1;
cur = cur.next.next;
}
return dumyHead.next;
}
}
19. 删除链表的倒数第 N 个结点
关键词:倒数的n用正数得到,快慢指针移动
关键:如何操作倒数第n个(无法得知链表的size),使用快慢指针,相隔n个节点
操作链表第n个节点时,要遍历到n-1位置的节点,再去操作第n个节点(比如设计链表中的删除某个index节点和在index添加节点的操作)
/**
* 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 removeNthFromEnd(ListNode head, int n) {
ListNode dumyHead = new ListNode();
dumyHead.next = head;
//此处要指向虚拟头节点dumyHead,这样fast和slow之间差n+1
ListNode slow = dumyHead;
ListNode fast = dumyHead;
for(int i = 0; i<=n; i++){
fast = fast.next;
}
while(fast!=null){
fast = fast.next;
slow = slow.next;
}
slow.next = slow.next.next;
return dumyHead.next;
}
}
面试题02.07. 链表相交
关键点:求相交,从后面往前看,所以让size小的后移
在没有n的情况下遍历链表while(cur!=null){cu = cur.next}
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) {
* val = x;
* next = null;
* }
* }
*/
public class Solution {
public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
//求相交的地方,前面没有重复的,后面必然有重复的
int lenA = 0;
int lenB = 0;
ListNode curA = headA;
ListNode curB = headB;
while(curA!=null){
lenA++;
curA = curA.next;
}
while(curB!=null){
lenB++;
curB = curB.next;
}
//⏰此处记得将cur改为头节点
curA = headA;
curB = headB;
//哪个长?无法判断哪个长,就指定lenA为最长
if(lenB>lenA){
int temp = lenA;
lenA = lenB;
lenB = temp;
ListNode temp1 = curA;
curA = curB;
curB = temp1;
}
int gap = lenA-lenB;
//⏰此处i<gap,不理解就举个例子
for(int i=0; i<gap; i++){
curA =curA.next;
}
//如何判断二者是否相交?当前的两个cur指针相等 相等则说明指向同一个
while(curA!=null){
if(curA==curB){
return curA;
}
curA = curA.next;
curB = curB.next;
}
return null;
}
}
142.环形链表II
关键点:数学思维
关键点
- 快慢指针相遇时的节点到环形链表入口的距离=头节点到环形链表入口的距离
- slow=x+y;fast=x+y+n(y+z); slow:fast=1:2
- slow!=x+y+n(y+z)的原因是fast和slow相遇必定是在第一圈完成的
代码
public class Solution {
public ListNode detectCycle(ListNode head) {
ListNode fast = head;
ListNode slow = head;
//快指针不为null的情况下,慢指针必然不为null
while(fast!=null &&fast.next!=null){
fast = fast.next.next;
slow = slow.next;
if(fast == slow){
ListNode index1 = fast;
ListNode index2 = head;
while(index1!=index2){
index1 = index1.next;
index2 = index2.next;
}
return index1;
}
}
return null;
}
}