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.)
Need review!
/**
* 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) {
// if (head == null) {
// return head;
// }
ListNode dummy = new ListNode(-1);
dummy.next = head;
ListNode cur = dummy;
ListNode temp = dummy;
ListNode node1 = dummy;
ListNode node2 = dummy;
// cur points at the dummy node, otherwise we can't change 1->2 to 2->1
// if the size is an even number cur.next == null -> end the loop
// if the size is an odd number cur.next.next == null -> end the loop
while (cur.next != null && cur.next.next!= null) {
//1. create a temp node to save node 1
//2. create another temp to save node 3
//3. after swap, move cur to the node before next swap.
node1 = cur.next;
node2 = cur.next.next;
temp = cur.next.next.next;
cur.next = node2;
node2.next = node1;
node1.next = temp;
cur = node1;
}
return dummy.next;
}
}
TC: O(n);
SC: O(1);
19. Remove Nth Node From End of List
Given the
head
of a linked list, remove thenth
node from the end of the list and return its head.
We have two pointers moving toward the end of the Linkedlist. The gap between these two pointers is n. Once we find the end node of the Linkedlist, we can easily remove the previous node that the other pointer points at.
/**
* 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(-1);
dummy.next = head;
ListNode fast = head;
ListNode slow = dummy;
int count = 0;
while (fast != null && fast.next != null) {
fast = fast.next;
count++;
if (count == n) {
slow = slow.next;
count--;
}
}
slow.next = slow.next.next;
return dummy.next;
}
}
TC:O(n);
SC:O(1)
160. Intersection of Two Linked Lists
Given the heads of two singly linked-lists
headA
andheadB
, return the node at which the two lists intersect. If the two linked lists have no intersection at all, returnnull
.
Need review!
This problem is hard to understand in the first place because it gives some useless extra information. I didn't come up with the solution until I watched an explanation video from Neetcode. This is not the most concise solution but it is the easiest solution for me.
1. go through two linkedlists and calculate each size.
2. count the gap between these two sizes and move curB or curA (depending on which list is longer) to curX+gap so that curA and curB have the same length of the remaining list.
3. star moving both nodes together until they meet, return node; otherwise return null.
/**
* 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) {
ListNode curA = headA;
ListNode curB = headB;
int sizeA = 0;
int sizeB = 0;
while (curA != null) {
curA = curA.next;
sizeA++;
}
while (curB != null) {
curB = curB.next;
sizeB++;
}
curA = headA;
curB = headB;
if (sizeA > sizeB) {
int gap = sizeA - sizeB;
while (gap > 0) {
curA = curA.next;
gap--;
}
while (curA != null) {
if (curA == curB) {
return curA;
}
curA = curA.next;
curB = curB.next;
}
} else {
int gap = sizeB - sizeA;
while (gap > 0) {
curB = curB.next;
gap--;
}
while (curA != null) {
if (curA == curB) {
return curA;
}
curA = curA.next;
curB = curB.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, returnnull
.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'snext
pointer is connected to (0-indexed). It is-1
if there is no cycle. Note thatpos
is not passed as a parameter.Do not modify the linked list.
How to know there is a cycle?
The fast pointer moves 2 steps ahead of the slow pointer. If they eventually meet, then there is a cycle.
How to find the node where the cycle begins?
Moving one pointer from the head, and moving the other one from the node where two nodes met previously. The intersection will be the node.
/**
* 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) {
ListNode fast = head;
ListNode slow = head;
while (fast != null && fast.next != null) {
fast = fast.next.next;
slow = slow.next;
if (fast == slow) {
ListNode temp = head;
while (temp != slow) {
temp = temp.next;
slow = slow.next;
}
return temp;
}
}
return null;
}
}