Coding Questions

Top 100 coding questions in Python

I have shared basic to advanced-level interview questions and answers.

BASIC LEVEL (1-20)

1. Reverse a String

def reverse_string(s):
    return s[::-1]

# Test
print(reverse_string("hello"))  # "olleh"

2. Check if a string is a palindrome

def is_palindrome(s):
    s = s.lower().replace(" ", "")
    return s == s[::-1]

# Test
print(is_palindrome("A man a plan a canal Panama"))  # True

3. Find Factorial

def factorial(n):
    if n == 0 or n == 1:
        return 1
    return n * factorial(n-1)

# Test
print(factorial(5))  # 120

4. Fibonacci Sequence

def fibonacci(n):
    a, b = 0, 1
    result = []
    for _ in range(n):
        result.append(a)
        a, b = b, a + b
    return result

# Test
print(fibonacci(10))  # [0, 1, 1, 2, 3, 5, 8, 13, 21, 34]

5. Check Prime Number

def is_prime(n):
    if n < 2:
        return False
    for i in range(2, int(n**0.5) + 1):
        if n % i == 0:
            return False
    return True

# Test
print(is_prime(17))  # True

6. Find Maximum in List

def find_max(lst):
    if not lst:
        return None
    max_val = lst[0]
    for num in lst:
        if num > max_val:
            max_val = num
    return max_val

# Test
print(find_max([3, 7, 2, 9, 1]))  # 9

7. Remove Duplicates from List

def remove_duplicates(lst):
    return list(set(lst))

# Test
print(remove_duplicates([1, 2, 2, 3, 4, 4, 5]))  # [1, 2, 3, 4, 5]

8. Count Character Frequency

from collections import Counter

def char_frequency(s):
    return dict(Counter(s))

# Test
print(char_frequency("hello"))  # {'h': 1, 'e': 1, 'l': 2, 'o': 1}

9. Check Anagram

def is_anagram(s1, s2):
    return sorted(s1.lower()) == sorted(s2.lower())

# Test
print(is_anagram("listen", "silent"))  # True

10. Find Missing Number in Array

def find_missing(arr):
    n = len(arr) + 1
    expected_sum = n * (n + 1) // 2
    actual_sum = sum(arr)
    return expected_sum - actual_sum

# Test
print(find_missing([1, 2, 3, 5]))  # 4

11. Find Second Largest Number

def second_largest(arr):
    unique_arr = list(set(arr))
    unique_arr.sort()
    return unique_arr[-2] if len(unique_arr) >= 2 else None

# Test
print(second_largest([10, 5, 8, 10, 7]))  # 8

12. Check Armstrong Number

def is_armstrong(n):
    digits = str(n)
    power = len(digits)
    return n == sum(int(d) ** power for d in digits)

# Test
print(is_armstrong(153))  # True (1³ + 5³ + 3³ = 153)

13. Sum of Digits

def sum_of_digits(n):
    return sum(int(d) for d in str(abs(n)))

# Test
print(sum_of_digits(1234))  # 10

14. Find GCD

import math

def find_gcd(a, b):
    return math.gcd(a, b)

# Alternative without math
def find_gcd_manual(a, b):
    while b:
        a, b = b, a % b
    return a

# Test
print(find_gcd(48, 18))  # 6

15. Find LCM

def find_lcm(a, b):
    return abs(a * b) // math.gcd(a, b)

# Test
print(find_lcm(4, 6))  # 12

16. Count Vowels in String

def count_vowels(s):
    vowels = set('aeiouAEIOU')
    return sum(1 for char in s if char in vowels)

# Test
print(count_vowels("Hello World"))  # 3

17. Check if String Contains Only Digits

def is_digit_string(s):
    return s.isdigit()

# Test
print(is_digit_string("12345"))  # True
print(is_digit_string("12a45"))  # False

18. Find Intersection of Two Lists

def intersection(lst1, lst2):
    return list(set(lst1) & set(lst2))

# Test
print(intersection([1, 2, 3, 4], [3, 4, 5, 6]))  # [3, 4]

19. Find Union of Two Lists

def union(lst1, lst2):
    return list(set(lst1) | set(lst2))

# Test
print(union([1, 2, 3], [3, 4, 5]))  # [1, 2, 3, 4, 5]

20. Check Balanced Parentheses

def is_balanced(s):
    stack = []
    brackets = {'(': ')', '{': '}', '[': ']'}

    for char in s:
        if char in brackets:
            stack.append(char)
        elif char in brackets.values():
            if not stack or brackets[stack.pop()] != char:
                return False
    return len(stack) == 0

# Test
print(is_balanced("({[]})"))  # True
print(is_balanced("({[})"))   # False

INTERMEDIATE LEVEL (21-60)

21. Two Sum Problem

def two_sum(nums, target):
    seen = {}
    for i, num in enumerate(nums):
        complement = target - num
        if complement in seen:
            return [seen[complement], i]
        seen[num] = i
    return []

# Test
print(two_sum([2, 7, 11, 15], 9))  # [0, 1]

22. Find Duplicates in Array

def find_duplicates(arr):
    seen = set()
    duplicates = set()
    for num in arr:
        if num in seen:
            duplicates.add(num)
        else:
            seen.add(num)
    return list(duplicates)

# Test
print(find_duplicates([1, 2, 3, 2, 4, 5, 3]))  # [2, 3]

23. Move Zeros to End

def move_zeros(nums):
    non_zero = [num for num in nums if num != 0]
    return non_zero + [0] * (len(nums) - len(non_zero))

# In-place version
def move_zeros_inplace(nums):
    pos = 0
    for i in range(len(nums)):
        if nums[i] != 0:
            nums[pos], nums[i] = nums[i], nums[pos]
            pos += 1
    return nums

# Test
print(move_zeros([0, 1, 0, 3, 12]))  # [1, 3, 12, 0, 0]

24. Rotate Array

def rotate_array(nums, k):
    k = k % len(nums)
    return nums[-k:] + nums[:-k]

# Test
print(rotate_array([1, 2, 3, 4, 5, 6, 7], 3))  # [5, 6, 7, 1, 2, 3, 4]

25. Find Majority Element

def majority_element(nums):
    count = 0
    candidate = None

    for num in nums:
        if count == 0:
            candidate = num
        count += 1 if num == candidate else -1

    # Verify if candidate is majority
    if nums.count(candidate) > len(nums) // 2:
        return candidate
    return None

# Test
print(majority_element([3, 2, 3]))  # 3

26. Binary Search

