今日任务
- 24.两两交换链表中的节点
- 19.删除链表的倒数第N个节点
- 160. 链表相交
- 142.环形链表II
24 两两交换链表中的节点
题目链接:https://leetcode.cn/problems/swap-nodes-in-pairs/description/
方法一:遍历实现
思路:
代码:
/*** 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 swapPairs(ListNode head) {ListNode dummyHead = new ListNode(0);dummyHead.next = head;ListNode temp = dummyHead;while(temp.next != null && temp.next.next != null) {ListNode node1 = temp.next;ListNode node2 = temp.next.next;temp.next = node2;node1.next = node2.next;node2.next = node1;temp = node1;}return dummyHead.next;}
}
方法二:递归
目前不太理解
19 删除链表的倒数第N个节点
题目链接:https://leetcode.cn/problems/remove-nth-node-from-end-of-list/description/
关键是 找到链表的倒数的位置
思路:
- 两个指针,一块一慢,都指向 dummyNode
- 先让快指针 先走 n+1 步
- 然后两个指针一起移动,直到快指针走到尽头
- 此时 慢指针 指向的 Node 就是倒数第N个节点 的前面一个节点
- 然后 让 倒数第N 个节点的前节点 指向 倒数第N 个节点的 后节点
class Solution {public ListNode removeNthFromEnd(ListNode head, int n) {ListNode dummyNode = new ListNode(0);dummyNode.next = head;ListNode fast = dummyNode;ListNode slow = dummyNode;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 dummyNode.next;}
}
160 链表相交
题目链接:https://leetcode.cn/problems/intersection-of-two-linked-lists-lcci/description/
同样使双指针的问题,关键点在于,后面相交的部分长度是一致的,就要保存两个链表在后面长度是一致的时候才能开始遍历
思路:
- 先计算两个链表的长度,使 curA 指向的是不短的那个链表
- 让长的链表 先走 两个链表长度差值的长度,这样两个链表的剩余长度就保持一致
- 开始遍历两个链表,当指向的是同一个对象的时候,就是交点
public class Solution {public ListNode getIntersectionNode(ListNode headA, ListNode headB) {ListNode curA = headA;ListNode curB = headB;int lenA = 0, lenB = 0;while(curA != null) {lenA++;curA = curA.next;}while(curB != null) {lenB++;curB = curB.next;}curA = headA;curB = headB;//使 curA 指向的链表使长的链表if(lenA < lenB) {int tmp = lenA;lenA = lenB;lenB = tmp;ListNode tmpNode = curA;curA = curB;curB = tmpNode;}int gap = lenA - lenB;while(gap-- > 0) {curA = curA.next;}while(curA != null) {if(curA == curB) {return curA;}curA = curA.next;curB = curB.next;}return null;}
}
142 环形链表II
题目链接:https://leetcode.cn/problems/linked-list-cycle-ii/description/
关键在于 要理解为什么一定是快的指针 从后面和 慢指针 相遇
一定是环内第一圈相遇
可知:x+y+z+y = 2 * (x + y) => x = z;
思路:
- 先理解为什么在环内,慢指针的第一圈相遇
- 将快指针放在头节点,慢指针依然为相遇节点
- 然后以同样速度,一次移动一个位置的话,就是走到环形入口相遇
代码:
public class Solution {public ListNode detectCycle(ListNode head) {ListNode fast = head;ListNode slow = head;while(true) {if(fast == null || fast.next == null) return null;fast = fast.next.next;slow = slow.next;if(fast == slow) break;}fast = head;while(slow != fast) {slow = slow.next;fast = fast.next;}return fast;}
}