24. 两两交换链表中的节点
题目:
给你一个链表,两两交换其中相邻的节点,并返回交换后链表的头节点。你必须在不修改节点内部的值的情况下完成本题(即,只能进行节点交换)。
思路:
使用虚拟头节点方法,每次调换两个节点的位置。注意改变链表时操作的顺序,避免链表成环导致死循环。
代码:
/**
* 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 dummy = new ListNode(0, head);
ListNode curr = dummy;
while (curr.next != null && curr.next.next != null) {
ListNode first = curr.next;
ListNode second = curr.next.next;
curr.next = second;
first.next = second.next;
second.next = first;
curr = first;
}
return dummy.next;
}
}
19.删除链表的倒数第N个节点
题目:
给你一个链表,删除链表的倒数第 n
个结点,并且返回链表的头结点。
思路:
虚拟头节点,方便处理需要删除的节点是头节点的情况。
快慢指针法,要删除倒数第n个节点,只需要让fast指针比slow节点快n步,当fast指针指向最后一个节点时,slow指针就指向了要删除节点的前一个节点。slow.next = slow.next.next 即可删除。
代码:
/**
* 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 dummy = new ListNode(0, head);
ListNode fast = dummy;
ListNode slow = dummy;
for (int i = 0; i < n && fast.next != null; i++) {
fast = fast.next;
}
while (fast.next != null) {
fast = fast.next;
slow = slow.next;
}
slow.next = slow.next.next;
return dummy.next;
}
}
面试题 02.07. 链表相交
题目:
给你两个单链表的头节点 headA
和 headB
,请你找出并返回两个单链表相交的起始节点。如果两个链表没有交点,返回 null。
思路:
使用集合的contains()方法判断是否有相交的节点。
代码:
/**
* 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) {
Set<ListNode> set = new HashSet<>();
while (headA != null) {
set.add(headA);
headA = headA.next;
}
while (headB != null) {
if (set.contains(headB)) {
return headB;
}
headB = headB.next;
}
return null;
}
}
142.环形链表II
题目:
给定一个链表的头节点 head
,返回链表开始入环的第一个节点。 如果链表无环,则返回 null
。
思路:
思路与上一题类似,利用集合的contains()方法,判断是否有环入口节点。
方法:
/**
* Definition for singly-linked list.
* class ListNode {
* int val;
* ListNode next;
* ListNode(int x) {
* val = x;
* next = null;
* }
* }
*/
public class Solution {
public ListNode detectCycle(ListNode head) {
Set<ListNode> set = new HashSet<>();
while (head != null) {
if (set.contains(head)) {
return head;
}
set.add(head);
head = head.next;
}
return null;
}
}