def binary_search(arr, target):
    left, right = 0, len(arr) - 1

    while left <= right:
        mid = (left + right) // 2
        if arr[mid] == target:
            return mid
        elif arr[mid] < target:
            left = mid + 1
        else:
            right = mid - 1
    return -1

# Test
print(binary_search([1, 2, 3, 4, 5, 6], 4))  # 3

27. Merge Sorted Arrays

def merge_sorted(arr1, arr2):
    i, j = 0, 0
    merged = []

    while i < len(arr1) and j < len(arr2):
        if arr1[i] < arr2[j]:
            merged.append(arr1[i])
            i += 1
        else:
            merged.append(arr2[j])
            j += 1

    merged.extend(arr1[i:])
    merged.extend(arr2[j:])
    return merged

# Test
print(merge_sorted([1, 3, 5], [2, 4, 6]))  # [1, 2, 3, 4, 5, 6]

28. First Non-Repeating Character

from collections import OrderedDict

def first_non_repeating(s):
    char_count = OrderedDict()

    for char in s:
        char_count[char] = char_count.get(char, 0) + 1

    for char, count in char_count.items():
        if count == 1:
            return char
    return None

# Test
print(first_non_repeating("swiss"))  # 'w'

29. Implement Stack using List

class Stack:
    def __init__(self):
        self.items = []

    def push(self, item):
        self.items.append(item)

    def pop(self):
        if not self.is_empty():
            return self.items.pop()
        return None

    def peek(self):
        if not self.is_empty():
            return self.items[-1]
        return None

    def is_empty(self):
        return len(self.items) == 0

    def size(self):
        return len(self.items)

30. Implement Queue using List

class Queue:
    def __init__(self):
        self.items = []

    def enqueue(self, item):
        self.items.append(item)

    def dequeue(self):
        if not self.is_empty():
            return self.items.pop(0)
        return None

    def is_empty(self):
        return len(self.items) == 0

    def size(self):
        return len(self.items)

31. Reverse Linked List

class ListNode:
    def __init__(self, val=0, next=None):
        self.val = val
        self.next = next

def reverse_linked_list(head):
    prev = None
    current = head

    while current:
        next_temp = current.next
        current.next = prev
        prev = current
        current = next_temp

    return prev

32. Detect Cycle in Linked List

def has_cycle(head):
    slow = fast = head

    while fast and fast.next:
        slow = slow.next
        fast = fast.next.next
        if slow == fast:
            return True
    return False

33. Find Middle of Linked List

def find_middle(head):
    slow = fast = head

    while fast and fast.next:
        slow = slow.next
        fast = fast.next.next

    return slow

34. Implement Binary Tree

class TreeNode:
    def __init__(self, val=0, left=None, right=None):
        self.val = val
        self.left = left
        self.right = right

class BinaryTree:
    def inorder_traversal(self, root):
        result = []
        self._inorder(root, result)
        return result

    def _inorder(self, node, result):
        if node:
            self._inorder(node.left, result)
            result.append(node.val)
            self._inorder(node.right, result)

35. Tree Traversals

def preorder(root):
    if not root:
        return []
    return [root.val] + preorder(root.left) + preorder(root.right)

def inorder(root):
    if not root:
        return []
    return inorder(root.left) + [root.val] + inorder(root.right)

def postorder(root):
    if not root:
        return []
    return postorder(root.left) + postorder(root.right) + [root.val]

def level_order(root):
    if not root:
        return []

    result, queue = [], [root]
    while queue:
        level = []
        for _ in range(len(queue)):
            node = queue.pop(0)
            level.append(node.val)
            if node.left:
                queue.append(node.left)
            if node.right:
                queue.append(node.right)
        result.append(level)
    return result

36. Maximum Depth of Binary Tree

def max_depth(root):
    if not root:
        return 0
    return 1 + max(max_depth(root.left), max_depth(root.right))

37. Validate Binary Search Tree

def is_valid_bst(root, min_val=float('-inf'), max_val=float('inf')):
    if not root:
        return True

    if not (min_val < root.val < max_val):
        return False

    return (is_valid_bst(root.left, min_val, root.val) and
            is_valid_bst(root.right, root.val, max_val))

38. Find All Permutations

def permutations(nums):
    result = []

    def backtrack(start):
        if start == len(nums):
            result.append(nums[:])
            return

        for i in range(start, len(nums)):
            nums[start], nums[i] = nums[i], nums[start]
            backtrack(start + 1)
            nums[start], nums[i] = nums[i], nums[start]

    backtrack(0)
    return result

# Test
print(permutations([1, 2, 3]))  # [[1,2,3], [1,3,2], [2,1,3], ...]

39. Find All Subsets

def subsets(nums):
    result = [[]]

    for num in nums:
        result += [subset + [num] for subset in result]

    return result

# Test
print(subsets([1, 2, 3]))  # [[], [1], [2], [3], [1,2], [1,3], [2,3], [1,2,3]]

40. Longest Substring Without Repeating Characters

def length_of_longest_substring(s):
    char_set = set()
    left = max_length = 0

    for right in range(len(s)):
        while s[right] in char_set:
            char_set.remove(s[left])
            left += 1
        char_set.add(s[right])
        max_length = max(max_length, right - left + 1)

    return max_length

# Test
print(length_of_longest_substring("abcabcbb"))  # 3

41. Container With Most Water

def max_area(height):
    left, right = 0, len(height) - 1
    max_water = 0

    while left < right:
        width = right - left
        h = min(height[left], height[right])
        max_water = max(max_water, width * h)

        if height[left] < height[right]:
            left += 1
        else:
            right -= 1

    return max_water

# Test
print(max_area([1,8,6,2,5,4,8,3,7]))  # 49

42. 3Sum Problem

def three_sum(nums):
    nums.sort()
    result = []

    for i in range(len(nums) - 2):
        if i > 0 and nums[i] == nums[i-1]:
            continue

        left, right = i + 1, len(nums) - 1

        while left < right:
            total = nums[i] + nums[left] + nums[right]
            if total < 0:
                left += 1
            elif total > 0:
                right -= 1
            else:
                result.append([nums[i], nums[left], nums[right]])
                while left < right and nums[left] == nums[left + 1]:
                    left += 1
                while left < right and nums[right] == nums[right - 1]:
                    right -= 1
                left += 1
                right -= 1

    return result

# Test
print(three_sum([-1, 0, 1, 2, -1, -4]))  # [[-1,-1,2], [-1,0,1]]

43. Merge Intervals

def merge_intervals(intervals):
    if not intervals:
        return []

    intervals.sort(key=lambda x: x[0])
    merged = [intervals[0]]

    for current in intervals[1:]:
        prev = merged[-1]
        if current[0] <= prev[1]:
            prev[1] = max(prev[1], current[1])
        else:
            merged.append(current)

    return merged

