Skip to main content

Linked Lists

  • Understanding linked lists
  • Solved problems are presented in alphabetical order
Intersection of Two Linked Lists

↗ See LeetCode Problem #160

//  Needs to work on intersection of linked listsclass ListNode {    int data;    ListNode next;    ListNode (int data) {        this.data = data;    }}public class Solution {/** * Definition for singly-linked list. * public class ListNode { *     int val; *     ListNode next; *     ListNode(int x) { *         val = x; *         next = null; *     } * } */    static ListNode getIntersectionNode(ListNode headA, ListNode headB) {        if (headA == null || headB == null) {            return null;        }        ListNode a_pointer = headA;        ListNode b_pointer = headB;        while (a_pointer != b_pointer) {            a_pointer = a_pointer == null ? headB : a_pointer.next;            b_pointer = b_pointer == null ? headA : b_pointer.next;        }        return a_pointer;    }    public static void main(String[] args) {        //Input: intersectVal = 8, listA = [4,1,8,4,5], listB = [5,6,1,8,4,5], skipA = 2        //, skipB = 3        //Output: Intersected at '8'        //Explanation: The intersected node's value is 8 (note that this must not be 0        //if the two lists intersect).        //From the head of A, it reads as [4,1,8,4,5]. From the head of B, it reads as [        //5,6,1,8,4,5]. There are 2 nodes before the intersected node in A; There are 3        //nodes before the intersected node in B.        //        //        // Example 2:        //        //        //Input: intersectVal = 2, listA = [1,9,1,2,4], listB = [3,2,4], skipA = 3,        //skipB = 1        //Output: Intersected at '2'        //Explanation: The intersected node's value is 2 (note that this must not be 0        //if the two lists intersect).        //From the head of A, it reads as [1,9,1,2,4]. From the head of B, it reads as [        //3,2,4]. There are 3 nodes before the intersected node in A; There are 1 node        //before the intersected node in B.        //        //        // Example 3://        int[] listA = {2,6,4};        int[] listA = {1,9,1,2,4};//        int[] listB = {1,5};        int[] listB = {3,2,4};        //  O/P: No intersection        ListNode head3A = new ListNode(listA[0]);        ListNode current3A = head3A;        for (int i = 1; i < listA.length; i++) {            ListNode node = new ListNode(listA[i]);            current3A.next = node;            current3A = node;        }        ListNode head3B = new ListNode(listB[0]);        ListNode current3B = head3B;        for (int i = 1; i < listB.length; i++) {            ListNode node = new ListNode(listB[i]);            current3B.next = node;            current3B = node;        }        System.out.println(getIntersectionNode(head3A,head3B));   }}
Linked List Cycle

↗ See LeetCode Problem #141

//  Needs work to make Linked list cycleclass ListNode {    int data;    ListNode next;    ListNode (int data) {        this.data = data;    }}public class Solution {/** * Definition for singly-linked list. * class ListNode { *     int val; *     ListNode next; *     ListNode(int x) { *         val = x; *         next = null; *     } * } */    static boolean hasCycle(ListNode head) {        ListNode slow = head;        ListNode fast = head;        while (fast != null && fast.next != null) {            slow = slow.next;            fast = fast.next.next;            if (fast == slow) {                return true;            }        }        return false;    }    public static void main(String[] args) {        int[] head1Array = {3,2,0,-4};        int pos1 = 1;        //  O/P: true        ListNode head1 = new ListNode(head1Array[0]);        ListNode current1 = head1;        ListNode startNode1 = new ListNode(head1Array[pos1]);//        for (int i = 1; i < head1Array.length; i++) {////            ListNode node = new ListNode(head1Array[i]);////            current1.next = node;//            current1 = node;//        }////        current1.next = new ListNode(head1Array[1]);        int count1 = 1;        while(current1.next != null) {           if (count1 == pos1) {               startNode1 = current1;           }           current1 = current1.next;           count1++;        }        current1.next = startNode1;        // Example 2:        int[] head2Array = {1,2};        //int pos2 = 0;        //  O/P: true        ListNode head2 = new ListNode(head2Array[0]);        ListNode current2 = head2;        for (int i = 1; i < head2Array.length; i++) {            ListNode node = new ListNode(head2Array[i]);            current2.next = node;            current2 = node;        }        // Example 3:        int[] head3Array = {1};        //int pos3 = -1;        //  O/P: false        ListNode head3 = new ListNode(head3Array[0]);        ListNode current3 = head3;        for (int i = 1; i < head3Array.length; i++) {            ListNode node = new ListNode(head3Array[i]);            current3.next = node;            current3 = node;        }        System.out.println("Example 1: " + hasCycle(head1));        System.out.println("Example 2: " + hasCycle(head2));        System.out.println("Example 3: " + hasCycle(head3));    }}
LRU Cache

