Skip to content

Commit b2d4105

Browse files
authored
Merge pull request ByteByteGoHq#9 from RYMNDK/java-solutions-linked-lists
Java solutions linked lists
2 parents 16cf108 + 84240b7 commit b2d4105

7 files changed

+325
-0
lines changed
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
import DS.MultiLevelListNode;
2+
3+
/*
4+
// Definition of MultiLevelListNode:
5+
class MultiLevelListNode {
6+
public int val;
7+
public MultiLevelListNode next;
8+
public MultiLevelListNode child;
9+
public MultiLevelListNode(int val) { this.val = val; }
10+
public MultiLevelListNode(int val, MultiLevelListNode next, MultiLevelListNode child) {
11+
this(val);
12+
this.next = next;
13+
this.child = child;
14+
}
15+
}
16+
*/
17+
18+
19+
public class FlattenMultiLevelList {
20+
public static MultiLevelListNode flattenMultiLevelList(MultiLevelListNode head) {
21+
if (head == null) {
22+
return null;
23+
}
24+
MultiLevelListNode tail = head;
25+
// Find the tail of the linked list at the first level.
26+
while (tail.next != null) {
27+
tail = tail.next;
28+
}
29+
MultiLevelListNode curr = head;
30+
// Process each node at the current level. If a node has a child linked list,
31+
// append it to the tail and then update the tail to the end of the extended
32+
// linked list. Continue until all nodes at the current level are processed.
33+
while (curr != null) {
34+
if (curr.child != null) {
35+
tail.next = curr.child;
36+
// Disconnect the child linked list from the current node.
37+
curr.child = null;
38+
while (tail.next != null) {
39+
tail = tail.next;
40+
}
41+
}
42+
curr = curr.next;
43+
}
44+
return head;
45+
}
46+
}