# Test
print(merge_intervals([[1,3], [2,6], [8,10], [15,18]]))  # [[1,6], [8,10], [15,18]]

44. Find Peak Element

def find_peak_element(nums):
    left, right = 0, len(nums) - 1

    while left < right:
        mid = (left + right) // 2
        if nums[mid] > nums[mid + 1]:
            right = mid
        else:
            left = mid + 1

    return left

# Test
print(find_peak_element([1,2,3,1]))  # 2

45. Search in Rotated Sorted Array

def search_rotated(nums, target):
    left, right = 0, len(nums) - 1

    while left <= right:
        mid = (left + right) // 2

        if nums[mid] == target:
            return mid

        # Left half is sorted
        if nums[left] <= nums[mid]:
            if nums[left] <= target < nums[mid]:
                right = mid - 1
            else:
                left = mid + 1
        # Right half is sorted
        else:
            if nums[mid] < target <= nums[right]:
                left = mid + 1
            else:
                right = mid - 1

    return -1

# Test
print(search_rotated([4,5,6,7,0,1,2], 0))  # 4

46. Word Break Problem

def word_break(s, word_dict):
    word_set = set(word_dict)
    dp = [False] * (len(s) + 1)
    dp[0] = True

    for i in range(1, len(s) + 1):
        for j in range(i):
            if dp[j] and s[j:i] in word_set:
                dp[i] = True
                break

    return dp[len(s)]

# Test
print(word_break("leetcode", ["leet", "code"]))  # True

47. Longest Palindromic Substring

def longest_palindrome(s):
    if not s:
        return ""

    start, max_len = 0, 1

    def expand_around_center(left, right):
        while left >= 0 and right < len(s) and s[left] == s[right]:
            left -= 1
            right += 1
        return left + 1, right - 1

    for i in range(len(s)):
        # Odd length
        l1, r1 = expand_around_center(i, i)
        # Even length
        l2, r2 = expand_around_center(i, i + 1)

        if r1 - l1 + 1 > max_len:
            start, max_len = l1, r1 - l1 + 1
        if r2 - l2 + 1 > max_len:
            start, max_len = l2, r2 - l2 + 1

    return s[start:start + max_len]

# Test
print(longest_palindrome("babad"))  # "bab" or "aba"

48. Implement LRU Cache

from collections import OrderedDict

class LRUCache:
    def __init__(self, capacity):
        self.cache = OrderedDict()
        self.capacity = capacity

    def get(self, key):
        if key not in self.cache:
            return -1
        self.cache.move_to_end(key)
        return self.cache[key]

    def put(self, key, value):
        if key in self.cache:
            self.cache.move_to_end(key)
        self.cache[key] = value
        if len(self.cache) > self.capacity:
            self.cache.popitem(last=False)

49. Find Kth Largest Element

import heapq

def find_kth_largest(nums, k):
    return heapq.nlargest(k, nums)[-1]

# Alternative using quickselect
def find_kth_largest_quickselect(nums, k):
    k = len(nums) - k

    def quickselect(left, right):
        pivot = nums[right]
        p = left

        for i in range(left, right):
            if nums[i] <= pivot:
                nums[p], nums[i] = nums[i], nums[p]
                p += 1

        nums[p], nums[right] = nums[right], nums[p]

        if p < k:
            return quickselect(p + 1, right)
        elif p > k:
            return quickselect(left, p - 1)
        else:
            return nums[p]

    return quickselect(0, len(nums) - 1)

# Test
print(find_kth_largest([3,2,1,5,6,4], 2))  # 5

50. Top K Frequent Elements

from collections import Counter
import heapq

def top_k_frequent(nums, k):
    count = Counter(nums)
    return heapq.nlargest(k, count.keys(), key=count.get)

# Alternative
def top_k_frequent_bucket(nums, k):
    count = Counter(nums)
    buckets = [[] for _ in range(len(nums) + 1)]

    for num, freq in count.items():
        buckets[freq].append(num)

    result = []
    for i in range(len(buckets) - 1, 0, -1):
        result.extend(buckets[i])
        if len(result) >= k:
            return result[:k]

    return result

# Test
print(top_k_frequent([1,1,1,2,2,3], 2))  # [1,2]

ADVANCED LEVEL (51-80)

51. Serialize and Deserialize Binary Tree

class Codec:
    def serialize(self, root):
        def dfs(node):
            if not node:
                result.append("null")
                return
            result.append(str(node.val))
            dfs(node.left)
            dfs(node.right)

        result = []
        dfs(root)
        return ",".join(result)

    def deserialize(self, data):
        def dfs():
            val = next(vals)
            if val == "null":
                return None
            node = TreeNode(int(val))
            node.left = dfs()
            node.right = dfs()
            return node

        vals = iter(data.split(","))
        return dfs()

52. Find Median from Data Stream

import heapq

class MedianFinder:
    def __init__(self):
        self.small = []  # max heap (store negatives)
        self.large = []  # min heap

    def add_num(self, num):
        heapq.heappush(self.small, -num)

        if (self.small and self.large and 
            -self.small[0] > self.large[0]):
            val = -heapq.heappop(self.small)
            heapq.heappush(self.large, val)

        if len(self.small) > len(self.large) + 1:
            val = -heapq.heappop(self.small)
            heapq.heappush(self.large, val)
        elif len(self.large) > len(self.small) + 1:
            val = heapq.heappop(self.large)
            heapq.heappush(self.small, -val)

    def find_median(self):
        if len(self.small) > len(self.large):
            return -self.small[0]
        elif len(self.large) > len(self.small):
            return self.large[0]
        else:
            return (-self.small[0] + self.large[0]) / 2.0

53. Regular Expression Matching

def is_match(s, p):
    memo = {}

    def dp(i, j):
        if (i, j) in memo:
            return memo[(i, j)]

        if j == len(p):
            return i == len(s)

        first_match = i < len(s) and (p[j] == s[i] or p[j] == '.')

        if j + 1 < len(p) and p[j + 1] == '*':
            ans = (dp(i, j + 2) or 
                   (first_match and dp(i + 1, j)))
        else:
            ans = first_match and dp(i + 1, j + 1)

        memo[(i, j)] = ans
        return ans

    return dp(0, 0)

# Test
print(is_match("aa", "a*"))  # True

54. Wildcard Matching

