PracHub
QuestionsPremiumLearningGuidesCheatsheetNEWCoaches

Quick Overview

This multi-part question evaluates algorithmic problem solving, data-structure selection, complexity analysis, API design, and the handling of trees, arrays, grids, circular structures, and dynamic updates.

  • Medium
  • LinkedIn
  • Coding & Algorithms
  • Software Engineer

Solve six algorithmic problems

Company: LinkedIn

Role: Software Engineer

Category: Coding & Algorithms

Difficulty: Medium

Interview Round: Onsite

Answer the following independent algorithmic prompts. For each, explain your approach, justify data structures, analyze time/space complexity, and provide correct code: 1) Bulb toggling passes: You have n bulbs initially off. For pass i (1 ≤ i ≤ n), toggle every bulb whose index is a multiple of i. After n passes, return the count of bulbs that are on. Follow-up: given m ≤ n passes or a custom toggling set S of divisors, compute the result efficiently without simulating all passes. 2) Repeated word-distance queries: Preprocess an array of words to support many queries of the form shortestDistance(word1, word 2) that returns the minimum index gap between any occurrence of the two words. Design the initialization and query APIs, then optimize for both time and memory. Follow-ups: support dynamic inserts/appends; support queries over a sliding window. 3) Invert a binary tree: Given the root of a binary tree, return its mirror image. Discuss iterative vs. recursive solutions and how to handle nodes missing exactly one child. Follow-ups: verify structural equality between the original and double-inverted tree; invert only nodes at odd depths. 4) Count land clusters in a grid: Given an m×n grid of '1' (land) and '0' (water), return the number of connected land clusters using 4-directional adjacency. Follow-ups: handle dynamic updates turning cells on/off; extend to 8-directional adjacency; optimize with union–find. 5) Longest run in a circular binary array: Given a binary array treated as circular (index wraps around), compute the maximum number of consecutive 1s. Follow-ups: if you may flip up to k zeros to ones, find the new maximum and return one optimal window. 6) Peel leaves by rounds: Given a binary tree, iteratively collect and remove its leaves; output a list of lists where the i-th list contains the values removed at round i. Provide an O(n) solution and discuss how computing node heights leads to the result.

Quick Answer: This multi-part question evaluates algorithmic problem solving, data-structure selection, complexity analysis, API design, and the handling of trees, arrays, grids, circular structures, and dynamic updates.

Part 1: Bulb Toggling Passes

You have n bulbs numbered from 1 to n, and all bulbs start turned off. On pass i, you toggle every bulb whose index is a multiple of i. After performing all passes from 1 to n, return how many bulbs are on. This version asks for the final count after all n passes, without simulating every toggle one by one.

Constraints

  • 0 <= n <= 10^18
  • Bulbs are 1-indexed
  • A toggle changes off to on, or on to off

Examples

Input: (0,)

Expected Output: 0

Explanation: There are no bulbs, so the answer is 0.

Input: (1,)

Expected Output: 1

Explanation: Bulb 1 is toggled once, so it stays on.

Input: (3,)

Expected Output: 1

Explanation: Only bulb 1 remains on.

Input: (10,)

Expected Output: 3

Explanation: The bulbs left on are 1, 4, and 9.

Input: (25,)

Expected Output: 5

Explanation: The bulbs left on are the perfect squares up to 25.

Solution

def solution(n):
    import math
    if n <= 0:
        return 0
    return math.isqrt(n)

Time complexity: O(1). Space complexity: O(1).

Hints

  1. A bulb ends up on only if it is toggled an odd number of times.
  2. Most divisors come in pairs. Which numbers have an unpaired divisor?

Part 2: Repeated Word-Distance Queries

Given a list of words and many queries, answer each query shortestDistance(word1, word2): the minimum absolute difference between any occurrence of word1 and any occurrence of word2 in the list. If a queried word does not appear, return -1 for that query. If word1 == word2, return the minimum distance between two distinct occurrences of that same word, or -1 if it appears fewer than two times.

