diff --git a/.DS_Store b/.DS_Store new file mode 100644 index 000000000..5008ddfcf Binary files /dev/null and b/.DS_Store differ diff --git a/.gitignore b/.gitignore new file mode 100644 index 000000000..8c060ebce --- /dev/null +++ b/.gitignore @@ -0,0 +1,17 @@ +.DS_Store + +/generated/prisma +API +Models +mission8/ +mission9/ +mission6/ +mission5/ +mission4/ +mission3/ +mission2/ +typescripted/ +practiceForUser/ +book_rental_service/ +prc4/ +refactoring_code/ diff --git a/algorithm/BST/222-CountCompleteTreeNode.ts b/algorithm/BST/222-CountCompleteTreeNode.ts new file mode 100644 index 000000000..e69de29bb diff --git a/algorithm/BST/BinarySearchTree.py b/algorithm/BST/BinarySearchTree.py new file mode 100644 index 000000000..468854c7c --- /dev/null +++ b/algorithm/BST/BinarySearchTree.py @@ -0,0 +1,133 @@ +class Node(): + def __init__(self): + self.val: None + self.left: None + self.right: None + +class BinaryTree(): + def __init__(self): + self.stack = [] + self.que = [] + + def insert(self, value): + crnt = self.root + newNode = Node(value) + + if not self.root: + self.root = newNode + return + + while (crnt): + if crnt.val > newNode.val: + if crnt.left is None : + # leaf node 까지 가기 + crnt.left = newNode + break + crnt = crnt.left + else: + if crnt.right is None: + crnt.right = newNode + break + crnt = crnt.right + return + + def delete(self, value): + if not self.root: + return + crnt = self.root + parent = None + while crnt: + if crnt.val == value: + + # 삭제할 노드가 자식이 두개가 있는 경우 + if crnt.left and crnt.right: + result = self.findSuccessor(crnt) + parentOfSuccessor = result.parent + successor = result.succesor + parent = crnt + if parentOfSuccessor.left == successor: + parentOfSuccessor.left = successor.right + else: + parentOfSuccessor.left = successor.right + + else: + # 삭제할 노드가 자식이 한개가 있는 경우 + child = self.root.left or self.root.right + if crnt.left != None: + parent.left = child + # 삭제할 노드가 자식이 리프노드인 경우 + if value < crnt.val: + crnt = crnt.left + else: crnt = crnt.right + return crnt + def find(self, value): + if not self.root: return + + crnt = self.root + while crnt: + if value == crnt.val: + return crnt.val + elif value < crnt.val: + crnt = crnt.left + else: + crnt = crnt.right + + return crnt + def findSuccessor(self, node): + # 삭제할 노드에서 오른쪽 자식에서 가장 막내 증손주 찾기 + parent = node + crnt = node.right + while crnt.left: + parent = crnt + crnt = crnt.left + return crnt, parent + # traverse + def preOrder(self, node): + # NLR + if not self.root: + return + self.stack.append(node) + + while len(self.stack) > 0: + removed = self.stack.pop() + print(removed.val) + if removed.right: + self.stack.append(removed.right) + if removed.left: + self.stack.append(removed.left) + + def inOrder(self, node): + # LNR + if not node: + return + + self.stack.append(node) + while len(self.stack) > 0 or node: + while node: + self.stack.append(node) + node = node.left + + node = self.stack.pop() + print(node.val) + + node = node.right + + def postOrder(self): + if not self.root: + return + + stack1 = [self.root] + stack2 = [] + + while len(stack1) > 0: + node = stack1.pop() + stack2.append(node) + + if node.left: + stack1.append(node.left) + if node.right: + stack1.append(node.right) + + while len(stack2) > 0: + node = stack2.pop() + print(node) diff --git a/algorithm/BST/BinarySearchTree.ts b/algorithm/BST/BinarySearchTree.ts new file mode 100644 index 000000000..a8ce6f9a3 --- /dev/null +++ b/algorithm/BST/BinarySearchTree.ts @@ -0,0 +1,161 @@ +type BstNode = { + val: T | null; + left: BstNode | null; + right: BstNode | null; +}; + +class Bst { + constructor( + private root: BstNode | null = null, + private compare: (a: T, b: T) => number, + private stack : BstNode[] = [], + private queue: T[] = [] + ) {} + insert(value: T) { + let crnt = this.root; + const newNode: BstNode = { + val: value, + left: null, + right: null, + }; + if (!this.root) { + this.root = newNode; + return; + } + while (crnt) { + let cmp = this.compare(value, crnt.val!); + if (cmp < 0) { + if (!crnt.left) { + crnt.left = newNode; + break; + } + crnt = crnt.left; + } else if (cmp > 0) { + if (!crnt.right) { + crnt.right = newNode; + break; + } + crnt = crnt.right; + } else { + break; + } + } + } + delete(value:T): BstNode | null { + let crnt = this.root + if (!this.root) return null + let parent = null + while(crnt){ + let cmp = this.compare(value, crnt.val!) + let child = crnt.left ?? crnt.right + // 삭제할 노드 조건 분기 + if(cmp === 0){ + // 삭제할 현재 노드가 자식이 두개가 있는 경우 + if(crnt.left && crnt.right){ + let result = this.findSuccessor(crnt)! + let successor = result.successor + let parentSuccessor = result.parent + crnt.val = successor.val + if(parentSuccessor.left === successor) parentSuccessor.left = successor.right + if(parentSuccessor.right === successor)parentSuccessor.right = successor.right + }else{ + // 삭제할 현재 노드가 리프 노드인 경우 + if(!parent) this.root = child + + // 삭제할 현재 노드가 하나의 자식이 있는 경우 + if(parent!.left === crnt){ // 삭제할 노드에 왼쪽자식이 있는 경우 + parent!.left = child // 삭제할 노드 부모 왼쪽에 삭제 노드 오른쪽에서 가장 작은 자식 대체 + }else{ + parent!.right = child + } + } + return this.root + } + parent = crnt // 이동전 저장 + if(cmp < 0) crnt = crnt.left + else crnt = crnt.right + } + return this.root + } + find(value: T) { + let crnt = this.root + while(crnt){ + let cmp = this.compare(value, crnt.val!) + if(cmp === 0){ + return crnt.val; + } + else if(cmp < 0){ + crnt = crnt.left + } + else { + crnt = crnt.right + } + } + return null + } + findSuccessor(node:BstNode) { + // 삭제할 노드의 오른쪽 자식에서 가장 작은 값(왼쪽) 찾기 + let parent = node + let crnt = node.right + if(!crnt) return null + while(crnt!.left){ + parent = crnt + crnt = crnt!.left + } + return {successor: crnt, parent} + } + + preOrderIterative(){ + if(!this.root) return null; + + let node = this.root + this.stack.push(node) + while(this.stack.length > 0){ + let removed = this.stack.pop() + console.log(removed!.val) + if(node.left){ + this.stack.push(node.left) + } + else { + this.stack.push(node.right!) + } + } + + } + + inOrderIterative(){ + if(!this.root) return null; + let crnt = this.root + this.stack.push(crnt) + while(this.stack.length > 0 || crnt){ + while(crnt){ + this.stack.push(crnt) + crnt = crnt.left! + } + let node = this.stack.pop() + console.log(node!.val) + crnt = node!.right! + } + } + + postOrderIterative(){ + if(!this.root) return null; + const stack1:(BstNode | undefined)[] = [this.root] + const stack2: (BstNode | undefined)[] = [] + + while(stack1.length > 0){ + const node = stack1.pop()! + stack2.push(node); + + if(node.left) stack1.push(node.left) + + if (node.right) stack1.push(node.right); + } + while(stack2.length > 0){ + const node = stack2.pop() + console.log(node) + } + } + + levelOrderIterative(){} +} \ No newline at end of file diff --git a/algorithm/Backtracking/78-subset.py b/algorithm/Backtracking/78-subset.py new file mode 100644 index 000000000..d5db7843d --- /dev/null +++ b/algorithm/Backtracking/78-subset.py @@ -0,0 +1,14 @@ +def subsetIterative(nums): + stack = [[[],0]] + result = [] + n = len(nums) + while len(stack) > 0: + [path, start] = stack.pop() + result.append(path) + + for i in range(start, n): + crntPath = path + nums[i] + path.append([crntPath, i + 1]) + + return result + diff --git a/algorithm/Backtracking/78-subset.ts b/algorithm/Backtracking/78-subset.ts new file mode 100644 index 000000000..a0f1fc274 --- /dev/null +++ b/algorithm/Backtracking/78-subset.ts @@ -0,0 +1,68 @@ +function subsets(nums: number[]): number[][] { + let stack: [number[],number][] = [[[],0]]; + let result: number[][] = []; + const n = nums.length; + while(stack.length > 0){ + let [path, start] = stack.pop()!; + result.push(path) + for(let i = start; i < n; i++){ + let crntPath = [...path, nums[i]] + stack.push([crntPath, i + 1]) + } + } + return result +}; + +function subsetsBT(nums: number[]): number[][] { + const result: number[][] = [] + const n: number = nums.length + function bt(path : number[], start: number){ + result.push([...path])// 값넣기 + + for(let i = start; i < n; i++){ + path.push(nums[i]) // 선택 + bt(path, i + 1) + path.pop() // 선택 해제 + } + } + bt([],0) + return result +}; + +/* + +* decison space + [] + / | \ + [1] [2] [3] + / \ / \ + [1,2] [1,3] [2,3] + + [1, 2, 3] + + +stack [[[1], 1], [[2], 2],[[3], 3]] + +stack.pop() +the result = [[],[3]] +stack = [[[1], 1], [[2], 2]] + +stack.pop() +stack = [[], 0], [[1], 1]] +result = [[], [3], [2]] +stack.push (path + previous path) +stack = [[[1], 1], [[2,3], 3]] + +stack.pop() +stack = [ [[1], 1]] +result = [[], [2], [3], [2,3]] + +stack.push([[1, 2], 2], [[1, 3], 3]) + +stack.pop() +result = [[], [2], [3], [2, 3], [1, 3]] + + +*/ + + diff --git a/algorithm/DynamicProgramming/62-UniquePath.py b/algorithm/DynamicProgramming/62-UniquePath.py new file mode 100644 index 000000000..615b68e12 --- /dev/null +++ b/algorithm/DynamicProgramming/62-UniquePath.py @@ -0,0 +1,30 @@ +def UniquePathByTab(m, n): + dp = [[0 for _ in range(n)] for _ in range(m)] + for i in range(n): + dp[0][i] = 1 + + for j in range(m): + dp[j][0] = 1 + + for i in range(1, m): + for j in range(1, n): + dp[i][j] = dp[i-1][j] + dp[i][j-1] + return dp[m-1][n-1] + +def UniquePathByMemo(m, n): + memo = [[-1 for _ in range(m)] for _ in range(n)] # 해당 경로가 방문하지 않는 경우 -1로 표시 + + for i in range(n): + memo[i][0] = 1 + + for j in range(m): + memo[0][j] = 1 + + def dfs(i, j): + if memo[i][j] == -1: + memo[i][j] = dfs(i-1, j) + dfs(i, j-1) + return memo[i][j] + + return dfs(n -1, m - 1) + +print(UniquePathByMemo(7, 3)) \ No newline at end of file diff --git a/algorithm/DynamicProgramming/62-UniquePath.ts b/algorithm/DynamicProgramming/62-UniquePath.ts new file mode 100644 index 000000000..3ca1c6ab5 --- /dev/null +++ b/algorithm/DynamicProgramming/62-UniquePath.ts @@ -0,0 +1,43 @@ +// problem defintion: +// general case = f(x, y) = f(x - 1, y) + f(x, y - 1) +// sub case = if x === 0 or y === 0, return 1 +/* approaching: + 1. memorization + 2.tabulation(bottom up) + 3. stack +*/ + +// tabulation && morization +// time complexity O(m * n) +// space complexity O(m * n) +function findUniqueByTab(m: number, n: number): number { + const dp = new Array(m).fill(0).map(() => new Array(n).fill(0)) + + for(let i = 0; i < m; i++ ){ + dp[i][0] = 1 + } + for(let j = 0; j < n; j++ ){ + dp[0][j] = 1 + } + for(let i = 1; i< m; i++ ){ + for(let j = 1; j< n; j++ ){ + dp[i][j] = dp[i - 1][j]+ dp[i][j - 1] + } + } + return dp[m - 1][n - 1] +} +console.log(findUniqueByTab(7, 3)) + +function findUniqueByMemo(m: number, n: number): number { + const dp = new Array(m).fill(0).map(() => new Array(n).fill(-1)) + function dfs(i:number, j: number){ + if(i === 0 || j === 0) return 1; + + if(dp[i][j] !== -1) return dp[i][j] + + dp[i][j] = dfs(i -1, j)+ dfs(i, j - 1) + return dp[i][j] + } + return dfs(m-1,n-1) +} +console.log(findUniqueByMemo(7, 3)) \ No newline at end of file diff --git a/algorithm/Graph/DFS/841-KeysAndRooms.ts b/algorithm/Graph/DFS/841-KeysAndRooms.ts new file mode 100644 index 000000000..852debe06 --- /dev/null +++ b/algorithm/Graph/DFS/841-KeysAndRooms.ts @@ -0,0 +1,34 @@ +function hasVisitedAllRooms(rooms:number[][]){ + const visited = new Set() + function dfs(room: number){ + if(visited.has(room))return; + visited.add(room) + + for(let keys of rooms[room]){ + dfs(keys) + } + } + dfs(0) + return visited.size === rooms.length; +} + +let result = hasVisitedAllRooms([[1],[2],[3],[]]) +console.log(result) + +function iterative(rooms:number[][]){ + const stack: number[] = [0] + const seen = new Set(); + + while(stack.length > 0){ + const room = stack.pop()! + if (seen.has(room)) continue + seen.add(room) + for(let key of rooms[room]){ + stack.push(key) + } + } + return seen.size === rooms.length +} + +let result2 = iterative([[1],[2],[3],[]]) +console.log(result2) \ No newline at end of file diff --git a/algorithm/Hash/1-twoSum.ts b/algorithm/Hash/1-twoSum.ts new file mode 100644 index 000000000..e69de29bb diff --git a/algorithm/Hash/Hash.ts b/algorithm/Hash/Hash.ts new file mode 100644 index 000000000..e560656b4 --- /dev/null +++ b/algorithm/Hash/Hash.ts @@ -0,0 +1,32 @@ +interface HListNode{ + val:T; + next: HListNode | null +} + +class HLinkedList{ + head: HListNode | null; + tail: HListNode | null + constructor(){ + this.head = null + this.tail = null + } + + append(value:T){ + const newNode:HListNode= { + val:value, + next: null + } + if (this.head === null){ + this.head = newNode + this.tail = newNode + } + } +} +class Hash { + key:K; + value:V + + constructor(size = 10){ + this.table = Array.from({ length: size }, () => new LinkedList()); + } +} \ No newline at end of file diff --git a/algorithm/Heap/LastStoneWeight/1046-LastStoneWeight.py b/algorithm/Heap/LastStoneWeight/1046-LastStoneWeight.py new file mode 100644 index 000000000..3efa63596 --- /dev/null +++ b/algorithm/Heap/LastStoneWeight/1046-LastStoneWeight.py @@ -0,0 +1,61 @@ +class MaxHeap: + def __init__(self): + self.heap = [] + + def swap(self, i, j): + [self.heap[i], self.heap[j]] = [self.heap[j], self.heap[i]] + def size(self): + return len(self.heap) + + def insert(self,value): + self.heap.append(value) + self.bubbleUp() + + def pop(self): + if self.size()== 0 : return None + if self.size() == 1 : return self.heap.pop() + end = self.size() - 1 + self.swap(0, end) + removed = self.heap.pop() + self.bubbleDown() + return removed + + def bubbleUp(self): + idx = self.size() - 1 + while idx > 0: + parent = (idx - 1) // 2 + if self.heap[parent] > self.heap[idx]: break + self.swap(parent,idx) + idx = parent + + def bubbleDown(self): + idx = 0 + while True: + left = 2 * idx + 1 + right = 2 * idx + 2 + largest = idx + if left < self.size() and self.heap[largest] < self.heap[left]: + largest = left + if right < self.size() and self.heap[largest] < self.heap[right]: + largest = right + if largest == idx: break + self.swap(largest,idx) + idx = largest + +def lastStoneWeight(stones): + heap = MaxHeap() + + for stone in stones: + heap.insert(stone) + + while heap.size() > 1 : + first = heap.pop() + second = heap.pop() + + if first - second != 0: + heap.insert(first - second) + + if heap.size() == 0 : 0 + else: return heap.pop() + +print(lastStoneWeight(stones = [2,7,4,1,8,1])) \ No newline at end of file diff --git a/algorithm/Heap/LastStoneWeight/1046-LastStoneWeight.ts b/algorithm/Heap/LastStoneWeight/1046-LastStoneWeight.ts new file mode 100644 index 000000000..e05fcd819 --- /dev/null +++ b/algorithm/Heap/LastStoneWeight/1046-LastStoneWeight.ts @@ -0,0 +1,67 @@ +class MaxHeap { + constructor( + private heap: T[] = [], + private compare: (a: T, b: T) => number, + ) {} + size() { + return this.heap.length; + } + swap(i: number, j: number) { + [this.heap[i], this.heap[j]] = [this.heap[j], this.heap[i]]; + } + insert(value: T) { + this.heap.push(value); + this.bubbleUp(); + } + pop() { + if (this.size() === 0) return undefined; + if (this.size() === 1) return this.heap.pop(); + const end = this.size() - 1; + const root = this.heap[0]; + this.swap(0, end); + this.heap.pop(); + this.bubbleDown(0); + return root; + } + bubbleDown(index: number) { + while (true) { + let left = 2 * index + 1 + let right = 2 * index + 2 + let crnt = index + if (left < this.size() && this.compare(this.heap[crnt], this.heap[left]) < 0) + crnt = left + if(right < this.size() && this.compare(this.heap[crnt], this.heap[right]) < 0){ + crnt = right + } + if (crnt === index) break; + this.swap(crnt,index) + index = crnt + } + } + bubbleUp() { + let index = this.size() - 1 + while (index > 0) { + let parent = Math.floor((index - 1) / 2) + if (this.compare(this.heap[index], this.heap[parent]) <= 0) break + this.swap(index, parent) + index = parent + } + } +} +function lastStoneWeight(stones:number[]): number | undefined { + const heap = new MaxHeap([],(a,b) => a - b) + for(let stone of stones){ + heap.insert(stone) + } + while(heap.size() > 0){ + let first = heap.pop()! + let second = heap.pop()! + if( first - second !== 0 ){ + heap.insert(first - second) + } + if(heap.size() === 0) return 0 + else return heap.pop() + } +} + +// time complexity \ No newline at end of file diff --git a/algorithm/Heap/MaxHeap.py b/algorithm/Heap/MaxHeap.py new file mode 100644 index 000000000..742d8f1e6 --- /dev/null +++ b/algorithm/Heap/MaxHeap.py @@ -0,0 +1,41 @@ +class MaxHeap: + def __init__(self): + self.heap = [] + + def swap(self, start, end): + self.heap[start], self.heap[end] = self.heap[end], self.heap[start] + + def insert(self, value): + self.heap.append(value) + self.bubbleUp() + + def pop(self): + end = len(self.heap) - 1 + self.swap(0, end) + removed = self.heap.pop() + self.bubbleDown(0) + return removed + + def bubbleUp(self): + idx = len(self.heap) - 1 + while idx > 0: + parentId = 2 * idx + if self.heap[parentId] < self.heap[idx]: + self.swap(parentId, idx) + idx = parentId + def bubbleDown(self,idx): + while True: + left = (2 * idx) + 1 + right = (2 * idx) + 2 + largest = idx + if left < len(self.heap) and self.heap[left] > self.heap[largest]: + largest = left + + if right < len(self.heap) and self.heap[right] > self.heap[largest]: + largest = right + + if idx == largest: + break + self.swap(idx, largest) + idx = largest + \ No newline at end of file diff --git a/algorithm/Heap/MinHeap.py b/algorithm/Heap/MinHeap.py new file mode 100644 index 000000000..e69de29bb diff --git a/algorithm/LinkedList/CycleLinkedList/141-CycleLinkedList_I.py b/algorithm/LinkedList/CycleLinkedList/141-CycleLinkedList_I.py new file mode 100644 index 000000000..77903e835 --- /dev/null +++ b/algorithm/LinkedList/CycleLinkedList/141-CycleLinkedList_I.py @@ -0,0 +1,18 @@ +class Node: + def __init__(self): + self.val = None, + self.next = None + + def hasCycle(self, head): + if not head: + return None + + fast = head + slow = head + + while fast or fast.next: + slow = slow.next + fast = fast.next.next + if slow == fast : + return True + return False \ No newline at end of file diff --git a/algorithm/LinkedList/CycleLinkedList/141-CycleLinkedList_I.ts b/algorithm/LinkedList/CycleLinkedList/141-CycleLinkedList_I.ts new file mode 100644 index 000000000..d5ea1b442 --- /dev/null +++ b/algorithm/LinkedList/CycleLinkedList/141-CycleLinkedList_I.ts @@ -0,0 +1,33 @@ +import { SinglyLinkedList } from "../SinglyLinkedList.ts" + +class ListNode { + val : T; + next: ListNode | null; + + constructor(val:T, next:ListNode | null){ + this.val = val, + this.next = next + } +} + +function hasCycleLinkedList(head:ListNode | null): boolean { + let fast = head + let slow = head + while(fast && fast.next){ + slow= slow!.next + fast = fast.next.next + + if(slow === fast) return true + } + return false +} + +const myList = new SinglyLinkedList() +const list = [1, 2, 3, 4]; + +for(let num of list){ + myList.append(num) +} + +myList!.tail!.next = myList.head!.next!.next; +console.log(hasCycleLinkedList(myList.head)) \ No newline at end of file diff --git a/algorithm/LinkedList/DoublyLinkedList.ts b/algorithm/LinkedList/DoublyLinkedList.ts new file mode 100644 index 000000000..9c61169e9 --- /dev/null +++ b/algorithm/LinkedList/DoublyLinkedList.ts @@ -0,0 +1,60 @@ +import type { ListNode } from "./SinglyLinkedList.ts"; + +class DoublyLinkedList{ + head: ListNode | null + tail: ListNode | null + + constructor(){ + this.head = null + this.tail = null + } + append(value:T){ + const newNode : ListNode = { + val :value, + next: null, + prev: null + }; + if(!this.head){ + this.head = newNode; + this.tail = newNode; + return + } + newNode.prev = this.tail + this.tail!.next = newNode; + this.tail = newNode; + } + preppend(value:T){ + const newNode : ListNode = { + val :value, + next: null, + prev: null + } + if(!this.head){ + this.head = newNode; + this.tail = newNode; + return ; + } + newNode.next = this.head; + this.head.prev = newNode + this.head = newNode; + } + insert(target:T, value:T){ + let crnt = this.head + let prev = null + const newNode: ListNode = { + val :value, + next: null, + prev: null + } + while(crnt){ + if(crnt.val === value){ + newNode.next = crnt.next + newNode.prev = crnt + crnt = newNode.next + return ; + } + crnt = crnt.next + } + } + +} \ No newline at end of file diff --git a/algorithm/LinkedList/ReversedLinkedList/206-ReversedLinkedList_I.py b/algorithm/LinkedList/ReversedLinkedList/206-ReversedLinkedList_I.py new file mode 100644 index 000000000..ea126052e --- /dev/null +++ b/algorithm/LinkedList/ReversedLinkedList/206-ReversedLinkedList_I.py @@ -0,0 +1,21 @@ +class Node: + def __init__(self): + self.val = None, + self.next = None + + +class LinkedList: + def reversedLinkedList(self, head): + if not head: + return None + + crnt = head + prev = None + while crnt: + node = crnt.next + crnt.next = prev + prev = crnt + crnt = node + + return prev + \ No newline at end of file diff --git a/algorithm/LinkedList/ReversedLinkedList/206-ReversedLinkedList_I.ts b/algorithm/LinkedList/ReversedLinkedList/206-ReversedLinkedList_I.ts new file mode 100644 index 000000000..89d50fc12 --- /dev/null +++ b/algorithm/LinkedList/ReversedLinkedList/206-ReversedLinkedList_I.ts @@ -0,0 +1,37 @@ +import { SinglyLinkedList } from "../SinglyLinkedList.ts"; +interface LinkedListNode { + val: T; + next: null | LinkedListNode; +} +class LinkedList { + head: LinkedListNode | null; + tail: LinkedListNode | null; + list: SinglyLinkedList; + + constructor() { + this.head = null; + this.tail = null; + this.list = new SinglyLinkedList(); + } + + reversedLinkedList() { + let prev = null; + let crnt = this.list.head; + while (crnt) { + let next = crnt.next; + crnt.next = prev; + prev = crnt; + crnt = next; + } + this.list.head = prev + } +} +const nums = [1, 2, 3, 4, 5]; +const list = new LinkedList() +for (let num of nums) { + list.list.append(num); +} +list.list.print() +list.reversedLinkedList() +list.list.print() + diff --git a/algorithm/LinkedList/SinglyLinkedList.ts b/algorithm/LinkedList/SinglyLinkedList.ts new file mode 100644 index 000000000..0fbfd15c6 --- /dev/null +++ b/algorithm/LinkedList/SinglyLinkedList.ts @@ -0,0 +1,105 @@ +export interface ListNode { + val: T; + next: ListNode | null; + prev?:ListNode| null; +} + +export class SinglyLinkedList { + head: ListNode | null; + tail: ListNode | null; + constructor() { + this.head = null; + this.tail = null; + } + append(value: T) { // add it from the end + const newNode: ListNode = { + val: value, + next: null, + }; + if (!this.head) { + this.head = newNode; + this.tail = newNode; + return; + } + if (this.tail) { + this.tail.next = newNode; + this.tail = newNode; + } + } + preppend(value: T) { // add + const newNode: ListNode = { + val: value, + next: null, + }; + if (!this.head) { + this.head = newNode; + this.tail = newNode; + } + newNode.next = this.head; + this.head = newNode; + } + insert(value: T, target: T) { + let prev = null; + let crnt = this.head; + const newNode: ListNode = { + val: value, + next: null, + }; + while (crnt) { + if (crnt.val === target) { + if (prev === null) { + newNode.next = this.head; + this.head = newNode; + } else { + prev.next = newNode; + newNode.next = crnt; + } + return; + } + prev = crnt; + crnt = crnt.next; + } + } + delete(value:T) { + let crnt = this.head; + let prev = null; + while(crnt){ + if(crnt.val === value){ + if(prev === null){ + this.head = crnt.next + }else{ + prev.next = crnt.next + } + if(crnt === this.tail){ + this.tail =prev + } + crnt = crnt.next; + continue; + } + prev = crnt; + crnt = crnt.next + } + } + find(value: T): T | undefined { + let crnt = this.head + while(crnt){ + if(crnt.val === value){ + return crnt.val + } + crnt = crnt.next; + } + return; + } + print() { + let crnt = this.head; + let result = []; + + while (crnt) { + result.push(crnt.val); + crnt = crnt.next; + } + + console.log(result.join(" -> ")); + } + +} diff --git a/algorithm/Queue.ts b/algorithm/Queue.ts new file mode 100644 index 000000000..f2fe44522 --- /dev/null +++ b/algorithm/Queue.ts @@ -0,0 +1,28 @@ +class Queue { + private items: T[] = []; + private readonly capacity: number; + + constructor(capacity: number) { + this.capacity = capacity; + } + isEmpty(): boolean { + return this.items.length === 0; + } + isFull(): boolean { + return this.items.length === this.capacity; + } + length(): number { + return this.items.length; + } + enqueue(item: T): boolean { + if (this.items.length !== this.capacity) return false; + else { + this.items.push(item); + return true; + } + } + dequeue(): T | undefined { + if (this.items.length === 0) return undefined; + return this.items.shift(); + } +} diff --git a/algorithm/Queue/QueueByLinkedList.py b/algorithm/Queue/QueueByLinkedList.py new file mode 100644 index 000000000..8ce81488d --- /dev/null +++ b/algorithm/Queue/QueueByLinkedList.py @@ -0,0 +1,34 @@ +class ListNode: + def __init__(self): + self.val = None + self.prev = None, + self.next = None + +class Queue: + def __init__(self): + self.head = None + self.tail = None + + def enqueue(self, value): + newNode = ListNode(value) + if not self.head: + self.tail = self.head = newNode + return + self.tail.next = newNode + self.tail = newNode + + def dequeue(self): + if not self.head: + return None + removed = self.head + if self.head == self.tail: + self.head = self.tail = None + else: + self.head = self.head.next + self.head.prev = None + return removed + + + + + diff --git a/algorithm/Queue/QueueByLinkedList.ts b/algorithm/Queue/QueueByLinkedList.ts new file mode 100644 index 000000000..bdff2ffaa --- /dev/null +++ b/algorithm/Queue/QueueByLinkedList.ts @@ -0,0 +1,57 @@ +class QueueNode { + value: T; + next: QueueNode | null; + prev: QueueNode | null; + constructor(value: T) { + this.value = value; + this.next = null; + this.prev = null; + } +} +class Q { + private head: QueueNode | null = null; + private tail: QueueNode | null = null; + private length = 0; + + enqueue(value: T) { + const newNode = new QueueNode(value); + if (!this.tail) { + this.head = this.tail = newNode; + }else { + this.tail.next = newNode + newNode.prev = this.tail + this.tail = newNode + } + this.length ++; + } + dequeue():T | null{ + if (!this.head) return null + const removed = this.head + if (this.head === this.tail) { + this.head = this.tail = null + } else { + this.head = this.head.next; + if (this.head) this.head.prev = null; + } + this.length--; + return removed.value + } + size(){ + return this.length; + } + peek():null | T{ + if (!this.head) return null; + return this.head.value; + } +} + +const q = new Q (); +q.enqueue(1); +q.enqueue(2); +q.enqueue(3); + +console.log(q); +console.log(q.peek()) +console.log(q.size()) +console.log(q.dequeue()) +console.log(q.size()) diff --git a/algorithm/heap.js b/algorithm/heap.js new file mode 100644 index 000000000..260c48faa --- /dev/null +++ b/algorithm/heap.js @@ -0,0 +1,62 @@ +var Heap = /** @class */ (function () { + function HeapByJs(compare, heap) { + if (heap === void 0) { heap = []; } + this.compare = compare; + this.heap = heap; + } + HeapByJs.prototype.insert = function (value) { + this.heap.push(value); + this.heapifyUp(); + }; + HeapByJs.prototype.pop = function (start, end) { + var n = this.heap.length; + this.swap(start, end); + var removed = this.heap.pop(); + this.heapifyDown(start, end); + return removed; + }; + HeapByJs.prototype.heapifyUp = function () { + var idx = this.heap.length - 1; + while (idx > 0) { + var parentIdx = Math.floor((idx - 1) / 2); + if (this.compare(this.heap[parentIdx], this.heap[idx]) < 0) + break; + this.swap(parentIdx, idx); + idx = parentIdx; + } + }; + HeapByJs.prototype.heapifyDown = function (start, end) { + while (2 * start + 1 < end) { + var left_c = 2 * start + 1; + var right_c = 2 * start + 2; + var target = left_c; + if (right_c < end && + this.compare(this.heap[right_c], this.heap[left_c]) < 0 //right node always bigger thatn left node + ) { + target = right_c; + } + if (this.compare(this.heap[start], this.heap[target]) < 0) + break; + this.swap(start, target); + start = target; + } + }; + HeapByJs.prototype.heapBuild = function () { + for (var i = Math.floor((this.heap.length - 1) / 2); i >= 0; --i) { + this.heapifyDown(i, this.heap.length); + } + }; + HeapByJs.prototype.heapSort = function () { + var n = this.heap.length; + this.heapBuild(); + for (var end = n - 1; end > 0; end--) { + this.swap(0, end); + this.heapifyDown(0, end); + } + }; + HeapByJs.prototype.swap = function (i, j) { + var _a; + _a = [this.heap[j], this.heap[i]], this.heap[i] = _a[0], this.heap[j] = _a[1]; + }; + return HeapByJs; +}()); diff --git a/algorithm/heap.ts b/algorithm/heap.ts new file mode 100644 index 000000000..13003a671 --- /dev/null +++ b/algorithm/heap.ts @@ -0,0 +1,71 @@ +export class HeapByTs { + constructor( + private compare: (a: T, b: T) => number, + private heap: T[] = [], + ) {} + + insert(value: T) { + this.heap.push(value); + this.heapifyUp(); + } + + pop(): T | undefined { + const n = this.heap.length; + const end = n - 1 + this.swap(0, end); + const removed = this.heap.pop(); + this.heapifyDown(0, end); + return removed; + } + + heapifyUp() { + let idx = this.heap.length - 1 + while(idx > 0){ + const parentIdx = Math.floor((idx - 1) / 2) + if (this.compare(this.heap[parentIdx],this.heap[idx]) < 0 ) break; + this.swap(parentIdx, idx) + idx = parentIdx + } + } + heapifyDown(start: number, end: number) { + while (2 * start + 1 < end) { + let left_c = 2 * start + 1; + let right_c = 2 * start + 2; + let target = left_c; + if ( + right_c < end && + this.compare(this.heap[right_c], this.heap[left_c]) < 0//right node always bigger thatn left node + ) { + target = right_c; + } + if (this.compare(this.heap[start], this.heap[target]) < 0) break; + this.swap(start, target); + start = target; + } + } + heapBuild() { + for(let i = Math.floor((this.heap.length - 1)/ 2); i >= 0; --i){ + this.heapifyDown(i,this.heap.length) + } + } + heapSort() { + const n = this.heap.length + this.heapBuild() + for(let end = n - 1; end > 0; end-- ){ + this.swap(0, end); + this.heapifyDown(0, end); + } + } + swap(i: number, j: number) { + [this.heap[i],this.heap[j]]=[this.heap[j],this.heap[i]] + } +} + +const minHeap = new HeapByTs((a, b) => a - b) +minHeap.insert(1) +minHeap.insert(2) +minHeap.insert(3) +minHeap.insert(4) + +console.log(minHeap.pop()); +console.log(minHeap) \ No newline at end of file diff --git a/algorithm/linkedList.js b/algorithm/linkedList.js new file mode 100644 index 000000000..fc15af1e2 --- /dev/null +++ b/algorithm/linkedList.js @@ -0,0 +1,76 @@ +// 1. initiate singly linked list + +class SinglyLinkedList{ + constructor(){ + this.head = null + this.tail = null + } + append(value){ + const newNode = {value, next: null} + if(this.head === null){ + this.head = newNode + this.tail = newNode + } + this.tail.next = newNode + this.tail = newNode + } + + insert(value,idx){ + const newNode = {value, next: null} + if(idx === 0 ){ + newNode.next = this.head + this.head = newNode + if (!this.tail) this.tail = newNode + return; + } + let prev = this.head + let crnt = prev.next + let crntIdx = 0 + while(prev && crntIdx < idx - 1){ + prev = prev.next + crnt = crnt.next + crntIdx ++ + } + if(!prev){ + console.log("out of bound") + return + }; + + newNode.next = crnt + prev.next = newNode + if (!crnt) this.tail = newNode + } + insertAfter(targetValue, value){ + let prev = this.head + let crnt = prev.next + const newNode = {value, next: crnt} + while(prev && prev.next !== null){ + prev = crnt + crnt = crnt.next + if(prev.value === targetValue){ + newNode.next = prev.next + prev.next = newNode + prev = prev.next + crnt = crnt.next + } + } + prev.next = newNode + } + deleteAtIndex(idx){ + + if (this.head === null) + return; // base case + if( idx === 0 ){ + thishead = head.next + return; + } + let prev = this.head + for (let i = 0; i < idx - 1; i++){ + if(!prev.next) return; + prev = prev.next + } + if(!prev.next) return; + + prev.next = prev.next.next; + } +} \ No newline at end of file diff --git a/algorithm/palindromNumber/9-palindromNumber.py b/algorithm/palindromNumber/9-palindromNumber.py new file mode 100644 index 000000000..9055b844b --- /dev/null +++ b/algorithm/palindromNumber/9-palindromNumber.py @@ -0,0 +1,16 @@ +def palindromNumber(x): + if x < 0: + return False + original = x + + reversed_num= 0 + + while x > 0: + digit = x % 10 + reversed_num = reversed_num * 10 + digit + x //= 10 + return reversed_num == original + +print(palindromNumber(121)) +print(palindromNumber(123)) +print(palindromNumber(11)) \ No newline at end of file diff --git a/algorithm/palindromNumber/9-palindromeNumber.ts b/algorithm/palindromNumber/9-palindromeNumber.ts new file mode 100644 index 000000000..42e30d611 --- /dev/null +++ b/algorithm/palindromNumber/9-palindromeNumber.ts @@ -0,0 +1,29 @@ +// Problem definition: Given an integer "x", return "true", if "x" is palindrome and "false" otherwise + +// 문제 정의: 주어진 정수 x에대하여, 앞 뒤과 똑같은 정수 인지 아닌지 참과 거짓을 구하라 +/* + Approaching: + 1. 121 / 10 = 12 + rem = 1 (121 % 10) + reversed value = 1 ( = 121's rem) + + 2. 12(121/ 10) / 10 = 1 + rem = 2 (12 % 1) + reversed value = 2 * (10 ** 1) + 1( = 121 % 10) + + 3. 1 (1 / 10) + rem = 1 + revereed value = 1 * (10 ** 2) + 20 + 1( = 121 % 10) +*/ +function palindromeNumber(x: number): boolean { + let reversed = 0; + let original = x + while(x > 0){ + let digit: number = x % 10 + x = Math.floor(x / 10) + reversed = reversed * 10 + digit + } + return (original === reversed) +} + +console.log(palindromeNumber(121)) \ No newline at end of file diff --git a/algorithm/readme.md b/algorithm/readme.md new file mode 100644 index 000000000..e638b66a6 --- /dev/null +++ b/algorithm/readme.md @@ -0,0 +1,23 @@ +# algorithms + +1. 정렬 알고리즘 + +2. 힙 정렬 + a. insert + b. + +3. stack + a. 삭제 + b. 추가 + +4. queue + + a. 삭제 + b. 추가 +5. 단일 연결 배열 + a. 삭제 + b. 추가 + +6. 이중 연결 배열 + a. 삭제 + b. 추가 \ No newline at end of file diff --git a/algorithm/sort.js b/algorithm/sort.js new file mode 100644 index 000000000..70ae3834e --- /dev/null +++ b/algorithm/sort.js @@ -0,0 +1,225 @@ +// merge sort +/* appraoch: divide and conquer +1. [7] | [3] | [1] | [2] | [8] | [6] | [4] | [9] | [5]; + +2. [3, 7] | [1, 2] | [8] | [6] | [4] | [9] | [5] + +3. [1, 2, 3, 7] | [6, 8] | [4, 9] | [5] + +4. [1, 2, 3, 7] | [4, 6, 8, 9] | [5] + +5. [1, 2, 3, 7] | [4, 5, 6, 8, 9] => o( log n ) + +6. [1 ,2, 3, 4, 5, 6, 7, 8, 9] = o(n) + +time complexity: o(n*logn) +space complexity: o(n) +*/ + +function mergeSort(nums = []) { + let n = nums.length; + if (n <= 1) return nums; + const mid = Math.floor(n / 2); + + let left_nums = nums.slice(0, mid); + let right_nums = nums.slice(mid); + + let sorted_left = mergeSort(left_nums); + let sorted_right = mergeSort(right_nums); + + let res = []; + let idx_l = 0; + let idx_r = 0; + + while (idx_l < sorted_left.length || idx_r < sorted_right.length) { + if (idx_l === sorted_left.length) { + res.push(sorted_right[idx_r]); + idx_r++; + continue; + } + if (idx_r === sorted_right.length) { + res.push(sorted_left[idx_l]); + idx_l++; + continue; + } + if (sorted_right[idx_r] <= sorted_left[idx_l]) { + res.push(sorted_right[idx_r]); + idx_r++; + } else { + res.push(sorted_left[idx_l]); + idx_l++; + } + } + return res; +} +console.log(mergeSort([7, 3, 1, 2, 8, 6, 4, 9, 5])); + +/* insert + ↓ : idx + ⇣ : pivot + + time complexity => o(n ** 2) + space complexity => o(1) || O(n) => recursive + + + ↓ ⇣ + [8, 4, 7] + +if nums[pivot] < nums[idx] + temp = 4 + => [8, 8, 7] shift 8 + nums[pivot] = nums[idx] + => [4, 8, 7] idx --(insert temp) + + ↓ ⇣ + [4, 8, 7] + temp = 7 + if temp < nums[idx] + => [2, 8, 8] + + => [4, 7, 8] insert temp +*/ +function insertSort(nums){ + const n = nums.length + for(let pIdx = 1; pIdx < n; pIdx++){ + let temp = nums[pIdx] + let idx = pIdx - 1 + while(idx >= 0 && temp < nums[idx]){ + nums[idx + 1] = nums[idx] + idx-- + } + nums[idx + 1] = temp + } + return nums +} + +console.log(insertSort([7, 3, 1, 2, 8, 6, 4, 9, 5])) + +// select sort + +/* + one of the slowest sorting algorithm => on**2 + 1. find minimum number in the array (1 to n - 1) + + 2. compare nums[0: n - 1] and nums[i: n - 1] then switch it or not + ↓ ⇣ +[3, 5, 1, 4] + ↓ ⇣ +[1, 3, 5, 4] + ↓ ⇣ +[1, 3, 5, 4] + +[1, 3, 4, 5] + +=> O n**2 timecomplexity + +=> O(n) + +*/ +function selectSort(nums){ + + n = nums.length + for(let i = 0; i < n; i++){ + minNum = nums[i] + minIdx = i + for(let j = i ; j < n; j++){ + if(nums[j] < minNum){ + minNum = nums[j] + minIdx = j + } + } + [nums[i],nums[minIdx]] = [nums[minIdx],nums[i]] + } + return nums +} +console.log(selectSort([7, 3, 1, 2, 8, 6, 4, 9, 5])) + + +// quick Sort +/* +pivot = 4 + ↓ ⇣ +[7, 3, 1, 2, 4, 6, 8, 9, 5] +[][7] + + ↓ ⇣ +[7, 3, 1, 2, 4, 6, 8, 9, 5] +[3][7] + + ↓ ⇣ +[7, 3, 1, 2, 4, 6, 8, 9, 5] +[3, 1][7] + + ↓ ⇣ +[7, 3, 1, 2, 4, 6, 8, 9, 5] +[3, 1, 2 ][7] + + ⇣ ↓ +[7, 3, 1, 2, 4, 6, 8, 9, 5] +[3, 1, 2 ][7, 6] + ⇣ ↓ +[7, 3, 1, 2, 4, 6, 8, 9, 5] +[3, 1, 2][7, 6, 8] + ⇣ ↓ +[7, 3, 1, 2, 4, 6, 8, 9, 5] +[3, 1, 2][7, 6, 8, 9] + ⇣ ↓ +[7, 3, 1, 2, 4, 6, 8, 9, 5] +[3, 1, 2] [7, 6, 8, 9, 5] + +pivot 1, 8 + ↓ ⇣ ↓ ⇣ +[3, 1, 2] [7, 6, 8, 9, 5] +[][3] [7][] + ↓ ⇣ ↓ ⇣ +[3, 1, 2] [7, 6, 8, 9, 5] +[2] [3] [7, 6][] + ⇣ ↓ + [7, 6, 8, 9, 5] + [7, 6] [9] + ⇣ ↓ + [7, 6, 8, 9, 5] + [7, 6] [9] + ⇣ ↓ + [7, 6, 8, 9, 5] + [7, 6, 5][9] + + pivot = 6 + ↓ ⇣ + [7, 6, 5] + [][7] + ⇣ ↓ + [7, 6, 5] + [5] [7] + +=> buttom up left + pivot + right + +worst time complexity: o(n**2) +fastest time complexity : n log n + +space complexity: o(n) +*/ +function quickSort(nums=[]){ + let n = nums.length + let mid = Math.floor(n / 2) + + let pivot = nums[mid] + let leftNums = [] + let rightNums = [] + + leftIdx = 0 + rightIdx = 0 + if(nums.length <= 1 ) {return nums}; + for(let i = 0; i < n; i++){ + if (i === mid) continue; + if(nums[i] < pivot){ + leftNums.push(nums[i]) + }else{ + rightNums.push(nums[i]) + } + } + const l_sorted = quickSort(leftNums) + const r_sorted = quickSort(rightNums) + return [...l_sorted, pivot, ...r_sorted ] +} +console.log(quickSort([7, 3, 1, 2, 8, 6, 4, 9, 5])) \ No newline at end of file diff --git a/algorithm/stack.ts b/algorithm/stack.ts new file mode 100644 index 000000000..cd6e5ea4c --- /dev/null +++ b/algorithm/stack.ts @@ -0,0 +1,42 @@ +console.log("🔥 FILE EXECUTED 🔥") +class stack { + items: T[] = []; + capacity: number; + + constructor(capacity: number) { + this.capacity = capacity; + } + peek(): T | undefined { + console.log(1) + if (this.items.length !== 0) { + return this.items[this.items.length - 1]; + } + return; + } + isEmpty(): boolean { + return this.items.length === 0; + } + pop(): T | undefined { + if (this.isEmpty()) return; + return this.items.pop(); + } + isFull():boolean { + return this.items.length === this.capacity + } + push(value: T) { + console.log(12) + if (this.isFull()) { + return; + } else { + this.items.push(value); + } + } +} + const s = new stack(5) + console.log(s.isEmpty()) + s.push(1) + s.push(2) + s.push(3) + s.push(4) + s.push(5) + console.log(s.peek()) diff --git a/algorithm/stack/20-validParenthesis.ts b/algorithm/stack/20-validParenthesis.ts new file mode 100644 index 000000000..fad496f94 --- /dev/null +++ b/algorithm/stack/20-validParenthesis.ts @@ -0,0 +1,27 @@ +/* +* problem defintion: Given a string s containing just the characters '(', ')', '{', '}', '[' and ']', determine if the input string is valid. An input string is valid if: +* Open brackets must be closed by the same type of brackets. +* Open brackets must be closed in the correct order. +* time complexity: o(n) +* space complexity: o(n) +*/ + +function valid(s: string): boolean { + let stack: Array = []; + const openBrackets: Array = ["{", "(", "["]; + const pairs: { [key: string]: string } = { "(": ")", "{": "}", "[": "]" }; + let i: number = 0; + while (i < s.length) { + if (openBrackets.includes(s[i])) { + stack.push(s[i]); + } else { + let last = stack.pop(); + if (!last || pairs[last] !== s[i]) return false; + } + i++; + } + return stack.length === 0; +} +console.log(valid("()")) +console.log(valid("()[]{}")) +console.log(valid("(]")) \ No newline at end of file diff --git a/algorithm/stack/682-BaseballGame.py b/algorithm/stack/682-BaseballGame.py new file mode 100644 index 000000000..94c0a861f --- /dev/null +++ b/algorithm/stack/682-BaseballGame.py @@ -0,0 +1,18 @@ +def calPoint(operations): + stack = [] + for record in operations: + if record == "C": + stack.pop() + + elif record == "D": + stack.append(stack[-1] * 2) + + elif record == "+": + stack.append(stack[-1] + stack[-2]) + else: + stack.append(int(record)) + + return sum(stack) + +# 파이썬은 js나 ts와 달리 sum 함수를 사용 하여 모든 배열의 정수의 합을 구할 수 있었음 +# 왜냐하면 파이썬에선 built-in 이라는 함수자체가 존재 하기 때문입니다. diff --git a/algorithm/stack/682-BaseballGame.ts b/algorithm/stack/682-BaseballGame.ts new file mode 100644 index 000000000..ccbb8acdc --- /dev/null +++ b/algorithm/stack/682-BaseballGame.ts @@ -0,0 +1,43 @@ +/* problem defintion + I should keep the scores for baseball game. At the begining, I should start an emty record. + + Given an array of strings operations, where operation[i] is the i th operation I must apply to the record and one of the following: + + integer "X": record new scores + "D": previous scores * 2 + "C": cancel the previous scores + "+": add prvious scores and the previous one + return the sum of records +*/ + +function calPoints(operations:string[]):number{ + const stack : number[] = []; + + for(let record of operations){ + if(record ==="C"){ + stack.pop() + } + else if(record === "D"){ + stack.push(stack[stack.length - 1] * 2) + } + else if (record === "+"){ + stack.push(stack[stack.length - 1] + stack[stack.length - 2]) + } + else { + stack.push(Number(record)) + } + } + const sum = stack.reduce((accumulator, current)=> accumulator + current, 0) + return sum +} + +/** + * 시간 복잡도 = + reduce => o(n) + stack.pop() => 1 + stack.push() => 1 + stack.pop 과 push(append)를 n 타임 반복 => o(n) + o(2n) => o(n) + + stack은 공간 복잡도 o(n) + */ \ No newline at end of file diff --git a/algorithm/stack/MinStack/155-MinStack.py b/algorithm/stack/MinStack/155-MinStack.py new file mode 100644 index 000000000..88e35b617 --- /dev/null +++ b/algorithm/stack/MinStack/155-MinStack.py @@ -0,0 +1,21 @@ +class MinStack: + def __init__(self): + self.stack = [] + self.minStack = [] + + def push(self, value): + self.stack.append(value) + + if len(self.minStack) == 0 or value <= self.getMin(): + self.minStack.append(value) + + def pop(self): + value = self.stack.pop() + if value == self.getMin(): + self.minStack.pop() + + def top(self): + return self.stack[len(self.stack - 1)] + + def getMin(self): + return self.minStack[len(self.minStack) - 1] \ No newline at end of file diff --git a/algorithm/stack/MinStack/155-MinStack.ts b/algorithm/stack/MinStack/155-MinStack.ts new file mode 100644 index 000000000..2923d55b7 --- /dev/null +++ b/algorithm/stack/MinStack/155-MinStack.ts @@ -0,0 +1,31 @@ +class MinStack{ + + constructor( + private stack: T[] = [], + private minStack: T[] = [] + ){} + + push(value:T){ + this.stack.push(value) + if(this.stack.length === 0 || value <= this.getMin()){ + this.minStack.push(value) + } + } + + pop(){ + const value = this.stack.pop() + if(value === this.getMin){ + this.minStack.pop() + } + } + + top(){ + return this.stack[this.stack.length - 1] + } + + getMin(){ + return this.minStack[this.minStack.length - 1] + } +} +// O(1) SC +// O(n) TC \ No newline at end of file diff --git a/algorithm/stack/stack.ts b/algorithm/stack/stack.ts new file mode 100644 index 000000000..d1f6077f4 --- /dev/null +++ b/algorithm/stack/stack.ts @@ -0,0 +1,21 @@ +class Stack{ + constructor( + private item : T[] = [] + ){} + + append(value:T){ + this.item.push(value) + } + + pop(){ + return this.item.pop() + } + + peak(){ + return this.item[this.item.length - 1] + } + isEmty(){ + if (this.item.length === 0) return true + else return false + } +} \ No newline at end of file diff --git a/algorithm/trappingWater/42-trappingWater.ts b/algorithm/trappingWater/42-trappingWater.ts new file mode 100644 index 000000000..9fcf294d5 --- /dev/null +++ b/algorithm/trappingWater/42-trappingWater.ts @@ -0,0 +1,28 @@ +function trap(height: number[]): number { + let left = 0; + let right = height.length - 1; + let leftMax = 0; + let rightMax = 0; + let trappedWater = 0; + + while (left < right) { + if (height[left] < height[right]) { + if (height[left] >= leftMax) { + leftMax = height[left]; + } else { + trappedWater += leftMax - height[left]; + } + left++; + } else { + if (height[right] >= rightMax) { + rightMax = height[right]; + } else { + trappedWater += rightMax - height[right]; + } + right--; + } + } + return trappedWater; +} + +console.log(trap([0,1,0,2,1,0,1,3,2,1,2,1])) \ No newline at end of file diff --git a/test.ts b/test.ts new file mode 100644 index 000000000..29348283b --- /dev/null +++ b/test.ts @@ -0,0 +1 @@ +console.log(1) \ No newline at end of file