class Solution {
public ListNode swapPairs(ListNode head) {
ListNode dumyhead = new ListNode(); //设置虚拟头节点
dumyhead.next = head;
ListNode cur = dumyhead; //遍历cur
ListNode temp ;
ListNode firstnode;
ListNode secondnode;
while(cur.next!=null&&cur.next.next!=null){ //考虑奇偶节点
temp = cur.next.next.next; //保存第三位
firstnode = cur.next;
secondnode = cur.next.next;
cur.next = secondnode; //先把第二位移到第一位
secondnode.next = firstnode; //在把第二位next赋值第一位
firstnode.next = temp;
cur = firstnode;
}
return dumyhead.next;
}
}
这道题主要是cur什么时候遍历结束,分两种情况
如果是奇数节点,那么cur.next.next=null则结束,cur.next不作交换
若是偶数节点,则cur.next=null结束
然后是交换节点。要思考清楚谁先谁后。最好是画图
19.删除链表的倒数第N个结点 leetcode19 Remove Nth Node From End of List
class Solution {
public ListNode removeNthFromEnd(ListNode head, int n) {
ListNode dumynode = new ListNode(1);
dumynode.next= head; //设置虚拟头
ListNode fast = dumynode;
ListNode slow = dumynode;
for(int i = 0 ;i<n;i++){ //快指针移动n+1步
fast = fast.next;
}
while(fast.next!=null){ //然后快慢指针一起移动
fast =fast.next;
slow = slow.next;
}
slow.next = slow.next.next; //slow.next为删除元素
return dumynode.next;
}
}
主要是快慢指针 slow在其删除元素的前一个
面试题 02.07. 链表相交 Intersection of Two Linked Lists LCCI
public class Solution {
public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
ListNode curA = headA;
ListNode curB = headB;
int lenA = 0,lenB = 0;
//计算长度
while(curA.next!=null){
curA = curA.next;
lenA++;
}
while(curB.next!=null){
curB = curB.next;
lenA++;
}
//指向头指针
curA = headA;
curB = headB;
//让A成为最长的链表
if(lenB>lenA){
//swap len
int templen = lenA;
lenA = lenB;
lenB = temp;
//交换节点
ListNode temp = curA;
curA = curB;
curB = temp;
}
//长度差
int len = lenA - lenB;
while(len-- > 0){ //让两个链表同一个位置
curA = curA.next;
}
while(curA!=null){
if(curA == curB) return curA;
curA = curA.next;
curB = curB.next;
}
return null;
}
}
当他们在同一位置上移动时,则可以找到是否右节点它们相同
142.环形链表 leetcode 142 Linked List Cycle II
public class Solution {
public ListNode detectCycle(ListNode head) {
ListNode fast = head,slow = head;
while(true){
if(fast==null || fast.next==null)return null; //无环为null
fast = fast.next.next;
slow = slow.next;
if(slow == fast) break; //有环
}
//
fast = head;
while(fast != slow){
fast = fast.next;
slow = slow.next;
}
return fast
}
}
光看题是有点抽象,很难想到何时达到入口节点
1判断是否有环
2哪里是环的起点
x=z,所以后面又取头节点,然后再移动节点,直到相遇则是入口节点
时间复杂度 O(N) :第二次相遇中,慢指针须走步数 x第一次相遇中,慢指针须走步数 x+y,其中 x为双指针重合点与环入口距离;因此总体为线性复杂度;
空间复杂度 O(1) :双指针使用常数大小的额外空间。