Constraints

  • 1 <= len(words) <= 10^5
  • 1 <= len(queries) <= 10^5
  • Each word is a non-empty string
  • Total processing should avoid rescanning the full words array for every query

Examples

Input: (["practice", "makes", "perfect", "coding", "makes"], [("coding", "practice"), ("makes", "coding")])

Expected Output: [3, 1]

Explanation: coding is at index 3 and practice at 0, so distance 3. makes occurs at 1 and 4; the closest makes to coding is at 4, so distance 1.

Input: (["a", "b", "a"], [("a", "c")])

Expected Output: [-1]

Explanation: Word c does not appear.

Input: (["a", "x", "a", "a"], [("a", "a"), ("x", "x")])

Expected Output: [1, -1]

Explanation: For a, the closest distinct occurrences are at indices 2 and 3. For x, there is only one occurrence.

Input: (["the", "quick", "brown", "fox", "quick"], [("quick", "fox"), ("the", "brown"), ("quick", "quick"), ("fox", "quick")])

Expected Output: [1, 2, 3, 1]

Explanation: The last query is the same pair as the first, just reversed.

Solution

def solution(words, queries):
    positions = {}
    for i, word in enumerate(words):
        positions.setdefault(word, []).append(i)

    cache = {}
    answer = []

    for w1, w2 in queries:
        key = (w1, w2) if w1 <= w2 else (w2, w1)
        if key in cache:
            answer.append(cache[key])
            continue

        if w1 not in positions or w2 not in positions:
            cache[key] = -1
            answer.append(-1)
            continue

        if w1 == w2:
            pos = positions[w1]
            if len(pos) < 2:
                dist = -1
            else:
                dist = min(pos[i] - pos[i - 1] for i in range(1, len(pos)))
            cache[key] = dist
            answer.append(dist)
            continue

        a = positions[w1]
        b = positions[w2]
        i = j = 0
        best = float('inf')

        while i < len(a) and j < len(b):
            best = min(best, abs(a[i] - b[j]))
            if a[i] < b[j]:
                i += 1
            else:
                j += 1

        cache[key] = best
        answer.append(best)

    return answer

Time complexity: O(n + sum over uncached queries of (occ(word1) + occ(word2)))). Space complexity: O(n + u).

Hints

  1. Store all positions for each distinct word in sorted order as you scan the list once.
  2. To compare two sorted position lists efficiently, try a two-pointer walk.

Part 3: Invert a Binary Tree

A binary tree is given in level-order array form, using None for missing children. Return the mirror image of the tree, also in level-order array form with trailing None values removed. In the inverted tree, every node's left and right children are swapped.

Constraints

  • 0 <= number of list entries <= 10^4
  • Node values are integers
  • If level_order is empty, the tree is empty

Examples

Input: ([4, 2, 7, 1, 3, 6, 9],)

Expected Output: [4, 7, 2, 9, 6, 3, 1]

Explanation: Every left/right subtree pair is mirrored.

Input: ([2, 1, 3, None, None, 4],)

Expected Output: [2, 3, 1, None, 4]

Explanation: Node 3's single child moves from the left side to the right side after inversion.

Input: ([],)

Expected Output: []

Explanation: An empty tree stays empty.

Input: ([1],)

Expected Output: [1]

Explanation: A single-node tree is unchanged.

Input: ([1, None, 2],)

Expected Output: [1, 2]

Explanation: A node with only a right child becomes a node with only a left child.

Solution

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

    class Node:
        __slots__ = ('val', 'left', 'right')

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

    nodes = [None if v is None else Node(v) for v in level_order]

    for i, node in enumerate(nodes):
        if node is None:
            continue
        left_i = 2 * i + 1
        right_i = 2 * i + 2
        if left_i < len(nodes):
            node.left = nodes[left_i]
        if right_i < len(nodes):
            node.right = nodes[right_i]

    root = nodes[0]
    if root is None:
        return []

    queue = [root]
    head = 0
    while head < len(queue):
        node = queue[head]
        head += 1
        node.left, node.right = node.right, node.left
        if node.left is not None:
            queue.append(node.left)
        if node.right is not None:
            queue.append(node.right)

    output = []
    queue = [root]
    head = 0
    while head < len(queue):
        node = queue[head]
        head += 1
        if node is None:
            output.append(None)
            continue
        output.append(node.val)
        queue.append(node.left)
        queue.append(node.right)

    while output and output[-1] is None:
        output.pop()

    return output