def is_match_wildcard(s, p):
    s_len, p_len = len(s), len(p)
    dp = [[False] * (p_len + 1) for _ in range(s_len + 1)]
    dp[0][0] = True

    for j in range(1, p_len + 1):
        if p[j-1] == '*':
            dp[0][j] = dp[0][j-1]

    for i in range(1, s_len + 1):
        for j in range(1, p_len + 1):
            if p[j-1] == '*':
                dp[i][j] = dp[i-1][j] or dp[i][j-1]
            elif p[j-1] == '?' or s[i-1] == p[j-1]:
                dp[i][j] = dp[i-1][j-1]

    return dp[s_len][p_len]

55. Edit Distance

def min_edit_distance(word1, word2):
    m, n = len(word1), len(word2)
    dp = [[0] * (n + 1) for _ in range(m + 1)]

    for i in range(m + 1):
        dp[i][0] = i
    for j in range(n + 1):
        dp[0][j] = j

    for i in range(1, m + 1):
        for j in range(1, n + 1):
            if word1[i-1] == word2[j-1]:
                dp[i][j] = dp[i-1][j-1]
            else:
                dp[i][j] = 1 + min(dp[i-1][j],    # delete
                                   dp[i][j-1],    # insert
                                   dp[i-1][j-1])  # replace

    return dp[m][n]

# Test
print(min_edit_distance("horse", "ros"))  # 3

56. Coin Change Problem

def coin_change(coins, amount):
    dp = [float('inf')] * (amount + 1)
    dp[0] = 0

    for coin in coins:
        for i in range(coin, amount + 1):
            dp[i] = min(dp[i], dp[i - coin] + 1)

    return dp[amount] if dp[amount] != float('inf') else -1

# Test
print(coin_change([1, 2, 5], 11))  # 3 (5+5+1)

57. Longest Increasing Subsequence

def length_of_lis(nums):
    dp = [1] * len(nums)

    for i in range(len(nums)):
        for j in range(i):
            if nums[i] > nums[j]:
                dp[i] = max(dp[i], dp[j] + 1)

    return max(dp) if dp else 0

# O(n log n) solution
def length_of_lis_optimized(nums):
    import bisect
    tails = []

    for num in nums:
        pos = bisect.bisect_left(tails, num)
        if pos == len(tails):
            tails.append(num)
        else:
            tails[pos] = num

    return len(tails)

# Test
print(length_of_lis([10,9,2,5,3,7,101,18]))  # 4

58. Maximum Subarray Sum (Kadane’s Algorithm)

def max_subarray_sum(nums):
    max_current = max_global = nums[0]

    for i in range(1, len(nums)):
        max_current = max(nums[i], max_current + nums[i])
        max_global = max(max_global, max_current)

    return max_global

# Test
print(max_subarray_sum([-2,1,-3,4,-1,2,1,-5,4]))  # 6

59. House Robber

def rob(nums):
    if not nums:
        return 0
    if len(nums) == 1:
        return nums[0]

    dp = [0] * len(nums)
    dp[0] = nums[0]
    dp[1] = max(nums[0], nums[1])

    for i in range(2, len(nums)):
        dp[i] = max(dp[i-1], dp[i-2] + nums[i])

    return dp[-1]

# Test
print(rob([1,2,3,1]))  # 4

60. Climbing Stairs

def climb_stairs(n):
    if n <= 2:
        return n

    dp = [0] * (n + 1)
    dp[1] = 1
    dp[2] = 2

    for i in range(3, n + 1):
        dp[i] = dp[i-1] + dp[i-2]

    return dp[n]

# Test
print(climb_stairs(5))  # 8

61. Unique Paths

def unique_paths(m, n):
    dp = [[1] * n for _ in range(m)]

    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]

# Test
print(unique_paths(3, 7))  # 28

62. Decode Ways

def num_decodings(s):
    if not s or s[0] == '0':
        return 0

    dp = [0] * (len(s) + 1)
    dp[0] = 1
    dp[1] = 1

    for i in range(2, len(s) + 1):
        one_digit = int(s[i-1:i])
        two_digits = int(s[i-2:i])

        if 1 <= one_digit <= 9:
            dp[i] += dp[i-1]
        if 10 <= two_digits <= 26:
            dp[i] += dp[i-2]

    return dp[-1]

# Test
print(num_decodings("12"))  # 2 (AB or L)

63. Word Search

def exist(board, word):
    def dfs(i, j, k):
        if k == len(word):
            return True
        if (i < 0 or i >= len(board) or 
            j < 0 or j >= len(board[0]) or 
            board[i][j] != word[k]):
            return False

        temp = board[i][j]
        board[i][j] = '#'

        found = (dfs(i+1, j, k+1) or
                dfs(i-1, j, k+1) or
                dfs(i, j+1, k+1) or
                dfs(i, j-1, k+1))

        board[i][j] = temp
        return found

    for i in range(len(board)):
        for j in range(len(board[0])):
            if dfs(i, j, 0):
                return True
    return False

# Test
board = [['A','B','C','E'],
         ['S','F','C','S'],
         ['A','D','E','E']]
print(exist(board, "ABCCED"))  # True

64. Number of Islands

def num_islands(grid):
    if not grid:
        return 0

    def dfs(i, j):
        if (i < 0 or i >= len(grid) or 
            j < 0 or j >= len(grid[0]) or 
            grid[i][j] != '1'):
            return

        grid[i][j] = '0'
        dfs(i+1, j)
        dfs(i-1, j)
        dfs(i, j+1)
        dfs(i, j-1)

    count = 0
    for i in range(len(grid)):
        for j in range(len(grid[0])):
            if grid[i][j] == '1':
                count += 1
                dfs(i, j)

    return count

# Test
grid = [
    ['1','1','1','1','0'],
    ['1','1','0','1','0'],
    ['1','1','0','0','0'],
    ['0','0','0','0','0']
]
print(num_islands(grid))  # 1

65. Course Schedule (Cycle Detection)

def can_finish(num_courses, prerequisites):
    from collections import defaultdict

    graph = defaultdict(list)
    for course, prereq in prerequisites:
        graph[prereq].append(course)

    visited = [0] * num_courses  # 0=unvisited, 1=visiting, 2=visited

    def has_cycle(course):
        if visited[course] == 1:
            return True
        if visited[course] == 2:
            return False

        visited[course] = 1

        for neighbor in graph[course]:
            if has_cycle(neighbor):
                return True

        visited[course] = 2
        return False

    for course in range(num_courses):
        if has_cycle(course):
            return False

    return True

# Test
print(can_finish(2, [[1,0]]))  # True

66. Minimum Window Substring

from collections import Counter

