C3 AI Software Engineer Interview Questions
39+ questions from real C3 AI Software Engineer interviews, reported by candidates.
Round Types
Top Topics
Questions
I recently finished C3 AI Solutions Engineering Loop. The OA was medium/hard LC, failed test cases but still got invited to other rounds. - HM round was easy, asked weakness/strengths type questions +
C3.ai Fulltime SDE Technical Phone Screen Interview Questions
There were two questions in total. (Question practice website: 1146) (Question practice website: 437) fail
#322 Coin Change
LeetCode #322: Coin Change. Difficulty: Medium. Topics: Array, Dynamic Programming, Breadth-First Search. Asked at C3.ai in the last 6 months.
## Problem Design an antivirus scanning system. It should: - Accept a file (represented as a byte string or path). - Check against a signature database (each signature is a known malicious byte pattern). - Classify the file as `CLEAN`, `INFECTED`, or `SUSPICIOUS`. - On `INFECTED`, quarantine the file (move to isolated storage, log the event). - Support adding new signatures at runtime. ```python class AntivirusScanner: def load_signatures(self, signatures: List[bytes]): ... def scan(self, file_path: str) -> ScanResult: ... def quarantine(self, file_path: str, reason: str): ... def add_signature(self, signature: bytes): ... class ScanResult: status: str # "CLEAN" | "INFECTED" | "SUSPICIOUS" matched_signatures: List[bytes] scanned_at: datetime ``` **Example:** ``` scanner.load_signatures([b"\xDE\xAD\xBE\xEF", b"MALWARE_MARKER"]) result = scanner.scan("/tmp/suspicious.exe") # result.status -> "INFECTED" # result.matched_signatures -> [b"MALWARE_MARKER"] ``` ## Follow-ups 1. How would you use Aho-Corasick to scan for multiple signatures in a single O(n) pass? 2. How do you scan compressed/archived files? 3. How would you parallelize scanning across thousands of files? 4. How do you prevent a quarantine bypass where malware deletes itself before isolation?
## Problem Given a grid with multiple people, find the point that minimizes the total travel distance for all to meet. ## Likely LeetCode equivalent LC 296 - Best Meeting Point (>80% confident) ## Tags matrix, math, sorting
## Problem Return the values of nodes visible from the right side of a binary tree, one per level. ## Likely LeetCode equivalent LC 199 - Binary Tree Right Side View (>80% confident) ## Tags binary_tree, bfs, dfs
## Problem Design a browser history data structure supporting visit, back, and forward operations. ## Likely LeetCode equivalent LC 1472 - Design Browser History (>80% confident) ## Tags design, stack, arrays
## Problem Find the longest subarray containing at most two distinct types of fruit, using a sliding window approach. ## Likely LeetCode equivalent LC 904 - Fruit Into Baskets (>80% confident) ## Tags sliding_window, hash_table, arrays
## Problem You are building an equity management tool. Given a list of share issuances and transfers, compute each stakeholder's current share count and ownership percentage. Operations: - `issue(to, shares)` - issue new shares to a stakeholder. - `transfer(from, to, shares)` - transfer shares between stakeholders. - `ownership() -> dict` - return `{stakeholder: (shares, pct)}` for all holders. ```python class CapTable: def issue(self, to: str, shares: int): ... def transfer(self, frm: str, to: str, shares: int): ... def ownership(self) -> dict: ... def total_shares(self) -> int: ... ``` **Example:** ``` cap = CapTable() cap.issue("Alice", 1000) cap.issue("Bob", 500) cap.transfer("Alice", "Carol", 200) cap.ownership() -> { "Alice": (800, 53.33%), "Bob": (500, 33.33%), "Carol": (200, 13.33%) } ``` ## Follow-ups 1. What happens if a transfer exceeds the sender's current holdings - raise or clamp? 2. How would you model vesting schedules (shares unlock monthly over 4 years)? 3. Add a dilution event: a new funding round issues shares and all existing percentages shrink. 4. How would you audit the full history of ownership at any past date?
## Problem You are given a flat list of employees with `{id, name, manager_id}`. Build the org-chart tree and implement: - `depth(employee_id) -> int`: levels below root (root = 0). - `subtree_size(employee_id) -> int`: number of nodes in the subtree rooted at that employee (inclusive). - `lowest_common_manager(id1, id2) -> int`: the deepest manager who is an ancestor of both. - `serialize() -> str`: BFS-order JSON representation of the tree. ```python class OrgChart: def __init__(self, employees: List[dict]): ... def depth(self, employee_id: int) -> int: ... def subtree_size(self, employee_id: int) -> int: ... def lowest_common_manager(self, id1: int, id2: int) -> int: ... ``` **Example:** ``` employees = [ {"id": 1, "manager_id": None}, {"id": 2, "manager_id": 1}, {"id": 3, "manager_id": 1}, {"id": 4, "manager_id": 2} ] depth(4) -> 2 subtree_size(1) -> 4 lowest_common_manager(3, 4) -> 1 ``` ## Follow-ups 1. What is the time complexity of `lowest_common_manager`? Can you get it to O(log n)? 2. How would you rebalance the tree if the org chart is very deep (degenerate chain)? 3. How would you support moving a subtree to a new manager? 4. How does this change if one employee can have multiple managers (matrix org)?
## Problem Given equations like A/B = k, answer queries for the value of other division expressions using graph traversal. ## Likely LeetCode equivalent LC 399 - Evaluate Division (>80% confident) ## Tags graph, bfs, union_find
## Problem Generate all possible combinations of k numbers from 1 to n using backtracking. ## Likely LeetCode equivalent LC 77 - Combinations (>80% confident) ## Tags backtracking, recursion
## Problem Generate all combinations of n pairs of valid parentheses using backtracking. ## Likely LeetCode equivalent LC 22 - Generate Parentheses (>80% confident) ## Tags backtracking, recursion, strings
## Problem You are given an `m x n` grid of integers. Starting at cell `(0, 0)`, reach cell `(m-1, n-1)` in the minimum number of jumps. From cell `(r, c)` with value `v`, you can jump to any cell `(r', c')` where `|r'-r| + |c'-c| <= v` and `grid[r'][c'] != -1` (blocked). Return the minimum number of jumps, or -1 if unreachable. ```python def min_jumps(grid: List[List[int]]) -> int: ... ``` **Example:** ``` grid = [ [2, 3, 1], [1, -1, 1], [1, 1, 0] ] Output: 2 # (0,0)->(0,1)->(2,2): jump 2 from (0,0) to (0,1) [val=3], jump up to (2,2) grid = [[0]] Output: 0 # already at destination ``` ## Approach BFS from `(0,0)`. For each cell at distance `d`, enqueue all reachable neighbors not yet visited. BFS guarantees minimum jumps. ## Follow-ups 1. What is the time complexity? How do you avoid revisiting cells inside the inner loop? 2. How does the problem change if jumping diagonally is also allowed? 3. If you need to find the actual path (not just count), how do you track it? 4. How would you solve this on a weighted grid where each jump has a cost?
## Problem Group an array of strings so that anagrams appear together, using a hash map keyed on sorted characters. ## Likely LeetCode equivalent LC 49 - Group Anagrams (>80% confident) ## Tags hash_table, strings, sorting
## Problem Given a list of daily temperature readings and a window size `k`, return the highest temperature recorded in each consecutive window of `k` days. ```python def highest_temperatures(temps: List[float], k: int) -> List[float]: ... ``` **Example:** ``` Input: temps=[3.1, 1.2, 4.5, 2.7, 6.0, 1.9, 3.3], k=3 Output: [4.5, 4.5, 6.0, 6.0, 6.0] # Windows: [3.1,1.2,4.5]->[4.5], [1.2,4.5,2.7]->[4.5], # [4.5,2.7,6.0]->[6.0], [2.7,6.0,1.9]->[6.0], [6.0,1.9,3.3]->[6.0] ``` ## Approach Use a monotonic deque. Maintain indices of temperatures in decreasing order. For each new element, pop the back of the deque while it holds smaller values. Pop the front if it slides out of the window. The front always holds the current max. Time: O(n). Space: O(k). ## Follow-ups 1. How does the deque approach work - walk through the invariant being maintained. 2. Extend to also return the minimum in each window simultaneously. 3. How would you handle missing readings (NaN) in the temperature series? 4. If readings arrive as a stream, how do you maintain the rolling max in O(1) amortized per element?
## Problem Design an iterator that interleaves elements from multiple input iterators in round-robin or alternating order. ## Likely LeetCode equivalent No direct unambiguous LC equivalent. ## Tags design, queue, iterator
## Problem Implement the following JavaScript utility functions without using the built-in equivalents: **Part 1:** Implement `myReduce(arr, fn, initialValue)` matching the behavior of `Array.prototype.reduce`. **Part 2:** Implement `myPromiseAll(promises)` matching `Promise.all` - resolves when all resolve, rejects on first rejection. **Part 3:** Implement `myFlatten(arr, depth)` matching `Array.prototype.flat(depth)`. ```js // Part 1 myReduce([1,2,3,4], (acc, x) => acc + x, 0) // -> 10 // Part 2 myPromiseAll([Promise.resolve(1), Promise.resolve(2)]).then(vs => console.log(vs)) // -> [1, 2] // Part 3 myFlatten([1,[2,[3,[4]]]],2) // -> [1, 2, 3, [4]] ``` ## Follow-ups 1. How would you implement `myPromiseAllSettled` that never rejects? 2. What happens in your `myReduce` if no `initialValue` is provided? 3. Implement `myPromiseRace` - resolves or rejects with the first settled promise. 4. How would you implement lazy evaluation using generators instead of `reduce`?
C3 AI SWE Onsite - Jump Game
## Problem Determine if you can reach the last index of an array where each element represents the max jump length from that position. ## Likely LeetCode equivalent LC 55 - Jump Game (>80% confident) ## Tags greedy, arrays, dynamic_programming
## Problem Find the number of unique k-diff pairs in an array where a pair (a, b) has an absolute difference equal to k. ## Likely LeetCode equivalent LC 532 - K-diff Pairs in an Array (>80% confident) ## Tags hash_table, two_pointers, arrays
See All 39 C3 AI Software Engineer Questions
Full question text, answer context, and frequency data for subscribers.
Get Access