Time complexity: O(n). Space complexity: O(n).

Hints

  1. Inversion is local: at every node, swap the left and right pointers.
  2. A breadth-first traversal is an easy way to process every node iteratively.

Part 4: Count Land Clusters in a Grid

You are given a grid of '1' and '0' characters, where '1' means land and '0' means water. Two land cells belong to the same cluster if they are connected horizontally or vertically. Return the number of connected land clusters.

Constraints

  • 0 <= number of rows <= 300
  • 0 <= number of columns <= 300
  • All rows have the same length
  • Adjacency is only up, down, left, and right

Examples

Input: (["11000", "11000", "00100", "00011"],)

Expected Output: 3

Explanation: There are three separate land clusters.

Input: (["000", "000"],)

Expected Output: 0

Explanation: There is no land.

Input: (["1"],)

Expected Output: 1

Explanation: A single land cell is one cluster.

Input: (["10", "01"],)

Expected Output: 2

Explanation: Diagonal cells are not connected under 4-directional adjacency.

Input: ([],)

Expected Output: 0

Explanation: An empty grid has zero clusters.

Solution

def solution(grid):
    if not grid:
        return 0
    rows = len(grid)
    cols = len(grid[0]) if grid[0] else 0
    if cols == 0:
        return 0

    g = [list(row) for row in grid]
    count = 0

    for r in range(rows):
        for c in range(cols):
            if g[r][c] != '1':
                continue

            count += 1
            stack = [(r, c)]
            g[r][c] = '0'

            while stack:
                x, y = stack.pop()

                if x > 0 and g[x - 1][y] == '1':
                    g[x - 1][y] = '0'
                    stack.append((x - 1, y))
                if x + 1 < rows and g[x + 1][y] == '1':
                    g[x + 1][y] = '0'
                    stack.append((x + 1, y))
                if y > 0 and g[x][y - 1] == '1':
                    g[x][y - 1] = '0'
                    stack.append((x, y - 1))
                if y + 1 < cols and g[x][y + 1] == '1':
                    g[x][y + 1] = '0'
                    stack.append((x, y + 1))

    return count

Time complexity: O(m * n). Space complexity: O(m * n) in the worst case due to the exploration stack.

Hints

  1. When you find an unvisited land cell, explore its whole component with DFS or BFS.
  2. Mark cells as visited so you do not count the same island more than once.

Part 5: Longest Run in a Circular Binary Array

You are given a binary array nums that should be treated as circular, so index n - 1 is adjacent to index 0. You may flip at most k zeros to ones. Return a tuple (max_len, start) where max_len is the maximum number of consecutive 1s obtainable in some circular window after at most k flips, and start is the smallest starting index of one optimal window in the original array. If nums is empty, return (0, -1). For a non-empty array, if the best length is 0, return start = 0.

Constraints

  • 0 <= len(nums) <= 2 * 10^5
  • 0 <= k <= len(nums)
  • Each element of nums is either 0 or 1
  • The chosen window length cannot exceed len(nums)

Examples

Input: ([1, 1, 0, 1], 0)

Expected Output: (3, 3)

Explanation: The best circular run is indices 3 -> 0 -> 1, which gives three 1s.

Input: ([1, 0, 1, 1, 0], 1)

Expected Output: (4, 0)

Explanation: Flipping the zero at index 1 gives a length-4 window starting at 0. Another length-4 answer starts at 2, but 0 is smaller.

Input: ([0, 0, 0], 2)

Expected Output: (2, 0)

Explanation: You can flip at most two zeros, so the best window length is 2.

Input: ([1, 1, 1], 1)

Expected Output: (3, 0)

Explanation: The whole array is already all 1s.

Input: ([], 1)

Expected Output: (0, -1)