def min_window(s, t):
    if not s or not t:
        return ""

    dict_t = Counter(t)
    required = len(dict_t)

    left = right = 0
    formed = 0
    window_counts = {}

    ans = float("inf"), None, None

    while right < len(s):
        char = s[right]
        window_counts[char] = window_counts.get(char, 0) + 1

        if char in dict_t and window_counts[char] == dict_t[char]:
            formed += 1

        while left <= right and formed == required:
            char = s[left]

            if right - left + 1 < ans[0]:
                ans = (right - left + 1, left, right)

            window_counts[char] -= 1
            if char in dict_t and window_counts[char] < dict_t[char]:
                formed -= 1

            left += 1

        right += 1

    return "" if ans[0] == float("inf") else s[ans[1]:ans[2] + 1]

# Test
print(min_window("ADOBECODEBANC", "ABC"))  # "BANC"

67. Sliding Window Maximum

from collections import deque

def max_sliding_window(nums, k):
    if not nums:
        return []

    result = []
    dq = deque()

    for i in range(len(nums)):
        # Remove elements out of window
        while dq and dq[0] <= i - k:
            dq.popleft()

        # Remove smaller elements
        while dq and nums[dq[-1]] <= nums[i]:
            dq.pop()

        dq.append(i)

        if i >= k - 1:
            result.append(nums[dq[0]])

    return result

# Test
print(max_sliding_window([1,3,-1,-3,5,3,6,7], 3))  # [3,3,5,5,6,7]

68. Trapping Rain Water

def trap(height):
    if not height:
        return 0

    left, right = 0, len(height) - 1
    left_max, right_max = height[left], height[right]
    water = 0

    while left < right:
        if left_max < right_max:
            left += 1
            left_max = max(left_max, height[left])
            water += left_max - height[left]
        else:
            right -= 1
            right_max = max(right_max, height[right])
            water += right_max - height[right]

    return water

# Test
print(trap([0,1,0,2,1,0,1,3,2,1,2,1]))  # 6

69. Largest Rectangle in Histogram

def largest_rectangle_area(heights):
    stack = []
    max_area = 0
    heights.append(0)  # Sentinel

    for i, h in enumerate(heights):
        while stack and heights[stack[-1]] > h:
            height = heights[stack.pop()]
            width = i if not stack else i - stack[-1] - 1
            max_area = max(max_area, height * width)
        stack.append(i)

    heights.pop()
    return max_area

# Test
print(largest_rectangle_area([2,1,5,6,2,3]))  # 10

70. Merge K Sorted Lists

import heapq

def merge_k_lists(lists):
    heap = []

    # Push first element from each list
    for i, lst in enumerate(lists):
        if lst:
            heapq.heappush(heap, (lst[0], i, 0))

    result = []
    while heap:
        val, list_idx, element_idx = heapq.heappop(heap)
        result.append(val)

        if element_idx + 1 < len(lists[list_idx]):
            next_val = lists[list_idx][element_idx + 1]
            heapq.heappush(heap, (next_val, list_idx, element_idx + 1))

    return result

# Test
lists = [[1,4,5], [1,3,4], [2,6]]
print(merge_k_lists(lists))  # [1,1,2,3,4,4,5,6]

71. Sort Colors (Dutch National Flag)

def sort_colors(nums):
    low, mid, high = 0, 0, len(nums) - 1

    while mid <= high:
        if nums[mid] == 0:
            nums[low], nums[mid] = nums[mid], nums[low]
            low += 1
            mid += 1
        elif nums[mid] == 1:
            mid += 1
        else:
            nums[mid], nums[high] = nums[high], nums[mid]
            high -= 1

# Test
nums = [2,0,2,1,1,0]
sort_colors(nums)
print(nums)  # [0,0,1,1,2,2]

72. Find First and Last Position

def search_range(nums, target):
    def find_left():
        left, right = 0, len(nums) - 1
        while left <= right:
            mid = (left + right) // 2
            if nums[mid] < target:
                left = mid + 1
            else:
                right = mid - 1
        return left

    def find_right():
        left, right = 0, len(nums) - 1
        while left <= right:
            mid = (left + right) // 2
            if nums[mid] <= target:
                left = mid + 1
            else:
                right = mid - 1
        return right

    left_idx = find_left()
    right_idx = find_right()

    if left_idx <= right_idx:
        return [left_idx, right_idx]
    return [-1, -1]

# Test
print(search_range([5,7,7,8,8,10], 8))  # [3,4]

73. Spiral Matrix

def spiral_order(matrix):
    if not matrix:
        return []

    result = []
    top, bottom = 0, len(matrix) - 1
    left, right = 0, len(matrix[0]) - 1

    while top <= bottom and left <= right:
        # Top row
        for j in range(left, right + 1):
            result.append(matrix[top][j])
        top += 1

        # Right column
        for i in range(top, bottom + 1):
            result.append(matrix[i][right])
        right -= 1

        if top <= bottom:
            # Bottom row
            for j in range(right, left - 1, -1):
                result.append(matrix[bottom][j])
            bottom -= 1

        if left <= right:
            # Left column
            for i in range(bottom, top - 1, -1):
                result.append(matrix[i][left])
            left += 1

    return result

# Test
matrix = [[1,2,3],[4,5,6],[7,8,9]]
print(spiral_order(matrix))  # [1,2,3,6,9,8,7,4,5]

74. Set Matrix Zeros

def set_zeroes(matrix):
    m, n = len(matrix), len(matrix[0])
    first_row_zero = any(matrix[0][j] == 0 for j in range(n))
    first_col_zero = any(matrix[i][0] == 0 for i in range(m))

    # Mark zeros
    for i in range(1, m):
        for j in range(1, n):
            if matrix[i][j] == 0:
                matrix[i][0] = 0
                matrix[0][j] = 0

    # Set zeros
    for i in range(1, m):
        for j in range(1, n):
            if matrix[i][0] == 0 or matrix[0][j] == 0:
                matrix[i][j] = 0

    if first_row_zero:
        for j in range(n):
            matrix[0][j] = 0

    if first_col_zero:
        for i in range(m):
            matrix[i][0] = 0

# Test
matrix = [[1,1,1],[1,0,1],[1,1,1]]
set_zeroes(matrix)
print(matrix)  # [[1,0,1],[0,0,0],[1,0,1]]

75. Valid Sudoku

