From fc56fcb8adb3ebc7fcea81016e9865e04efc7fbd Mon Sep 17 00:00:00 2001 From: rishigoswamy Date: Sun, 15 Mar 2026 12:56:19 -0700 Subject: [PATCH] Add implementation for leetcode problems 994, 690 --- leetcode_690.py | 89 ++++++++++++++++++++++++++++++++++++++++++ leetcode_994.py | 102 ++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 191 insertions(+) create mode 100644 leetcode_690.py create mode 100644 leetcode_994.py diff --git a/leetcode_690.py b/leetcode_690.py new file mode 100644 index 0000000..a0aad40 --- /dev/null +++ b/leetcode_690.py @@ -0,0 +1,89 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +""" +Created on Sun Mar 15 00:00:00 2026 + +@author: rishigoswamy + + LeetCode 690: Employee Importance + Link: https://leetcode.com/problems/employee-importance/ + + Problem: + You have a data structure of employee information including their id, importance, + and list of subordinate ids. Given a target employee id, return the total importance + value of the employee and all their subordinates (recursively). + + Approach: + BFS. Build a hashmap of id → Employee for O(1) lookup. Seed the queue with the + target id, then for each dequeued employee add their importance and enqueue all + their direct subordinates. + + 1️⃣ Build empMap: id → Employee object. + 2️⃣ Seed queue with the target id. + 3️⃣ Dequeue employee id, add importance, enqueue all subordinates. + 4️⃣ Return accumulated importance when queue is empty. + + Note: queue.extend(subordinates) works; queue.append(generator) does NOT + (lazy generators are enqueued as a single object, not individual items). + + // Time Complexity : O(n) + Every employee is visited at most once. + // Space Complexity : O(n) + Hashmap and queue each hold at most n entries. + +""" + +from collections import deque +from typing import List + + +# Definition for Employee. +# class Employee: +# def __init__(self, id: int, importance: int, subordinates: List[int]): +# self.id = id +# self.importance = importance +# self.subordinates = subordinates + +class Solution: + def getImportance(self, employees: List['Employee'], id: int) -> int: + empMap = {} + for employee in employees: + empMap[employee.id] = employee + + queue = deque() + queue.append(id) + imp = 0 + + while queue: + emp = queue.popleft() + imp += empMap[emp].importance + # queue.extend(empMap[emp].subordinates) — built-in to flatten list and enqueue each item + for sub in empMap[emp].subordinates: + queue.append(sub) + + return imp + + ''' + def getImportance(self, employees: List['Employee'], id: int) -> int: + # Two separate maps for importance and subordinates. + empImportanceMap = {} + empSubordinateMap = {} + queue = deque() + importance = 0 + + for employee in employees: + if employee.id == id: + for sub in employee.subordinates: + queue.append(sub) + importance += employee.importance + empImportanceMap[employee.id] = employee.importance + empSubordinateMap[employee.id] = employee.subordinates + + while queue: + currEmployeeId = queue.popleft() + importance += empImportanceMap[currEmployeeId] + for sub in empSubordinateMap[currEmployeeId]: + queue.append(sub) + + return importance + ''' diff --git a/leetcode_994.py b/leetcode_994.py new file mode 100644 index 0000000..674d704 --- /dev/null +++ b/leetcode_994.py @@ -0,0 +1,102 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +""" +Created on Sun Mar 15 00:00:00 2026 + +@author: rishigoswamy + + LeetCode 994: Rotting Oranges + Link: https://leetcode.com/problems/rotting-oranges/ + + Problem: + Given an m x n grid where 0 = empty, 1 = fresh orange, 2 = rotten orange, + every minute any fresh orange adjacent (4-directionally) to a rotten orange + becomes rotten. Return the minimum number of minutes until no fresh oranges + remain, or -1 if impossible. + + Approach: + Multi-source BFS. Seed the queue with all initially rotten oranges simultaneously. + Expand level by level (each level = 1 minute). Track freshCount to detect + unreachable fresh oranges. + + 1️⃣ Scan grid: enqueue all rotten oranges, count fresh oranges. + 2️⃣ Early exit: if freshCount == 0, return 0. + 3️⃣ BFS level by level; for each rotten cell infect adjacent fresh cells and decrement freshCount. + 4️⃣ Increment time after each level. + 5️⃣ After BFS: if freshCount == 0 return time-1 (last increment was on empty queue), else -1. + + // Time Complexity : O(m * n) + Every cell is visited at most once. + // Space Complexity : O(m * n) + Queue can hold all cells in the worst case. + +""" + +from collections import deque +from typing import List + + +class Solution: + def orangesRotting(self, grid: List[List[int]]) -> int: + freshCount = 0 + queue = deque() + + for i in range(len(grid)): + for j in range(len(grid[0])): + if grid[i][j] == 2: + queue.append([i, j]) + if grid[i][j] == 1: + freshCount += 1 + + if freshCount == 0: + return 0 + + directions = [[0, 1], [0, -1], [1, 0], [-1, 0]] + time = 0 + + while queue: + size = len(queue) + for _ in range(size): + x, y = queue.popleft() + for direction in directions: + X, Y = x + direction[0], y + direction[1] + if 0 <= X < len(grid) and 0 <= Y < len(grid[0]): + if grid[X][Y] == 1: + grid[X][Y] = 2 + queue.append([X, Y]) + freshCount -= 1 + time += 1 + + if freshCount == 0: + return time - 1 + return -1 + + ''' + def orangesRotting(self, grid: List[List[int]]) -> int: + # DFS approach: overwrite cell values with the time they were infected. + # Re-visit a cell if a shorter infection time is found (grid[X][Y] > time). + self.directions = [[0, 1], [0, -1], [1, 0], [-1, 0]] + + def dfs(grid, i, j, time): + grid[i][j] = time + for direction in self.directions: + X, Y = i + direction[0], j + direction[1] + if 0 <= X < len(grid) and 0 <= Y < len(grid[0]): + if grid[X][Y] == 1 or grid[X][Y] > time: + dfs(grid, X, Y, time + 1) + + mxTime = 2 + + for i in range(len(grid)): + for j in range(len(grid[0])): + if grid[i][j] == 2: + dfs(grid, i, j, 2) + + for i in range(len(grid)): + for j in range(len(grid[0])): + if grid[i][j] == 1: + return -1 + mxTime = max(mxTime, grid[i][j]) + + return mxTime - 2 + '''