diff --git a/alien-dictionary/dolphinflow86.py b/alien-dictionary/dolphinflow86.py new file mode 100644 index 0000000000..7445860dfb --- /dev/null +++ b/alien-dictionary/dolphinflow86.py @@ -0,0 +1,43 @@ +# C is total length of all words, U is number of unique alien letters (<= 26). +# TC: O(C) - comparing adjacent words and processing topological sort graph +# SC: O(1) - unique letters and adjacency list bounded by 26 characters + +from collections import deque + + +class Solution: + + def alienOrder(self, words) -> str: + adj = {char: set() for word in words for char in word} + indegree = {char: 0 for word in words for char in word} + + for i in range(len(words) - 1): + w1, w2 = words[i], words[i + 1] + min_len = min(len(w1), len(w2)) + + if len(w1) > len(w2) and w1[:min_len] == w2[:min_len]: + return "" + + for j in range(min_len): + if w1[j] != w2[j]: + if w2[j] not in adj[w1[j]]: + adj[w1[j]].add(w2[j]) + indegree[w2[j]] += 1 + break + + queue = deque([char for char in indegree if indegree[char] == 0]) + result = [] + + while queue: + char = queue.popleft() + result.append(char) + + for neighbor in adj[char]: + indegree[neighbor] -= 1 + if indegree[neighbor] == 0: + queue.append(neighbor) + + if len(result) < len(indegree): + return "" + + return "".join(result) diff --git a/meeting-rooms/dolphinflow86.py b/meeting-rooms/dolphinflow86.py new file mode 100644 index 0000000000..c64d382b6b --- /dev/null +++ b/meeting-rooms/dolphinflow86.py @@ -0,0 +1,15 @@ +# N is the number of intervals. +# TC: O(N log N) - sorting the intervals by start time +# SC: O(1) - constant extra space + + +class Solution: + + def canAttendMeetings(self, intervals) -> bool: + intervals.sort(key=lambda x: x[0]) + + for i in range(1, len(intervals)): + if intervals[i][0] < intervals[i - 1][1]: + return False + + return True diff --git a/non-overlapping-intervals/dolphinflow86.py b/non-overlapping-intervals/dolphinflow86.py new file mode 100644 index 0000000000..af785e82ef --- /dev/null +++ b/non-overlapping-intervals/dolphinflow86.py @@ -0,0 +1,20 @@ +# N is the number of intervals. +# TC: O(N log N) - sorts intervals by end time and performs a single pass +# SC: O(N) - space required for sorting + + +class Solution: + + def eraseOverlapIntervals(self, intervals: list[list[int]]) -> int: + intervals.sort(key=lambda x: x[1]) + + remove_count = 0 + prev_end = float("-inf") + + for start, end in intervals: + if start < prev_end: + remove_count += 1 + else: + prev_end = end + + return remove_count diff --git a/remove-nth-node-from-end-of-list/dolphinflow86.py b/remove-nth-node-from-end-of-list/dolphinflow86.py new file mode 100644 index 0000000000..b8eff152e3 --- /dev/null +++ b/remove-nth-node-from-end-of-list/dolphinflow86.py @@ -0,0 +1,28 @@ +# N is the number of nodes in the linked list. +# TC: O(N) - single pass using two pointers with an (n + 1) gap +# SC: O(1) - modifies links in place using constant extra variables + +# Definition for singly-linked list. +# class ListNode: +# def __init__(self, val=0, next=None): +# self.val = val +# self.next = next + + +class Solution: + + def removeNthFromEnd(self, head, n: int): + dummy = ListNode(0, head) + fast = dummy + slow = dummy + + for _ in range(n + 1): + fast = fast.next + + while fast: + fast = fast.next + slow = slow.next + + slow.next = slow.next.next + + return dummy.next diff --git a/same-tree/dolphinflow86.py b/same-tree/dolphinflow86.py new file mode 100644 index 0000000000..40bb359448 --- /dev/null +++ b/same-tree/dolphinflow86.py @@ -0,0 +1,21 @@ +# N is the minimum number of nodes between trees p and q, and H is tree height. +# TC: O(N) - visits each node at most once comparing values +# SC: O(H) - recursion call stack proportional to tree height (O(N) in worst case) + +# Definition for a binary tree node. +# class TreeNode: +# def __init__(self, val=0, left=None, right=None): +# self.val = val +# self.left = left +# self.right = right + + +class Solution: + + def isSameTree(self, p, q) -> bool: + if not p and not q: + return True + if not p or not q or p.val != q.val: + return False + + return self.isSameTree(p.left, q.left) and self.isSameTree(p.right, q.right)