From 14f81b64ed74abb4763a7ca4b786b6d07e827b1b Mon Sep 17 00:00:00 2001 From: Paridhi Malviya Date: Thu, 8 Jan 2026 11:42:37 -0600 Subject: [PATCH] Implement Set. Implement Min Stack --- .DS_Store | Bin 0 -> 6148 bytes ImplementSet.swift | 74 +++++++++++ min stack/LinkedListToStackAdapter.swift | 159 +++++++++++++++++++++++ min stack/MinStack.swift | 77 +++++++++++ 4 files changed, 310 insertions(+) create mode 100644 .DS_Store create mode 100644 ImplementSet.swift create mode 100644 min stack/LinkedListToStackAdapter.swift create mode 100644 min stack/MinStack.swift diff --git a/.DS_Store b/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..2320308c37da9335dc3c6d8db6e6dee63bebd45c GIT binary patch literal 6148 zcmeHKJ5B>J5S@V(i)gl_^c8Xg6D=pm1t5t8h%B23sAybrGmb#dNqF-C?J6#ikPt#M zlKsY>kG)S?+e1XWc-qW~S|V!D1X+}d$aK|o!II`wp{V*hpt;~hZVe`8R^WyfMDS!7eu04xY?d${ literal 0 HcmV?d00001 diff --git a/ImplementSet.swift b/ImplementSet.swift new file mode 100644 index 00000000..e9d62ab4 --- /dev/null +++ b/ImplementSet.swift @@ -0,0 +1,74 @@ +// +// S30Programs.swift +// DSA-Practice +// +// Created by Paridhi Malviya on 12/24/25. +// + + +//We are implementing Set with double hashing +class ImplementSet { + + //primary storage + private var storage: [[Bool]?] + //length of primary array + private var buckets: Int + //length of nested array + private var bucketItems: Int + + private func hash1(key: Int) -> Int { + //primary bucket + return key % buckets + } + + private func hash2(key: Int) -> Int { + //nested array bucket + return key / bucketItems + } + + + init() { + buckets = 1000 + bucketItems = 1000 + storage = Array(repeating: nil, count: buckets) + } + + //primary array contains the pointer to the nested array. + //secondary array contains the items which has the same hash1 value. To identify items uniquely in secondary array, apply hash2. After hash2, you will find an index, set that index's value to true. + //O(1) + func add(key: Int) { + let bucket = hash1(key: key) + + if (storage[bucket] == nil) { + //there is no nested arrey, so create a nested array + if (bucket == 0) { + storage[bucket] = Array(repeating: false, count: bucketItems + 1) + } else { + storage[bucket] = Array(repeating: false, count: bucketItems) + } + } + let bucketItem = hash2(key: key) + storage[bucket]![bucketItem] = true + } + + func remove(key: Int) { + //find out the primary array bucket + let bucket = hash1(key: key) + //if there is no nested array, just return. Wouldn't remove anything + if (storage[bucket] == nil) { + return + } + let bucketItem = hash2(key: key) + storage[bucket]![bucketItem] = false + } + + func contains(key: Int) -> Bool { + let bucket = hash1(key: key) + let bucketItem = hash2(key: key) + //if there is no nested array, return false + if (storage[bucket] == nil) { + return false + } + return storage[bucket]![bucketItem] + } +} diff --git a/min stack/LinkedListToStackAdapter.swift b/min stack/LinkedListToStackAdapter.swift new file mode 100644 index 00000000..ce4cfb25 --- /dev/null +++ b/min stack/LinkedListToStackAdapter.swift @@ -0,0 +1,159 @@ +// +// LinkedListToStackAdapter.swift +// DSA-Practice +// +// Created by Paridhi Malviya on 12/16/25. +// + +//Implement stack using linked list + +class LLNode { + var value: T + var next: LLNode? + + init(value: T, next: LLNode?) { + self.value = value + self.next = next + } +} + +class LLLinkedList { + private var head: LLNode? + private var tail: LLNode? + + var isEmpty: Bool { + return head == nil + } + + var count: Int { + var currentHead = head + var count = 0 + while (currentHead != nil) { + count += 1 + currentHead = currentHead?.next + } + return count + } + + init() { + + } +} + +extension LLLinkedList { + func append(value: T) { + let newNode = LLNode(value: value, next: nil) + if head == nil { + //means linkedlist is empty, so set the newnode as the head and tail both + tail = newNode + head = newNode + } else { + //if linked list is not empty then do normal appending + tail?.next = newNode + tail = newNode + } + } + + func prepend(value: T) { + let newNode = LLNode(value: value, next: nil) + if head == nil { + //linked list is empty + head = LLNode(value: value, next: nil) + tail = head + } else { + // linked list is not empty + newNode.next = head + head = newNode + } + } + + func removeFirstNode() -> LLNode? { + if (head == nil) { + //it means the ll is empty + return nil + } else { + //if the ll is not empty + let currentHead = head + if let nextNode = head?.next { + head = nextNode + } else if (head?.next == nil) { + head = nil + } + return currentHead + } + } + + var currentHead: LLNode? { + return head + } +} + +extension LLLinkedList: CustomStringConvertible { + var description: String { + var currentNode = head + var descString = "[" + while currentNode != nil { + descString += "\(String(describing: currentNode?.value))" + currentNode = currentNode?.next + if (currentNode != nil) { + descString += "," + } + } + return descString + "]" + } +} + +class StackUsingLL: CustomStringConvertible { + private var llList: LLLinkedList? + + init(llList: LLLinkedList) { + self.llList = llList + } + + func push(value: T) { + //append the first element at the start of the linked list + llList?.prepend(value: value) + } + + func pop() -> T? { + //remove the first node from the linked list and return it. + let removedItem = llList?.removeFirstNode() + return removedItem?.value + } + + func peek() -> T? { + return llList?.currentHead?.value + } + + func isEmpty() -> Bool { + return llList?.isEmpty ?? true + } + + var description: String { + var currentHead = llList?.currentHead + var descString = "[" + while (currentHead != nil) { + descString += "\(currentHead!.value)" + currentHead = currentHead!.next + if (currentHead != nil) { + descString += "," + } + } + return descString + "]" + } +} + +class LinkedListToStackAdapter { + + init() { + let stack = StackUsingLL(llList: LLLinkedList()) + stack.push(value: 2) + stack.push(value: 3) + stack.push(value: 6) + let poppedElement = stack.pop() + print("popped element \(poppedElement, default: "NA")") + let topElement = stack.peek() + print("topElement \(topElement, default: "NA")") + print("printed linked list \(stack.description)") + } +} diff --git a/min stack/MinStack.swift b/min stack/MinStack.swift new file mode 100644 index 00000000..c17e0b7f --- /dev/null +++ b/min stack/MinStack.swift @@ -0,0 +1,77 @@ +// +// ImplementMinStack.swift +// DSA-Practice +// +// Created by Paridhi Malviya on 12/24/25. +// + +//Min stack - supports push, pop, top and retrieving the minimum element in constant time. + +class MinStack { + + var stack: StackUsingLL = StackUsingLL(llList: LLLinkedList()) + + /* + Min stack maintains 1:1 mapping with the main element and the minimum element. + At the 4th push to the stack, min stack contains the minimum at the 4th index in all elements present at 0 to 4th index. + Either we cna maintain a min stack or can store a tuple in the main stack. Pair(current element, current minimum) + */ + var minStack: StackUsingLL = StackUsingLL(llList: LLLinkedList()) + + private var currentMin: Int + + init() { + self.currentMin = Int.max + self.minStack.push(value: self.currentMin) + } + + + //it will pop the top element + func pop() -> Int? { + if (!stack.isEmpty()) { + let topElement = stack.pop()! + let _ = minStack.pop() + currentMin = minStack.peek()! + return topElement + } + return nil + } + + //it will push the element + func push(val: Int) { + let minimum = min(currentMin, val) + stack.push(value: val) + minStack.push(value: minimum) + } + + //it will return the top element + func top() -> Int? { + return stack.peek() + } + + //it will return the min element in the stack + func getMin() -> Int { + return currentMin + //or can return minStack.peek() + } +} + +class ImplementMinStack { + + //Implement this stack using linked list because push and pop can happen in O(1) time cmplexity. + //Take 1 stack to keep min items. + + init() { + let items: [Any] = [12, 8, 10, 1, 2, "P", "P", 3, "P", "P", "P"] + + let minStack = MinStack() + for item in items { + if (item is Int) { + minStack.push(val: item as! Int) + } else { + let removedElement = minStack.pop() + print("removedElement \(String(describing: removedElement))") + } + } + } +}