链表节点的操作
24.两两交换链表中的节点
题目描述: 对于链表1->2->3->4 变换为 2->1->3->4
解题思路:需要用到两个指针,然后按照指针指向顺序,修改指针指向
代码:
class Solution {
public ListNode swapPairs(ListNode head) {
if(head == null) return null;
ListNode dumy = new ListNode(-1, head);
ListNode pre = dumy;
ListNode curr = head;
while(curr != null && curr.next != null){
// 指针更改多个指向时必须按照顺序来, 一一更改, 对于后面丢失指针的节点需要提前保存起来
ListNode temp = curr.next.next;
pre.next = curr.next;
curr.next.next = curr;
curr.next = temp;
pre = curr;
curr = curr.next;
}
return dumy.next;
}
}
19.删除链表的倒数第n个节点
题目描述:
- 1->2->3->4->5
- 删除倒数第一个
- 1->2->3->5
解题思路: 双指针:当curr指针走到n位置时,此时用另外一个指针pre跟它同时向后走,那么当curr走到结尾时候,pre就在被删除节点的上一个节点 此时,只需要进行删除操作即可
代码:
class Solution {
public ListNode removeNthFromEnd(ListNode head, int n) {
// 虚拟头节点 + 双指针
ListNode dumy = new ListNode(-1, head);
ListNode pre = dumy;
ListNode curr = head;
int i = 0;
while(curr != null){
if(i++ >= n){
// 找到需要被删除节点的上一个节点
pre = pre.next;
}
curr = curr.next;
}
pre.next = pre.next.next;
return dumy.next;
}
}
面试题: 链表相交
解题思路: 浪漫的解法:当我走完我的路却找不到你,于是我又走你来时的路,当你走到终点时,见不到我,你也来走我来时的路,若相交,则一定可以在终点相遇
代码:
public class Solution {
public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
ListNode left = headA;
ListNode right = headB;
while(left != right){
left = left == null ? headB : left.next;
right = right == null ? headA: right.next;
}
return left;
}
}
142. 环形链表
解题思路:快慢指针
- 快慢指针:快指针一次走两步,慢指针一次走一步,若存在环则一定相遇
- 快慢指针找中点,当快指针走到结尾时,慢指针刚好走到链表中点
代码:
public class Solution {
public ListNode detectCycle(ListNode head) {
ListNode slow = head, fast = head;
while (fast != null && fast.next != null) {
slow = slow.next;
fast = fast.next.next;
// 找到环的入口
if (fast == slow) {
fast = head;
while (fast != null && slow != null) {
if (fast == slow) {
return slow;
}
slow = slow.next;
fast = fast.next;
}
}
}
return null;
}
}