- 两两交换链表中的节点
1、1虚拟节点
要注意一点:使用虚拟的节点的意义就是想让头节点和其他节点一样,所以在定义returnHead的时候应该定义成
ListNode returnHead = dummy; return returnHead.next;
而不能是
ListNode returnHead = head;
return head;
比如 0 1 2
交换完是 1 0 2
如果返回head
就会是0 2
public static ListNode swapPairs(ListNode head) {
//虚拟节点
ListNode dummy = new ListNode(0,head);
//需要一个节点保存现在的头节点 用于返回 但不能直接保存head 因为这个head的位置也是要参与交换的
//ListNode returnHead = head;
ListNode returnHead = dummy;
//这个节点作为临时节点 和dummy还有temp一起变化
ListNode cur = head;
while (cur != null && cur.next != null){
ListNode temp = cur.next.next; // 缓存 next
dummy.next = cur.next;// 将 prev 的 next 改为 head 的 next
cur.next.next = cur;// 将 head.next(prev.next) 的next,指向 head
cur.next = temp; // 将head 的 next 接上缓存的temp
dummy = cur;// 步进1位
cur = cur.next;// 步进1位
}
return returnHead.next;
}
19.删除链表的倒数第N个节点
思路 快慢指针
使用虚拟头节点
让快指针先走n+1
然后快慢指针一起走 直到快指针指向null
慢指针就指向的目标节点的前一个节点
/**
*思路 快慢指针
* 使用虚拟头节点
* 让快指针先走n+1
* 然后快慢指针一起走 直到快指针指向null
* 慢指针就指向的目标节点的前一个节点
*/
public static ListNode removeNthFromEnd(ListNode head, int n) {
// 链表中结点的数目为 sz
// 1 <= sz <= 30
// 0 <= Node.val <= 100
// 1 <= n <= sz
ListNode dummy = new ListNode(0,head);
ListNode fast = dummy;
ListNode slow = dummy;
for (int i = 0; i <= n; i++) { //让fast先走n+1
fast = fast.next;
}
while (fast != null){
fast = fast.next;
slow = slow.next; //快慢指针一起移动
}
slow.next = slow.next.next;
return dummy.next;
}
面试题 02.07. 链表相交 同:160.链表相交
这里要注意,交点不是数值相等,而是指针相等。
思路:把两条链表尾端对其,然后长链表移动到和短链表头节点的位置,比较两条链表是否相等,不相等就往后挪一位,直到相等或为null
ListNode listNode7 = new ListNode(6, null);
ListNode listNode6 = new ListNode(2, listNode7);
ListNode listNode5 = new ListNode(6, listNode6);
ListNode listNode4 = new ListNode(5, listNode5);
ListNode listNode3 = new ListNode(4, listNode4);
// ListNode listNode2 = new ListNode(6, null);
ListNode listNode1 = new ListNode(2, listNode6);
ListNode listNode0 = new ListNode(1, listNode1);
ListNode listNode = getIntersectionNode(listNode0,listNode3);
这样才会返回2 6
142.环形链表II
public ListNode detectCycle(ListNode head) {
ListNode fast = head;
ListNode slow = head;
while (fast!=null && fast.next != null){ //fast.next != null fast一次走两个
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;
}