def is_valid_sudoku(board):
    rows = [set() for _ in range(9)]
    cols = [set() for _ in range(9)]
    boxes = [set() for _ in range(9)]

    for i in range(9):
        for j in range(9):
            val = board[i][j]
            if val == '.':
                continue

            box_idx = (i // 3) * 3 + (j // 3)

            if (val in rows[i] or 
                val in cols[j] or 
                val in boxes[box_idx]):
                return False

            rows[i].add(val)
            cols[j].add(val)
            boxes[box_idx].add(val)

    return True

# Test
board = [
    ["5","3",".",".","7",".",".",".","."],
    ["6",".",".","1","9","5",".",".","."],
    [".","9","8",".",".",".",".","6","."],
    ["8",".",".",".","6",".",".",".","3"],
    ["4",".",".","8",".","3",".",".","1"],
    ["7",".",".",".","2",".",".",".","6"],
    [".","6",".",".",".",".","2","8","."],
    [".",".",".","4","1","9",".",".","5"],
    [".",".",".",".","8",".",".","7","9"]
]
print(is_valid_sudoku(board))  # True

76. N-Queens Problem

def solve_n_queens(n):
    def is_safe(row, col):
        # Check column
        for i in range(row):
            if board[i][col] == 'Q':
                return False

        # Check diagonal (top-left)
        i, j = row - 1, col - 1
        while i >= 0 and j >= 0:
            if board[i][j] == 'Q':
                return False
            i -= 1
            j -= 1

        # Check diagonal (top-right)
        i, j = row - 1, col + 1
        while i >= 0 and j < n:
            if board[i][j] == 'Q':
                return False
            i -= 1
            j += 1

        return True

    def backtrack(row):
        if row == n:
            result.append([''.join(row) for row in board])
            return

        for col in range(n):
            if is_safe(row, col):
                board[row][col] = 'Q'
                backtrack(row + 1)
                board[row][col] = '.'

    result = []
    board = [['.' for _ in range(n)] for _ in range(n)]
    backtrack(0)
    return result

# Test
print(len(solve_n_queens(4)))  # 2 solutions for 4x4

77. Sudoku Solver

def solve_sudoku(board):
    def is_valid(row, col, num):
        # Check row
        for j in range(9):
            if board[row][j] == num:
                return False

        # Check column
        for i in range(9):
            if board[i][col] == num:
                return False

        # Check box
        box_row, box_col = (row // 3) * 3, (col // 3) * 3
        for i in range(box_row, box_row + 3):
            for j in range(box_col, box_col + 3):
                if board[i][j] == num:
                    return False

        return True

    def solve():
        for i in range(9):
            for j in range(9):
                if board[i][j] == '.':
                    for num in '123456789':
                        if is_valid(i, j, num):
                            board[i][j] = num
                            if solve():
                                return True
                            board[i][j] = '.'
                    return False
        return True

    solve()
    return board

78. Evaluate Reverse Polish Notation

def eval_rpn(tokens):
    stack = []
    operators = {'+', '-', '*', '/'}

    for token in tokens:
        if token not in operators:
            stack.append(int(token))
        else:
            b = stack.pop()
            a = stack.pop()

            if token == '+':
                stack.append(a + b)
            elif token == '-':
                stack.append(a - b)
            elif token == '*':
                stack.append(a * b)
            else:  # division
                stack.append(int(a / b))

    return stack[0]

# Test
print(eval_rPN(["2","1","+","3","*"]))  # 9

79. Implement Trie (Prefix Tree)

class TrieNode:
    def __init__(self):
        self.children = {}
        self.is_end = False

class Trie:
    def __init__(self):
        self.root = TrieNode()

    def insert(self, word):
        node = self.root
        for char in word:
            if char not in node.children:
                node.children[char] = TrieNode()
            node = node.children[char]
        node.is_end = True

    def search(self, word):
        node = self.root
        for char in word:
            if char not in node.children:
                return False
            node = node.children[char]
        return node.is_end

    def starts_with(self, prefix):
        node = self.root
        for char in prefix:
            if char not in node.children:
                return False
            node = node.children[char]
        return True

80. Design Twitter

from collections import defaultdict
import heapq

class Twitter:
    def __init__(self):
        self.tweets = defaultdict(list)  # user_id -> [(timestamp, tweet_id)]
        self.follows = defaultdict(set)  # user_id -> set of followee_ids
        self.timestamp = 0

    def post_tweet(self, user_id, tweet_id):
        self.tweets[user_id].append((self.timestamp, tweet_id))
        self.timestamp += 1

    def get_news_feed(self, user_id):
        # Get all tweets from user and followees
        all_tweets = []
        users = self.follows[user_id] | {user_id}

        for user in users:
            all_tweets.extend(self.tweets[user])

        # Get 10 most recent
        return [tweet_id for _, tweet_id in sorted(all_tweets, reverse=True)[:10]]

    def follow(self, follower_id, followee_id):
        if follower_id != followee_id:
            self.follows[follower_id].add(followee_id)

    def unfollow(self, follower_id, followee_id):
        self.follows[follower_id].discard(followee_id)

ADVANCED ALGORITHMS & DATA STRUCTURES (81-100)

81. LFU Cache

from collections import defaultdict, OrderedDict

class LFUCache:
    def __init__(self, capacity):
        self.capacity = capacity
        self.key_to_val = {}
        self.key_to_freq = {}
        self.freq_to_keys = defaultdict(OrderedDict)
        self.min_freq = 0

    def get(self, key):
        if key not in self.key_to_val:
            return -1

        freq = self.key_to_freq[key]
        self.key_to_freq[key] = freq + 1
        del self.freq_to_keys[freq][key]
        self.freq_to_keys[freq + 1][key] = None

        if len(self.freq_to_keys[freq]) == 0:
            del self.freq_to_keys[freq]
            if self.min_freq == freq:
                self.min_freq += 1

        return self.key_to_val[key]

    def put(self, key, value):
        if self.capacity <= 0:
            return

        if key in self.key_to_val:
            self.key_to_val[key] = value
            self.get(key)
            return

        if len(self.key_to_val) >= self.capacity:
            evict_key, _ = self.freq_to_keys[self.min_freq].popitem(last=False)
            del self.key_to_val[evict_key]
            del self.key_to_freq[evict_key]

        self.key_to_val[key] = value
        self.key_to_freq[key] = 1
        self.freq_to_keys[1][key] = None
        self.min_freq = 1

82. Find Median in Two Sorted Arrays

def find_median_sorted_arrays(nums1, nums2):
    if len(nums1) > len(nums2):
        nums1, nums2 = nums2, nums1

    m, n = len(nums1), len(nums2)
    total = m + n
    half = total // 2

    left, right = 0, m

    while left <= right:
        i = (left + right) // 2
        j = half - i

        if i < m and nums2[j-1] > nums1[i]:
            left = i + 1
        elif i > 0 and nums1[i-1] > nums2[j]:
            right = i - 1
        else:
            # Found correct partition
            if i == 0:
                max_left = nums2[j-1]
            elif j == 0:
                max_left = nums1[i-1]
            else:
                max_left = max(nums1[i-1], nums2[j-1])

            if total % 2 == 1:
                return min(nums1[i] if i < m else float('inf'),
                          nums2[j] if j < n else float('inf'))

            if i == m:
                min_right = nums2[j]
            elif j == n:
                min_right = nums1[i]
            else:
                min_right = min(nums1[i], nums2[j])

            return (max_left + min_right) / 2.0

    return 0.0

# Test
print(find_median_sorted_arrays([1,3], [2]))  # 2.0

83. Longest Consecutive Sequence

def longest_consecutive(nums):
    num_set = set(nums)
    longest = 0

    for num in num_set:
        if num - 1 not in num_set:
            current_num = num
            current_streak = 1

            while current_num + 1 in num_set:
                current_num += 1
                current_streak += 1

            longest = max(longest, current_streak)

    return longest

# Test
print(longest_consecutive([100,4,200,1,3,2]))  # 4

84. Alien Dictionary

from collections import defaultdict, deque

def alien_order(words):
    graph = defaultdict(set)
    in_degree = {c: 0 for word in words for c in word}

    # Build graph
    for i in range(len(words) - 1):
        word1, word2 = words[i], words[i+1]
        min_len = min(len(word1), len(word2))

        # Check for invalid case
        if len(word1) > len(word2) and word1[:min_len] == word2[:min_len]:
            return ""

        for j in range(min_len):
            if word1[j] != word2[j]:
                if word2[j] not in graph[word1[j]]:
                    graph[word1[j]].add(word2[j])
                break

    # Calculate in-degree
    for u in graph:
        for v in graph[u]:
            in_degree[v] += 1

    # Topological sort
    queue = deque([c for c in in_degree if in_degree[c] == 0])
    result = []

    while queue:
        char = queue.popleft()
        result.append(char)

        for neighbor in graph[char]:
            in_degree[neighbor] -= 1
            if in_degree[neighbor] == 0:
                queue.append(neighbor)

    if len(result) != len(in_degree):
        return ""

    return ''.join(result)

# Test
print(alien_order(["wrt","wrf","er","ett","rftt"]))  # "wertf"

85. Minimum Path Sum

def min_path_sum(grid):
    m, n = len(grid), len(grid[0])

    for i in range(1, m):
        grid[i][0] += grid[i-1][0]
    for j in range(1, n):
        grid[0][j] += grid[0][j-1]

    for i in range(1, m):
        for j in range(1, n):
            grid[i][j] += min(grid[i-1][j], grid[i][j-1])

    return grid[m-1][n-1]

# Test
grid = [[1,3,1],[1,5,1],[4,2,1]]
print(min_path_sum(grid))  # 7

86. Palindrome Partitioning

def partition_palindrome(s):
    def is_palindrome(sub):
        return sub == sub[::-1]

    def backtrack(start, path):
        if start == len(s):
            result.append(path[:])
            return

        for end in range(start + 1, len(s) + 1):
            if is_palindrome(s[start:end]):
                path.append(s[start:end])
                backtrack(end, path)
                path.pop()

    result = []
    backtrack(0, [])
    return result

# Test
print(partition_palindrome("aab"))  # [["a","a","b"],["aa","b"]]

87. Reconstruct Itinerary

from collections import defaultdict

def find_itinerary(tickets):
    graph = defaultdict(list)

    for src, dst in sorted(tickets, reverse=True):
        graph[src].append(dst)

    result = []

    def dfs(airport):
        while graph[airport]:
            dfs(graph[airport].pop())
        result.append(airport)

    dfs("JFK")
    return result[::-1]

# Test
tickets = [["MUC","LHR"],["JFK","MUC"],["SFO","SJC"],["LHR","SFO"]]
print(find_itinerary(tickets))  # ["JFK","MUC","LHR","SFO","SJC"]

88. Minimum Height Trees

from collections import defaultdict, deque

def find_min_height_trees(n, edges):
    if n == 1:
        return [0]

    graph = defaultdict(set)
    for u, v in edges:
        graph[u].add(v)
        graph[v].add(u)

    leaves = deque([node for node in range(n) if len(graph[node]) == 1])

    remaining_nodes = n
    while remaining_nodes > 2:
        leaf_count = len(leaves)
        remaining_nodes -= leaf_count

        for _ in range(leaf_count):
            leaf = leaves.popleft()
            neighbor = graph[leaf].pop()
            graph[neighbor].remove(leaf)
            if len(graph[neighbor]) == 1:
                leaves.append(neighbor)

    return list(leaves)

# Test
print(find_min_height_trees(4, [[1,0],[1,2],[1,3]]))  # [1]

89. Word Ladder

from collections import deque

def ladder_length(begin_word, end_word, word_list):
    word_set = set(word_list)
    if end_word not in word_set:
        return 0

    queue = deque([(begin_word, 1)])

    while queue:
        word, length = queue.popleft()

        if word == end_word:
            return length

        for i in range(len(word)):
            for c in 'abcdefghijklmnopqrstuvwxyz':
                next_word = word[:i] + c + word[i+1:]
                if next_word in word_set:
                    word_set.remove(next_word)
                    queue.append((next_word, length + 1))

    return 0

# Test
begin = "hit"
end = "cog"
word_list = ["hot","dot","dog","lot","log","cog"]
print(ladder_length(begin, end, word_list))  # 5

90. Count of Smaller Numbers After Self

def count_smaller(nums):
    def merge_sort(arr):
        mid = len(arr) // 2
        if mid:
            left = merge_sort(arr[:mid])
            right = merge_sort(arr[mid:])

            i = j = 0
            for i in range(len(arr)):
                if j == len(right) or (i < len(left) and left[i][1] <= right[j][1]):
                    arr[i] = left[i]
                    i += 1
                else:
                    arr[i] = right[j]
                    result[arr[i][0]] += len(left) - i
                    j += 1
            return arr
        return arr

    result = [0] * len(nums)
    merge_sort(list(enumerate(nums)))
    return result

# Test
print(count_smaller([5,2,6,1]))  # [2,1,1,0]

91. Maximal Rectangle

def maximal_rectangle(matrix):
    if not matrix:
        return 0

    def largest_rectangle(heights):
        stack = []
        max_area = 0
        heights.append(0)

        for i, h in enumerate(heights):
            while stack and heights[stack[-1]] > h:
                height = heights[stack.pop()]
                width = i if not stack else i - stack[-1] - 1
                max_area = max(max_area, height * width)
            stack.append(i)

        heights.pop()
        return max_area

    heights = [0] * len(matrix[0])
    max_area = 0

    for row in matrix:
        for i, val in enumerate(row):
            heights[i] = heights[i] + 1 if val == '1' else 0
        max_area = max(max_area, largest_rectangle(heights))

    return max_area

# Test
matrix = [["1","0","1","0","0"],
          ["1","0","1","1","1"],
          ["1","1","1","1","1"],
          ["1","0","0","1","0"]]
print(maximal_rectangle(matrix))  # 6

92. Burst Balloons

def max_coins(nums):
    nums = [1] + nums + [1]
    n = len(nums)
    dp = [[0] * n for _ in range(n)]

    for length in range(2, n):
        for left in range(n - length):
            right = left + length
            for k in range(left + 1, right):
                dp[left][right] = max(dp[left][right],
                                      dp[left][k] + dp[k][right] +
                                      nums[left] * nums[k] * nums[right])

    return dp[0][n-1]

# Test
print(max_coins([3,1,5,8]))  # 167

93. Serialize and Deserialize N-ary Tree

class Node:
    def __init__(self, val=None, children=None):
        self.val = val
        self.children = children if children is not None else []

class Codec:
    def serialize(self, root):
        if not root:
            return ""

        result = [str(root.val)]
        for child in root.children:
            result.append(self.serialize(child))
        result.append("#")
        return ",".join(result)

    def deserialize(self, data):
        if not data:
            return None

        def helper():
            val = next(vals)
            if val == "#":
                return None

            node = Node(int(val))
            while True:
                child = helper()
                if child is None:
                    break
                node.children.append(child)
            return node

        vals = iter(data.split(","))
        return helper()

94. Flatten Nested List Iterator

class NestedIterator:
    def __init__(self, nested_list):
        self.stack = []
        self._flatten(nested_list)

    def _flatten(self, nested_list):
        for item in reversed(nested_list):
            if item.isInteger():
                self.stack.append(item.getInteger())
            else:
                self._flatten(item.getList())

    def next(self):
        return self.stack.pop()

    def has_next(self):
        return bool(self.stack)

95. Max Points on a Line

from collections import defaultdict

def max_points(points):
    if len(points) <= 2:
        return len(points)

    def get_slope(p1, p2):
        if p1[0] == p2[0]:
            return float('inf')
        return (p2[1] - p1[1]) / (p2[0] - p1[0])

    max_count = 0

    for i in range(len(points)):
        slopes = defaultdict(int)
        same = 0
        vertical = 0

        for j in range(i + 1, len(points)):
            if points[i] == points[j]:
                same += 1
            else:
                slope = get_slope(points[i], points[j])
                slopes[slope] += 1

        if slopes:
            max_count = max(max_count, max(slopes.values()) + same + 1)
        else:
            max_count = max(max_count, same + 1)

    return max_count

# Test
points = [[1,1],[2,2],[3,3]]
print(max_points(points))  # 3

96. Word Search II

class TrieNode:
    def __init__(self):
        self.children = {}
        self.word = None

class Solution:
    def find_words(self, board, words):
        # Build Trie
        root = TrieNode()
        for word in words:
            node = root
            for char in word:
                if char not in node.children:
                    node.children[char] = TrieNode()
                node = node.children[char]
            node.word = word

        result = []

        def dfs(i, j, node):
            if node.word:
                result.append(node.word)
                node.word = None

            if i < 0 or i >= len(board) or j < 0 or j >= len(board[0]):
                return

            char = board[i][j]
            if char not in node.children:
                return

            board[i][j] = '#'
            for di, dj in [(0,1),(1,0),(0,-1),(-1,0)]:
                dfs(i + di, j + dj, node.children[char])
            board[i][j] = char

        for i in range(len(board)):
            for j in range(len(board[0])):
                dfs(i, j, root)

        return result

# Test
board = [["o","a","a","n"],["e","t","a","e"],["i","h","k","r"],["i","f","l","v"]]
words = ["oath","pea","eat","rain"]
print(Solution().find_words(board, words))  # ["oath","eat"]

97. Candy Crush (1D)

def candy_crush(s):
    stack = []

    for char in s:
        if stack and stack[-1][0] == char:
            stack[-1][1] += 1
            if stack[-1][1] >= 3:
                stack.pop()
        else:
            stack.append([char, 1])

    return ''.join(char * count for char, count in stack)

# Test
print(candy_crush("aaabbbc"))  # "c"
print(candy_crush("aabbbacd"))  # "cd"

98. Employee Free Time

def employee_free_time(schedule):
    intervals = []
    for employee in schedule:
        for interval in employee:
            intervals.append(interval)

    intervals.sort()
    merged = [intervals[0]]

    for start, end in intervals[1:]:
        if start <= merged[-1][1]:
            merged[-1][1] = max(merged[-1][1], end)
        else:
            merged.append([start, end])

    result = []
    for i in range(1, len(merged)):
        result.append([merged[i-1][1], merged[i][0]])

    return result

# Test
schedule = [[[1,2],[5,6]], [[1,3]], [[4,10]]]
print(employee_free_time(schedule))  # [[3,4]]

99. Race Car

from collections import deque

def racecar(target):
    queue = deque([(0, 1, 0)])  # (position, speed, steps)
    visited = set([(0, 1)])

    while queue:
        pos, speed, steps = queue.popleft()

        if pos == target:
            return steps

        # Accelerate
        next_pos = pos + speed
        next_speed = speed * 2
        if (next_pos, next_speed) not in visited:
            visited.add((next_pos, next_speed))
            queue.append((next_pos, next_speed, steps + 1))

        # Reverse
        next_speed = -1 if speed > 0 else 1
        if (pos, next_speed) not in visited:
            visited.add((pos, next_speed))
            queue.append((pos, next_speed, steps + 1))

    return -1

# Test
print(racecar(3))  # 2

100. Swim in Rising Water

import heapq

def swim_in_water(grid):
    n = len(grid)
    visited = [[False] * n for _ in range(n)]
    heap = [(grid[0][0], 0, 0)]
    visited[0][0] = True

    directions = [(0,1),(1,0),(0,-1),(-1,0)]

    while heap:
        time, i, j = heapq.heappop(heap)

        if i == n-1 and j == n-1:
            return time

        for di, dj in directions:
            ni, nj = i + di, j + dj
            if 0 <= ni < n and 0 <= nj < n and not visited[ni][nj]:
                visited[ni][nj] = True
                heapq.heappush(heap, (max(time, grid[ni][nj]), ni, nj))

    return -1

# Test
grid = [[0,2],[1,3]]
print(swim_in_water(grid))  # 3

Leave a Comment

Your email address will not be published. Required fields are marked *

Scroll to Top