diff --git a/work/1/Hard/Hash Table/127.word-ladder.py b/work/1/Hard/Hash Table/127.word-ladder.py new file mode 100644 index 0000000..3cfeca5 --- /dev/null +++ b/work/1/Hard/Hash Table/127.word-ladder.py @@ -0,0 +1,93 @@ +""" +127. Word Ladder +Difficulty: Hard +https://leetcode.com/problems/word-ladder/ + +────────────────────────────────────────────────── + +A transformation sequence from word beginWord to word endWord using a +dictionary wordList is a sequence of words beginWord -> s1 -> s2 -> +... -> sk such that: + + • Every adjacent pair of words differs by a single letter. + +• Every si for 1 <= i <= k is in wordList. Note that beginWord does +not need to be in wordList. + + • sk == endWord + +Given two words, beginWord and endWord, and a dictionary wordList, +return the number of words in the shortest transformation sequence +from beginWord to endWord, or 0 if no such sequence exists. + + + +Example 1: + +Input: beginWord = "hit", endWord = "cog", wordList = +["hot","dot","dog","lot","log","cog"] +Output: 5 +Explanation: One shortest transformation sequence is "hit" -> "hot" +-> "dot" -> "dog" -> cog", which is 5 words long. + +Example 2: + +Input: beginWord = "hit", endWord = "cog", wordList = +["hot","dot","dog","lot","log"] +Output: 0 +Explanation: The endWord "cog" is not in wordList, therefore there is +no valid transformation sequence. + + + +Constraints: + + • 1 <= beginWord.length <= 10 + + • endWord.length == beginWord.length + + • 1 <= wordList.length <= 5000 + + • wordList[i].length == beginWord.length + +• beginWord, endWord, and wordList[i] consist of lowercase English +letters. + + • beginWord != endWord + + • All the words in wordList are unique. +""" + +import collections + + +class Solution: + def ladderLength(self, beginWord: str, endWord: str, wordList: list[str]) -> int: + if endWord not in wordList: + return 0 + + adj = collections.defaultdict(list) + wordList.append(beginWord) + + for word in wordList: + for j in range(len(word)): + pattern = word[:j] + "*" + word[j + 1 :] + adj[pattern].append(word) + + visit = set([beginWord]) + q = collections.deque([beginWord]) + res = 1 + + while q: + for i in range(len(q)): + word = q.popleft() + if word == endWord: + return res + for j in range(len(word)): + pattern = word[:j] + "*" + word[j + 1 :] + for adjWord in adj[pattern]: + if adjWord not in visit: + visit.add(adjWord) + q.append(adjWord) + res += 1 + return 0 diff --git a/work/1/Medium/Array/994.rotting-oranges.py b/work/1/Medium/Array/994.rotting-oranges.py new file mode 100644 index 0000000..07df235 --- /dev/null +++ b/work/1/Medium/Array/994.rotting-oranges.py @@ -0,0 +1,93 @@ +""" +994. Rotting Oranges +Difficulty: Medium +https://leetcode.com/problems/rotting-oranges/ + +────────────────────────────────────────────────── + +You are given an m x n grid where each cell can have one of three +values: + + • 0 representing an empty cell, + + • 1 representing a fresh orange, or + + • 2 representing a rotten orange. + +Every minute, any fresh orange that is 4-directionally adjacent to a +rotten orange becomes rotten. + +Return the minimum number of minutes that must elapse until no cell +has a fresh orange. If this is impossible, return -1. + + + +Example 1: + +Input: grid = [[2,1,1],[1,1,0],[0,1,1]] +Output: 4 + +Example 2: + +Input: grid = [[2,1,1],[0,1,1],[1,0,1]] +Output: -1 +Explanation: The orange in the bottom left corner (row 2, column 0) +is never rotten, because rotting only happens 4-directionally. + +Example 3: + +Input: grid = [[0,2]] +Output: 0 +Explanation: Since there are already no fresh oranges at minute 0, +the answer is just 0. + + + +Constraints: + + • m == grid.length + + • n == grid[i].length + + • 1 <= m, n <= 10 + + • grid[i][j] is 0, 1, or 2. +""" + +from collections import deque + + +class Solution: + def orangesRotting(self, grid: list[list[int]]) -> int: + q = deque() + time, fresh = 0, 0 + + rows, cols = len(grid), len(grid[0]) + for r in range(rows): + for c in range(cols): + if grid[r][c] == 1: + fresh += 1 + if grid[r][c] == 2: + q.append([r, c]) + + directions = [[0, 1], [0, -1], [1, 0], [-1, 0]] + + while q and fresh > 0: + for i in range(len(q)): + r, c = q.popleft() + for dr, dc in directions: + row, col = dr + r, dc + c + # check if in bounds + if ( + row < 0 + or col < 0 + or row == len(grid) + or col == len(grid[0]) + or grid[row][col] != 1 + ): + continue + grid[row][col] = 2 + q.append([row, col]) + fresh -= 1 + time += 1 + return time if fresh == 0 else -1