↗ See LeetCode Problem #146

import java.util.Map;import java.util.HashMap;class LRUCache {    class DoublyLinkedNode {        int key;        int value;        DoublyLinkedNode previousNode;        DoublyLinkedNode nextNode;    }    private Map<Integer, DoublyLinkedNode> cacheMap = new HashMap<>();    private int cacheSize;    private int cacheCapacity;    private DoublyLinkedNode head;    private DoublyLinkedNode tail;    //  Add node at the front but after the dummy head node    private void addNode(DoublyLinkedNode node) {        node.previousNode = head;        node.nextNode = head.nextNode;        head.nextNode.previousNode = node;        head.nextNode = node;    }    private void removeNode(DoublyLinkedNode node) {        DoublyLinkedNode previousNode = node.previousNode;        DoublyLinkedNode nextNode = node.nextNode;        previousNode.nextNode = nextNode;        nextNode.previousNode = previousNode;    }    //  Move an existing node at the front but after the dummy head node    private void moveToFront(DoublyLinkedNode node) {        removeNode(node);        addNode(node);    }    //  Remove the last node, which is an existing node    //      right before the dummy tail    private DoublyLinkedNode popEndNode() {        DoublyLinkedNode endNode = tail.previousNode;        removeNode(endNode);        return endNode;    }    public LRUCache(int capacity) {        this.cacheSize = 0;        this.cacheCapacity = capacity;        head = new DoublyLinkedNode();        tail = new DoublyLinkedNode();        head.nextNode = tail;        tail.previousNode = head;    }    public int get(int key) {        DoublyLinkedNode node = cacheMap.get(key);        if (node == null) {            return -1;        }        moveToFront(node);        return node.value;    }    public void put(int key, int value) {        DoublyLinkedNode node = cacheMap.get(key);        if (node == null) {            DoublyLinkedNode updatedNode = new DoublyLinkedNode();            updatedNode.key = key;            updatedNode.value = value;            cacheMap.put(key, updatedNode);            addNode(updatedNode);            //  Increase the size the LRUCache by 1            ++cacheSize;            if (cacheSize > cacheCapacity) {                DoublyLinkedNode endNode = popEndNode();                cacheMap.remove(endNode.key);                //  Decrease the size the LRUCache by 1                --cacheSize;            }        } else {            node.value = value;            moveToFront(node);        }    }}class Solution {    public static void main(String[] args) {        // Example 1:        //Input        //["LRUCache", "put", "put", "get", "put", "get", "put", "get", "get", "get"]        //[[2], [1, 1], [2, 2], [1], [3, 3], [2], [4, 4], [1], [3], [4]]        LRUCache lruCache = new LRUCache(2);        lruCache.put(1, 1);        lruCache.put(2, 2);        System.out.println(lruCache.get(1));        lruCache.put(3, 3);        System.out.println(lruCache.get(2));        lruCache.put(4, 4);        System.out.println(lruCache.get(1));        System.out.println(lruCache.get(3));        System.out.println(lruCache.get(4));        //Output        //[null, null, null, 1, null, -1, null, -1, 3, 4]        //        //Explanation        //LRUCache lRUCache = new LRUCache(2);        //lRUCache.put(1, 1); // cache is {1=1}        //lRUCache.put(2, 2); // cache is {1=1, 2=2}        //lRUCache.get(1);    // return 1        //lRUCache.put(3, 3); // LRU key was 2, evicts key 2, cache is {1=1, 3=3}        //lRUCache.get(2);    // returns -1 (not found)        //lRUCache.put(4, 4); // LRU key was 1, evicts key 1, cache is {4=4, 3=3}        //lRUCache.get(1);    // return -1 (not found)        //lRUCache.get(3);    // return 3        //lRUCache.get(4);    // return 4    }}/** * Your LRUCache object will be instantiated and called as such: * LRUCache obj = new LRUCache(capacity); * int param_1 = obj.get(key); * obj.put(key,value); */
Merge Two Sorted Lists

↗ See LeetCode Problem #21

class ListNode {    int data;    ListNode next;    ListNode(int num) {        this.data = num;        this.next = null;    }}public class Solution {    /**     * 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; }     * }     */    static ListNode merge(ListNode head1, ListNode head2) {        ListNode mergedList;        if (head1 == null) {            return head2;        }        if (head2 == null) {            return head1;        }        if (head1.data < head2.data) {            //point to smaller element            mergedList = head1;            mergedList.next = merge(head1.next, head2);        } else { //head1 is large, so pass h            //point to smaller element            mergedList = head2;            //head2 is already considered            //now process next node of head2            mergedList.next = merge(head1, head2.next);        }        return mergedList;    }    static int countNodes (ListNode head) {        int count = 1;        ListNode current = head;        while (current.next != null){            current = current.next;            count++;        }        return count;    }    public static void main(String[] args) {        //  Example 1:        //  Output: [1,1,2,3,4,4]        //  Input: list1 = [1,2,4], list2 = [1,3,4]//        int[] ex1data1 = {1,2,4};        int[] ex1data1 = {2, 4, 5};        ListNode head1ex1 = new ListNode(ex1data1[0]);        ListNode current1Ex1 = head1ex1;        for (int i = 1; i < ex1data1.length; i++) {            ListNode node = new ListNode(ex1data1[i]);            current1Ex1.next = node;            current1Ex1 = node;        }        System.out.println("Ex1 (Head 1) - # of Nodes: " + countNodes(head1ex1));//        int[] ex1data = {1,3,4};        int[] ex1data2 = {3,4,6,7};        ListNode head2ex1 = new ListNode(ex1data2[0]);        ListNode current2Ex1 = head2ex1;        for (int i = 1; i < ex1data2.length; i++) {            ListNode node = new ListNode(ex1data2[i]);            current2Ex1.next = node;            current2Ex1 = node;        }        System.out.println("Ex1 (Head 2) - # of Nodes: " + countNodes(head2ex1));        ListNode mergedListEx1 = merge(head1ex1, head2ex1);        System.out.println("Ex1 (merged list) - # of Nodes: " + countNodes(mergedListEx1));        System.out.println("Ex1 (merged list) - Head: " + mergedListEx1.data);        System.out.println();        int[] ex2data1 = {1, 3, 5, 9};        ListNode head1ex2 = new ListNode(ex2data1[0]);        ListNode current1Ex2 = head1ex2;        for (int i = 1; i < ex2data1.length; i++) {            ListNode node = new ListNode(ex2data1[i]);            current1Ex2.next = node;            current1Ex2 = node;        }        System.out.println("Ex2 (Head 1) - # of Nodes: " + countNodes(head1ex2));        int[] ex2data2 = {2, 4, 5, 6, 10};        ListNode head2ex2 = new ListNode(ex2data2[0]);        ListNode current2Ex2 = head2ex2;        for (int i = 1; i < ex2data2.length; i++) {            ListNode node = new ListNode(ex2data2[i]);            current2Ex2.next = node;            current2Ex2 = node;        }        System.out.println("Ex2 (Head 2) - # of Nodes: " + countNodes(head2ex2));        ListNode mergedListEx2 = merge(head1ex2, head2ex2);        System.out.println("Ex2 (merged list) - # of Nodes: " + countNodes(mergedListEx2));        System.out.println("Ex2 (merged list) - Head: " + mergedListEx2.data);        //  Example 2:        //  Output: []        //  Input: list1 = [], list2 = []        //  Example 3:        //  Input: list1 = [], list2 = [0]        //  Output: [0]    }}
Middle of the Linked List

↗ See LeetCode Problem #876

class ListNode {    int data;    ListNode next;    ListNode (int data) {        this.data = data;    }}public class Solution {    /**     * 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; }     * }     */    static ListNode head;    static ListNode tail;//    static ListNode findMiddleNode(ListNode head) {    static int findMiddleNode(ListNode head) {        ListNode fast = head;        ListNode slow = head;        while (fast != null && fast.next != null) {            fast = fast.next.next;            slow = slow.next;        }//        return slow;        return slow.data;    }    static int countNodes (ListNode head) {        int count = 1;        ListNode current = head;            while (current.next != null){                current = current.next;                count++;            }        return count;    }    public static void main(String[] args) {        //  Input: head = [1,2,3,4,5]        //  Output: [3,4,5]        int[] dataArray = {1, 2, 3, 4, 5};        ListNode head = new ListNode(dataArray[0]);        ListNode current = head;        for (int i = 1; i < dataArray.length; i++) {            ListNode node = new ListNode(dataArray[i]);            current.next = node;            current = node;        }        System.out.println(countNodes(head));        System.out.println(findMiddleNode(head));    }}
Palindrome Linked List

↗ See LeetCode Problem #234

public class Solution {    public static void main(String[] args) {        System.out.println("Hello, world!");    }}
Remove Nth Node from End of List

↗ See LeetCode Problem #19

class ListNode {    int val;    ListNode next;    ListNode(int val) {        this.val = val;        this.next = null;    }}public class Solution {/** * 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; } * } *///    static ListNode removeNthFromEnd(ListNode head, int n) {    static int removeNthFromEnd(ListNode head, int n) {        ListNode dummy = new ListNode(0);        dummy.next = head;        ListNode first = dummy;        ListNode second = dummy;        for (int i = 1; i <= n + 1; i++) {            first = first.next;        }        while (first != null) {            first = first.next;            second = second.next;        }        second.next = second.next.next;//        return dummy.next;        return dummy.next.val;    }    static int countNodes (ListNode head) {        int count = 1;        ListNode current = head;        while (current.next != null){            current = current.next;            count++;        }        return count;    }    public static void main(String[] args) {        //Input: head = [1,2,3,4,5], n = 2        //Output: [1,2,3,5]        int[] valArray = {1, 2, 3, 4, 5};        int n = 2;        ListNode head = new ListNode(valArray[0]);        ListNode current = head;        for (int i = 1; i < valArray.length; i++) {            ListNode node = new ListNode(valArray[i]);            current.next = node;            current = node;        }        System.out.println(countNodes(head));        System.out.println(removeNthFromEnd(head, n));    }}
Reorder List

↗ See LeetCode Problem #143

class ListNode {    int data;    ListNode next;    ListNode(int data) {        this.data = data;    }}public class Solution {/** * 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 {    static void reorderList(ListNode head) {        if (head == null) {            return;        }        //  find the middle node        //  middle node is =slow=        ListNode slow = head;        ListNode fast = head;        while (fast != null && fast.next != null) {            slow = slow.next;            fast = fast.next.next;        }        //  reverse the second part of the list node in-place        //  head of the reversed linked-list is =prev=        ListNode prev = null;        ListNode current = slow;        while (current != null) {            ListNode next = current.next;            current.next = prev;            prev = current;            current = next;        }        //  merge two sorted lists        ListNode first = head;        ListNode second = prev;        while (second.next != null) {            ListNode next = first.next;            first.next = second;            first = next;            next = second.next;            second.next = first;            second = next;        }        //  Output the head        System.out.println(head.data);    }    public static void main(String[] args) {        // Example 1:        //Input: head = [1,2,3,4]        //  O/P: [1,4,2,3]        // Example 2:        //Input: head = [1,2,3,4,5]        //  O/P: [1,5,2,4,3]        int[] dataArray1 = {1, 2, 3, 4};        ListNode head1 = new ListNode(dataArray1[0]);        ListNode current1 = head1;        for (int i = 1; i < dataArray1.length; i++) {            ListNode node = new ListNode(dataArray1[i]);            current1.next = node;            current1 = node;        }        int[] dataArray2 = {1, 2, 3, 4, 5};        ListNode head2 = new ListNode(dataArray2[0]);        ListNode current2 = head2;        for (int i = 1; i < dataArray2.length; i++) {            ListNode node = new ListNode(dataArray2[i]);            current2.next = node;            current2 = node;        }        reorderList(head1);        reorderList(head2);    }}
Palindrome Linked List

↗ See LeetCode Problem #234

class ListNode {    int data;    ListNode next;    ListNode (int data) {        this.data = data;    }}public class Solution {/** * 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 {    static boolean isPalindrome(ListNode head) {        if (head == null) {            return true;        }        ListNode fast = head;        ListNode slow = head;        while (fast.next != null && fast.next.next != null) {            slow = slow.next;            fast = fast.next.next;        }        ListNode firstHalfHead = head;        ListNode secondHalfHead = reverseLinkedList(slow.next);        while (firstHalfHead != null && secondHalfHead != null){//            if (firstHalfHead.val != secondHalfHead.val) {            if (firstHalfHead.data != secondHalfHead.data) {                return false;            }            firstHalfHead = firstHalfHead.next;            secondHalfHead = secondHalfHead.next;        }        return true;    }    static private ListNode reverseLinkedList(ListNode head) {        ListNode current = head;        ListNode prev = null;        while (current != null) {            ListNode next = current.next;            current.next = prev;            prev = current;            current = next;        }        return prev;    }    public static void main(String[] args) {        // Example 1:        int[] head1Array = {1,2,2,1};        //  O/P: true        // Example 2:        int[] head2Array = {1,2};        //  O/P: false        ListNode head1 = new ListNode(head1Array[0]);        ListNode current1 = head1;        for (int i = 1; i < head1Array.length; i++) {            ListNode node = new ListNode(head1Array[i]);            current1.next = node;            current1 = node;        }        ListNode head2 = new ListNode(head1Array[0]);        ListNode current2 = head2;        for (int i = 1; i < head2Array.length; i++) {            ListNode node = new ListNode(head2Array[i]);            current2.next = node;            current2 = node;        }        System.out.println("Example 1: " + isPalindrome(head1));        System.out.println("Example 1: " + isPalindrome(head2));    }}
Reverse Linked List

↗ See LeetCode Problem #206

/** * 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 ListNode {    int data;    ListNode next;    ListNode(int data) {        this.data = data;        this.next = null;    }}//class LinkedList {////////}class Solution {//    static ListNode reverseList(ListNode head) {    static int reverseList(ListNode head) {        ListNode prev = null;        while (head != null) {            ListNode next = head.next;            head.next = prev;            prev = head;            head = next;        }//        return prev;        return prev.data;    }    static int countNodes (ListNode head) {        int count = 1;        ListNode current = head;        while (current.next != null){            current = current.next;            count++;        }        return count;    }    public static void main(String[] args) {        int[] headArray = {1,2,3,4,5};        ListNode head = new ListNode(headArray[0]);        ListNode current = head;        for (int i = 1; i < headArray.length; i++) {            ListNode node = new ListNode(headArray[i]);            current.next = node;            current = node;        }//        ListNode nodeA = new ListNode(1);//        ListNode nodeB = new ListNode(2);//        ListNode nodeC = new ListNode(3);//        ListNode nodeD = new ListNode(4);//        ListNode nodeE = new ListNode(5);////        nodeA.next = nodeB;//        nodeB.next = nodeC;//        nodeC.next = nodeD;//        nodeD.next = nodeE;        System.out.println(countNodes(head));        System.out.println(reverseList(head));//        System.out.println();//        System.out.println(countNodes(nodeA));//        System.out.println(reverseList(nodeA));    }}