diff --git a/Problem1.java b/Problem1.java new file mode 100644 index 00000000..d52316dc --- /dev/null +++ b/Problem1.java @@ -0,0 +1,58 @@ +// Time Complexity : O(1) amortized for push, pop, peek, and empty +// Space Complexity : O(n) +// Did this code successfully run on Leetcode : Yes +// Any problem you faced while coding this : No major issues; understanding when to move elements between stacks was the key. + +// I used two stacks: 'in' for incoming elements and 'out' for removing elements. +// When popping or peeking, if 'out' is empty, I move all elements from 'in' to 'out' to maintain FIFO order. +// This ensures that each element is moved at most once between the stacks, giving amortized O(1) performance. + +class MyQueue { + Stack in; + Stack out; + + public MyQueue() { + in = new Stack<>(); + out = new Stack<>(); + + } + + public void push(int x) { + in.push(x); + + } + private void moveInToOut(){ + if(out.isEmpty()){ + while(!in.isEmpty()){ + out.push(in.pop()); + + } + } + } + + public int pop() { + moveInToOut(); + return out.pop(); + + } + + public int peek() { + moveInToOut(); + return out.peek(); + + } + + public boolean empty() { + return in.isEmpty() && out.isEmpty(); + + } +} + +/** + * Your MyQueue object will be instantiated and called as such: + * MyQueue obj = new MyQueue(); + * obj.push(x); + * int param_2 = obj.pop(); + * int param_3 = obj.peek(); + * boolean param_4 = obj.empty(); + */ diff --git a/Problem2.java b/Problem2.java new file mode 100644 index 00000000..8b9a1cd2 --- /dev/null +++ b/Problem2.java @@ -0,0 +1,107 @@ +// Time Complexity : +// put() = O(1) average, O(n) worst +// get() = O(1) average, O(n) worst +// remove() = O(1) average, O(n) worst +// +// Space Complexity : O(N) where N = number of inserted key-value pairs +// +// Did this code successfully run on Leetcode : Yes +// +// Any problem you faced while coding this : +// Understanding how to implement separate chaining using linked lists +// and handling collisions correctly. Also ensuring find() returns +// the previous node to simplify insert/update/remove operations. + +// Your code here along with comments explaining your approach + +class MyHashMap { + + // Node structure for each key-value pair + class Node { + int key, value; + Node next; + + Node(int key, int value) { + this.key = key; + this.value = value; + } + } + + // Bucket size (large enough to minimize collisions) + private final int SIZE = 10000; + private Node[] buckets; + + public MyHashMap() { + buckets = new Node[SIZE]; + } + + // Hash function + private int hash(int key) { + return key % SIZE; + } + + // Helper function: returns previous node of the target key + private Node find(Node head, int key) { + Node prev = null; + Node curr = head; + + while (curr != null && curr.key != key) { + prev = curr; + curr = curr.next; + } + + return prev; + } + + public void put(int key, int value) { + int index = hash(key); + + // If bucket empty, create a dummy node + if (buckets[index] == null) { + buckets[index] = new Node(-1, -1); + } + + Node prev = find(buckets[index], key); + + // If the key does NOT exist, add new node + if (prev.next == null) { + prev.next = new Node(key, value); + } else { + // If key exists → update value + prev.next.value = value; + } + } + + public int get(int key) { + int index = hash(key); + + if (buckets[index] == null) return -1; + + Node prev = find(buckets[index], key); + + if (prev.next == null) return -1; + + return prev.next.value; + } + + public void remove(int key) { + int index = hash(key); + + if (buckets[index] == null) return; + + Node prev = find(buckets[index], key); + + // If key exists, delete it + if (prev.next != null) { + prev.next = prev.next.next; + } + } +} + +/** + * Your MyHashMap object will be instantiated and called as such: + * MyHashMap obj = new MyHashMap(); + * obj.put(key,value); + * int param_2 = obj.get(key); + * obj.remove(key); + */