java/Linked Lists/LRUCache.java

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
import java.util.HashMap;
2+
3+
class DoublyLinkedListNode {
4+
public int key;
5+
public int val;
6+
public DoublyLinkedListNode next;
7+
public DoublyLinkedListNode prev;
8+
public DoublyLinkedListNode(int key, int val) {
9+
this.key = key;
10+
this.val = val;
11+
}
12+
}
13+
14+
15+
public class LRUCache {
16+
public int capacity;
17+
public HashMap<Integer, DoublyLinkedListNode> cache;
18+
public DoublyLinkedListNode head;
19+
public DoublyLinkedListNode tail;
20+
public LRUCache(int capacity) {
21+
this.capacity = capacity;
22+
// A hash map that maps keys to nodes.
23+
cache = new HashMap<>();
24+
// Initialize the head and tail dummy nodes and connect them to
25+
// each other to establish a basic two-node doubly linked list.
26+
head = new DoublyLinkedListNode(-1, -1);
27+
tail = new DoublyLinkedListNode(-1, -1);
28+
head.next = tail;
29+
tail.prev = head;
30+
}
31+
32+
public int get(int key) {
33+
if (!cache.containsKey(key)) {
34+
return -1;
35+
}
36+
else {
37+
// To make this key the most recently used, remove its node and
38+
// re-add it to the tail of the linked list.
39+
remove(cache.get(key));
40+
addToTail(cache.get(key));
41+
return cache.get(key).val;
42+
}
43+
}
44+
45+
public void put(int key, int val) {
46+
// If a node with this key already exists, remove it from the
47+
// linked list.
48+
if (cache.containsKey(key)) {
49+
remove(cache.get(key));
50+
}
51+
DoublyLinkedListNode node = new DoublyLinkedListNode(key, val);
52+
cache.put(key, node);
53+
// Remove the least recently used node from the cache if adding
54+
// this new node will result in an overflow.
55+
if (cache.size() > capacity) {
56+
cache.remove(head.next.key);
57+
remove(head.next);
58+
}
59+
addToTail(node);
60+
}
61+
62+
private void addToTail(DoublyLinkedListNode node) {
63+
DoublyLinkedListNode prevNode = tail.prev;
64+
node.prev = prevNode;
65+
node.next = tail;
66+
prevNode.next = node;
67+
tail.prev = node;
68+
}
69+
70+
private void remove(DoublyLinkedListNode node) {
71+
node.prev.next = node.next;
72+
node.next.prev = node.prev;
73+
}
74+
75+
}
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
import DS.ListNode;
2+
3+
/*
4+
// Definition of ListNode:
5+
class ListNode {
6+
public int val;
7+
public ListNode next;
8+
public ListNode(int val) { this.val = val; }
9+
public ListNode(int val, ListNode next) {
10+
this(val);
11+
this.next = next;
12+
}
13+
}
14+
*/
15+
16+
17+
public class LinkedListIntersection {
18+
public static ListNode linkedListIntersection(ListNode headA, ListNode headB) {
19+
ListNode ptrA = headA;
20+
ListNode ptrB = headB;
21+
// Traverse through list A with 'ptrA' and list B with 'ptrB'
22+
// until they meet.
23+
while (ptrA != ptrB) {
24+
// Traverse list A -> list B by first traversing 'ptrA' and
25+
// then, upon reaching the end of list A, continue the
26+
// traversal from the head of list B.
27+
ptrA = ptrA == null ? headB : ptrA.next;
28+
// Simultaneously, traverse list B -> list A.
29+
ptrB = ptrB == null ? headA : ptrB.next;
30+
}
31+
// At this point, 'ptrA' and 'ptrB' either point to the
32+
// intersection node or both are null if the lists do not
33+
// intersect. Return either pointer.
34+
return ptrA;
35+
}
36+
}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
import DS.ListNode;
2+
3+
/*
4+
// Definition of ListNode:
5+
class ListNode {
6+
public int val;
7+
public ListNode next;
8+
public ListNode(int val) { this.val = val; }
9+
public ListNode(int val, ListNode next) {
10+
this(val);
11+
this.next = next;
12+
}
13+
}
14+
*/
15+
16+
17+
public class LinkedListReversal {
18+
public static ListNode linkedListReversal(ListNode head) {
19+
ListNode currNode = head;
20+
ListNode prevNode = null;
21+
// Reverse the direction of each node's pointer until 'currNode'
22+
// is null.
23+
while (currNode != null) {
24+
ListNode nextNode = currNode.next;
25+
currNode.next = prevNode;
26+
prevNode = currNode;
27+
currNode = nextNode;
28+
}
29+
// 'prevNode' will be pointing at the head of the reversed linked
30+
// list.
31+
return prevNode;
32+
}
33+
}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
import DS.ListNode;
2+
3+
/*
4+
// Definition of ListNode:
5+
class ListNode {
6+
public int val;
7+
public ListNode next;
8+
public ListNode(int val) { this.val = val; }
9+
public ListNode(int val, ListNode next) {
10+
this(val);
11+
this.next = next;
12+
}
13+
}
14+
*/
15+
16+
17+
public class LinkedListReversalRecursive {
18+
public static ListNode linkedListReversalRecursive(ListNode head) {
19+
// Base cases.
20+
if (head == null || head.next == null) return head;
21+
else {
22+
// Recursively reverse the sublist starting from the next node.
23+
ListNode newHead = linkedListReversalRecursive(head.next);
24+
// Connect the reversed linked list to the head node to fully
25+
// reverse the entire linked list.
26+
head.next.next = head;
27+
head.next = null;
28+
return newHead;
29+
}
30+
}
31+
}
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
import DS.ListNode;
2+
3+
/*
4+
// Definition of ListNode:
5+
class ListNode {
6+
public int val;
7+
public ListNode next;
8+
public ListNode(int val) { this.val = val; }
9+
public ListNode(int val, ListNode next) {
10+
this(val);
11+
this.next = next;
12+
}
13+
}
14+
*/
15+
16+
17+
public class PalindromicLinkedList {
18+
public static boolean palindromicLinkedList(ListNode head) {
19+
// Find the middle of the linked list and then reverse the second half of the
20+
// linked list starting at this midpoint.
21+
ListNode mid = findMiddle(head);
22+
ListNode secondHead = reverseList(mid);
23+
// Compare the first half and the reversed second half of the list
24+
ListNode ptr1 = head;
25+
ListNode ptr2 = secondHead;
26+
boolean result = true;
27+
while (ptr2 != null) {
28+
if (ptr1.val != ptr2.val) {
29+
result = false;
30+
}
31+
ptr1 = ptr1.next;
32+
ptr2 = ptr2.next;
33+
}
34+
return result;
35+
}
36+
37+
// From the 'Reverse Linked List' problem.
38+
private static ListNode reverseList(ListNode head) {
39+
ListNode currNode = head;
40+
ListNode prevNode = null;
41+
while (currNode != null) {
42+
ListNode nextNode = currNode.next;
43+
currNode.next = prevNode;
44+
prevNode = currNode;
45+
currNode = nextNode;
46+
}
47+
return prevNode;
48+
}
49+
50+
// From the 'Linked List Midpoint' problem.
51+
private static ListNode findMiddle(ListNode head) {
52+
ListNode p1 = head;
53+
ListNode p2 = head;
54+
while (p2 != null && p2.next != null) {
55+
p1 = p1.next;
56+
p2 = p2.next.next;
57+
}
58+
return p1;
59+
}
60+
}
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
import DS.ListNode;
2+
3+
/*
4+
// Definition of ListNode:
5+
class ListNode {
6+
public int val;
7+
public ListNode next;
8+
public ListNode(int val) { this.val = val; }
9+
public ListNode(int val, ListNode next) {
10+
this(val);
11+
this.next = next;
12+
}
13+
}
14+
*/
15+
16+
17+
public class RemoveKthLastNode {
18+
public static ListNode removeKthLastNode(ListNode head, int k) {
19+
// A dummy node to ensure there's a node before 'head' in case we
20+
// need to remove the head node.
21+
ListNode dummy = new ListNode(-1);
22+
dummy.next = head;
23+
ListNode trailer = dummy;
24+
ListNode leader = head;
25+
// Advance 'leader' k steps ahead.
26+
for (int i = 0; i < k; i++) {
27+
leader = leader.next;
28+
// If k is larger than the length of the linked list, no node
29+
// needs to be removed.
30+
if (leader == null) {
31+
return head;
32+
}
33+
}
34+
// Move 'leader' to the end of the linked list, keeping 'trailer'
35+
// k nodes behind.
36+
while (leader.next != null) {
37+
leader = leader.next;
38+
trailer = trailer.next;
39+
}
40+
// Remove the kth node from the end.
41+
trailer.next = trailer.next.next;
42+
return dummy.next;
43+
}
44+
}

0 commit comments

Comments
 (0)