From 62d048c8d6e1112e055b88ab33ecc7b0794b9cc2 Mon Sep 17 00:00:00 2001 From: Paridhi Malviya Date: Sun, 8 Feb 2026 19:09:03 -0600 Subject: [PATCH] Complete Linked-List 1 --- LinkedListCycleTwo.swift | 66 +++++++++++++++++++ RemoveNthElementFromLast.swift | 50 +++++++++++++++ ReverseLinkedList.swift | 114 +++++++++++++++++++++++++++++++++ 3 files changed, 230 insertions(+) create mode 100644 LinkedListCycleTwo.swift create mode 100644 RemoveNthElementFromLast.swift create mode 100644 ReverseLinkedList.swift diff --git a/LinkedListCycleTwo.swift b/LinkedListCycleTwo.swift new file mode 100644 index 00000000..a3e50232 --- /dev/null +++ b/LinkedListCycleTwo.swift @@ -0,0 +1,66 @@ +// +// CyclicLinkedList.swift +// DSA-Practice +// +// Created by Paridhi Malviya on 1/15/26. +// + +/* + O(n) + O(n) + use hashset having the nodes especially the node address. + Most of the linked list problems can be optimized with the extra space. + + Floyd's algorithm - + take a slow pointer and a fast pointer. + Move slow by 1x and fast by 2x + check if they have met or not. + + If they didn't meet and fast goes out of the list. then it's not cyclic. + think about the even and odd lenght linekd list. + for even length -> fast != nil + for odd length -> fast.next != nil + + In the first cycle -> the slow will be caught by fast one, no matter where slow and fast starts off. EVen if they are diagonally opposite, fast will be able to catch slow in the first cycle of slow. + + For 3x -> we can't guarantee that they will meet in optimal manner. + + How to figure out the head of the cycle -> + The distance of the head of the linked list is -> + O(2n), no extra space - O(1) + */ + +class CyclicLinkedList { + init() { + + } + + func detectCycle(_ head: LLNode?) -> LLNode? { + if (head?.next == nil) { + return nil + } + + var slow = head?.next + var fast = head?.next?.next + while(slow !== fast) { + if (fast?.next == nil || fast?.next?.next == nil) { + return nil + } + slow = slow?.next + fast = fast?.next?.next + } + + //slow and fast are meeting, so there is a cycle. now, iterate from head and the slow pointer, where both pointers meet, that would be the beginning of the cycle + fast = head + while (fast !== slow) { + fast = fast?.next + slow = slow?.next + } + return slow + } + + + func detectingTheHeadOfTheCycle() { + + } +} diff --git a/RemoveNthElementFromLast.swift b/RemoveNthElementFromLast.swift new file mode 100644 index 00000000..ddaf3aec --- /dev/null +++ b/RemoveNthElementFromLast.swift @@ -0,0 +1,50 @@ +// +// RemoveElementFromLast.swift +// DSA-Practice +// +// Created by Paridhi Malviya on 1/15/26. +// + +/* + Bruteforce - 2 pass algorithm - + first push all elements in the stack. Then don'r pick the element at the nth position and pick other eleent and form the linked list + + approach2 - > 2 pass algorithm. move through the linked to count the no of elemtns. + no of elements - n-> pos + now, traverse until the counter is pos. Then remove the next node. + + 1 pass algorithm - + use slow pointer, fast pointer - move th window until fast == nil. When fast =nil, at that moment, slow is at the position one step before the node I need to remove. I can remove the node. + to remove the last element, maintain a dummy node at the start of the linked list. + to remove the first node, dummy node will be useful. dummy.next = head of the linked list. + */ + +class RemoveNthNodeFromEnd { + + init() { + + } + + func removeNthFromEnd(_ head: ListNode?, _ n: Int) -> ListNode? { + var count = 0 + let dummy = ListNode(-1) + dummy.next = head + var slow: ListNode? = dummy + var fast: ListNode? = dummy + while (count <= n) { + fast = fast?.next + count += 1 + } + + while (fast != nil) { + fast = fast?.next + slow = slow?.next + } + let temp = slow?.next + slow?.next = slow?.next?.next + temp?.next = nil + return dummy.next + + } + +} diff --git a/ReverseLinkedList.swift b/ReverseLinkedList.swift new file mode 100644 index 00000000..feefbcc3 --- /dev/null +++ b/ReverseLinkedList.swift @@ -0,0 +1,114 @@ +// +// ReverseLinkedList.swift +// DSA-Practice +// +// Created by Paridhi Malviya on 1/15/26. +// + +/* + reverse linked list - + approach 1 -> store all nodes in stack and start unfolding the stack. + use array. put elements in array and then traverse from the end. + + In linked list problem, we can avoid using extra space. + + + using 3 pointers -> + current, previous, next + + before you lose the connection with the node, store it in a temp variable. + + Approach 3 -> recursion. O(n) space - for recursion stack + O(n) - time complexity + + */ + +public class ListNode { + public var val: Int + public var next: ListNode? + public init() { self.val = 0; self.next = nil; } + public init(_ val: Int) { self.val = val; self.next = nil; } + public init(_ val: Int, _ next: ListNode?) { self.val = val; self.next = next; } +} + +class ReverseLinkedList { + + func reverseList(_ head: LLNode?) -> LLNode? { + if (head == nil || head?.next == nil) { + return head + } + + var current = head //ListNode? + var prev: LLNode? //ListNode? + var temp: LLNode? + while(current != nil) { + temp = current?.next + current?.next = prev + prev = current + current = temp + } + return prev + } + + var result: LLNode? + func reverseListByRecursionUsingPointers(_ head: LLNode?) -> LLNode? { + var prev: LLNode? + reverse(head, prev: prev) + return result + } + + func reverse(_ current: LLNode?, prev: LLNode?) { + var prev = prev + var current = current + if (current == nil) { + result = prev + return + } + + let temp = current?.next + current?.next = prev + prev = current + current = temp + + reverse(current, prev: prev) + } + + //MARK: using in built recursion stack + + var newHead: LLNode? + func reverseUsingRecursionStack(_ head: LLNode?) -> LLNode? { + reverseRecursionStack(head) + return result + } + + func reverseRecursionStack(_ head: LLNode?) { + if (head == nil || head?.next == nil) { + newHead = head + return + } + reverseRecursionStack(head?.next) + head?.next?.next = head + head?.next = nil + return + } + + //MARK: using in built stack, using Node return type + func reverseListUsingNodeReturnType(_ head: ListNode?) -> ListNode? { + return reverseUsingNodeReturnType(head) + } + + //O(n) - time complexity, O(n)- recursion stack + func reverseUsingNodeReturnType(_ head: ListNode?) -> ListNode? { + if (head == nil || head?.next == nil) { + return head + } + //result is not parameter of recursion, so it will remain constant. If stack unfolds, the head will change, but result will remain constant. + let result = reverseUsingNodeReturnType(head?.next) + head?.next?.next = head + head?.next = nil + return result + } + + +} +