Explanation: Empty input has no valid starting index.

Solution

def solution(nums, k):
    n = len(nums)
    if n == 0:
        return (0, -1)

    left = 0
    zeros = 0
    best_len = 0
    best_start = 0

    for right in range(2 * n):
        if nums[right % n] == 0:
            zeros += 1

        while zeros > k or right - left + 1 > n:
            if nums[left % n] == 0:
                zeros -= 1
            left += 1

        if left < n:
            cur_len = right - left + 1
            if cur_len > best_len or (cur_len == best_len and left < best_start):
                best_len = cur_len
                best_start = left

    return (best_len, best_start)

Time complexity: O(n). Space complexity: O(1).

Hints

  1. A standard sliding window works for 'at most k zeros', but circularity suggests looking at a doubled array.
  2. Even with doubling, do not allow a window longer than the original array length.

Part 6: Peel Leaves by Rounds

A binary tree is given in level-order array form, using None for missing children. Repeatedly collect all current leaves, remove them, and continue until the tree is empty. Return a list of lists where the ith inner list contains the node values removed during round i. Within each round, output values in the left-to-right order produced by a postorder DFS.

Constraints

  • 0 <= number of list entries <= 10^4
  • Node values are integers
  • The intended solution should run in O(n)

Examples

Input: ([1, 2, 3, 4, 5],)

Expected Output: [[4, 5, 3], [2], [1]]

Explanation: First remove leaves 4, 5, and 3; then 2 becomes a leaf; finally 1.

Input: ([1],)

Expected Output: [[1]]

Explanation: A single node is removed in the first round.

Input: ([],)

Expected Output: []

Explanation: An empty tree produces no rounds.

Input: ([1, 2, 3, None, 4],)

Expected Output: [[4, 3], [2], [1]]

Explanation: Nodes 4 and 3 are leaves first, then 2, then 1.

Input: ([1, 2, 3, 4, 5, 6, 7],)

Expected Output: [[4, 5, 6, 7], [2, 3], [1]]

Explanation: All nodes are grouped by their distance from the nearest leaf.

Solution

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

    class Node:
        __slots__ = ('val', 'left', 'right')

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

    nodes = [None if v is None else Node(v) for v in level_order]

    for i, node in enumerate(nodes):
        if node is None:
            continue
        left_i = 2 * i + 1
        right_i = 2 * i + 2
        if left_i < len(nodes):
            node.left = nodes[left_i]
        if right_i < len(nodes):
            node.right = nodes[right_i]

    root = nodes[0]
    if root is None:
        return []

    import sys
    sys.setrecursionlimit(1_000_000)

    result = []

    def dfs(node):
        if node is None:
            return -1
        h_left = dfs(node.left)
        h_right = dfs(node.right)
        h = 1 + max(h_left, h_right)
        if h == len(result):
            result.append([])
        result[h].append(node.val)
        return h

    dfs(root)
    return result

Time complexity: O(n). Space complexity: O(n).

Hints

  1. Instead of physically removing leaves round by round, compute each node's height from the bottom.
  2. All nodes with the same bottom-up height are removed in the same round.
Last updated: May 8, 2026

Loading coding console...

PracHub

Master your tech interviews with 7,500+ real questions from top companies.

Product

  • Questions
  • Learning Tracks
  • Interview Guides
  • Resources
  • Premium
  • For Universities
  • Student Access

Browse

  • By Company
  • By Role
  • By Category
  • Topic Hubs
  • SQL Questions
  • Compare Platforms
  • Discord Community

Support

  • support@prachub.com
  • (916) 541-4762

Legal

  • Privacy Policy
  • Terms of Service
  • About Us

© 2026 PracHub. All rights reserved.

Related Coding Questions

  • Count Trips From Vehicle Logs - LinkedIn (easy)
  • Design O(1) Randomized Multiset - LinkedIn (easy)
  • Process Mutable Matrix Sum Queries - LinkedIn (medium)
  • Design a Randomized Multiset - LinkedIn (medium)
  • Can You Place N Objects? - LinkedIn (medium)