24. Swap Nodes in Pairs
Given a linked list, swap every two adjacent nodes and return its head. You must solve the problem without modifying the values in the list's nodes (i.e., only nodes themselves may be changed.)
Example 1:
题目解析:
- 两两交换节点,都是重复的逻辑,可以考虑使用递归
代码:
1. 递归
class Solution {
public ListNode swapPairs(ListNode head) {
if (head == null || head.next == null) {
return head;
}
ListNode curHead = head.next;
ListNode temp = curHead.next;
curHead.next = head;
head.next = swapPairs(temp);
return curHead;
}
}
2. 迭代
class Solution {
public ListNode swapPairs(ListNode head) {
ListNode dummy = new ListNode();
ListNode prev = dummy;
dummy.next = head;
while (head != null && head.next != null) {
ListNode temp = head.next.next;
prev.next = head.next;
head.next.next = head;
head.next = temp;
prev = head;
head = temp;
}
if (head != null) {
prev.next = head;
}
return dummy.next;
}
}
19. Remove Nth Node From End of List
Given the head of a linked list, remove the nth node from the end of the list and return its head.
Example 1:
题目解析:
- 一般做法,先遍历一遍,在根据N的值移动到对应节点删除
- 使用双指针,快指针先走n步,然后快慢指针同时走,直到快指针走到最后一个节点为止,也就是说此时相当于慢指针从后往前走了n步。
代码:
1. 两轮遍历
class Solution {
public ListNode removeNthFromEnd(ListNode head, int n) {
int size = 0;
ListNode dummy = new ListNode();
dummy.next = head;
ListNode newHead = head;
while (newHead != null) {
size++;
newHead = newHead.next;
}
newHead = dummy;
for (int i = 0; i < size - n; i++) {
newHead = newHead.next;
}
newHead.next = newHead.next.next;
return dummy.next;
}
}
2. 双指针
class Solution {
public ListNode removeNthFromEnd(ListNode head, int n) {
ListNode slow = head, fast = head;
for (int i = 0; i < n; i++) {
fast = fast.next;
}
if (fast == null) {
return head.next;
}
while (fast.next != null) {
fast = fast.next;
slow = slow.next;
}
slow.next = slow.next.next;
return head;
}
}
160. Intersection of Two Linked Lists
Given the heads of two singly linked-lists headA and headB, return the node at which the two lists intersect. If the two linked lists have no intersection at all, return null.
For example, the following two linked lists begin to intersect at node c1:
The test cases are generated such that there are no cycles anywhere in the entire linked structure.
Note that the linked lists must retain their original structure after the function returns.
Custom Judge:
The inputs to the judge are given as follows (your program is not given these inputs):
intersectVal- The value of the node where the intersection occurs. This is0if there is no intersected node.listA- The first linked list.listB- The second linked list.skipA- The number of nodes to skip ahead inlistA(starting from the head) to get to the intersected node.skipB- The number of nodes to skip ahead inlistB(starting from the head) to get to the intersected node.
The judge will then create the linked structure based on these inputs and pass the two heads, headA and headB to your program. If you correctly return the intersected node, then your solution will be accepted.
题目解析:
- 只需移动起点到相同长度的位置即可找到相交点。
代码:
public class Solution {
public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
ListNode newHeadA = headA, newHeadB = headB;
int sizeA = 0, sizeB = 0;
while (newHeadA != null) {
sizeA++;
newHeadA = newHeadA.next;
}
while (newHeadB != null) {
sizeB++;
newHeadB = newHeadB.next;
}
if (sizeA > sizeB) {
int diff = sizeA - sizeB;
for (int i = 0; i < diff; i++) {
headA = headA.next;
}
} else if (sizeA < sizeB) {
int diff = sizeB - sizeA;
for (int i = 0; i < diff; i++) {
headB = headB.next;
}
}
while (headA != null) {
if (headA == headB) {
return headA;
}
headA = headA.next;
headB = headB.next;
}
return null;
}
}
142. Linked List Cycle II
Given the head of a linked list, return the node where the cycle begins. If there is no cycle, return null.
There is a cycle in a linked list if there is some node in the list that can be reached again by continuously following the next pointer. Internally, pos is used to denote the index of the node that tail's next pointer is connected to (0-indexed). It is -1 if there is no cycle. Note that pos is not passed as a parameter.
Do not modify the linked list.
Example 1:
题目解析:
- 使用快慢指针,如果有环的话一定会相遇。
- 通过判断快指针的情况判断是否有环
代码:
public class Solution {
public ListNode detectCycle(ListNode head) {
if (head == null || head.next == null) {
return null;
}
ListNode slow = head.next, fast = head.next.next;
while (slow != fast) {
if (fast == null || fast.next == null) {
return null;
}
slow = slow.next;
fast = fast.next.next;
}
while (head != slow) {
head = head.next;
slow = slow.next;
}
return head;
}
}
总结
- 双指针(快慢指针)在链表问题中十分常见。