Mock Interview Flashcards

To ask in Interview

1
Q

You are given the head of a singly linked-list. The list can be represented as:

L0 → L1 → … → Ln - 1 → Ln
Reorder the list to be on the following form:

L0 → Ln → L1 → Ln - 1 → L2 → Ln - 2 → …
You may not modify the values in the list’s nodes. Only nodes themselves may be changed.

Example 1:

Input: head = [1,2,3,4]
Output: [1,4,2,3]
Example 2:

Input: head = [1,2,3,4,5]
Output: [1,5,2,4,3]

Constraints:

The number of nodes in the list is in the range [1, 5 * 104].
1 <= Node.val <= 1000

https://leetcode.com/problems/reorder-list/description/

A

class ListNode:

# Definition for singly-linked list.
# class ListNode(object):
#     def \_\_init\_\_(self, val=0, next=None):
#         self.val = val
#         self.next = next
class Solution(object):
    def reorderList(self, head):
        """
        :type head: ListNode
        :rtype: None Do not return anything, modify head in-place instead.
        """
        # One Pass Recursion
        def rec(head, runner):
            if not runner.next:
                return head
            nx_head = rec(head, runner.next)
            # Runner will be none when any of the next two cases are met.
            # nx_head.next will be none if nodes are odd numbered
            # runner will be equal to nx_head when nodes are equal numbered. 
            # The logic works as follows
            # 1,2,3,4
            # 1 -> 4 -> 2 (runner = 3, nx_head = 1) (Set runner.next = None, ie. 3->None)
            # 1 -> 4 -> 2 -> 3 -> None (runner = 2, nx_head = 2 << runner = nx_head, runner.next = None)
            # Odd, 1,2,3
            # 1 -> 3 -> 2 (runner = 2, nx_head = 2) (set runner.next = None)
            # 1 -> 3 -> 2 -> None (runner = 1, nx_head = 2, << nx_head.next == None )
            if not nx_head or not nx_head.next or nx_head == runner:
                return None
            # Save these 2 temp variables
            nxt_node = runner.next
            nx_nx_head = nx_head.next
            
            nx_head.next = nxt_node
            runner.next = None # we do not need it anymore, this is to have a clean ending list, otherwise cycles
            nx_head.next.next = nx_nx_head
            return nx_nx_head
        rec(head, head)

Interleave using splitting list in middle
~~~
class Solution:
def reorderList(self, head: Optional[ListNode]) -> None:
“””
Do not return anything, modify head in-place instead.
“””
# Other way, reach center, reverse the list, interleave join them

    # reach center
    fast, slow = head, head
    while fast and fast.next:
        slow = slow.next
        fast = fast.next.next
    # Slow is at the center now

    #Reverse from slow onwards
    prev = None
    cur = slow
    while cur:
        cur.next, cur, prev = prev, cur.next, cur
    # prev is the head of the reversed list now interleave join them
    second = prev
    first = head
    while second.next:
        first.next, second.next, first, second = second, first.next, first.next, second.next ~~~

O(n), space O(1)

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
2
Q
  1. Insert into a Sorted Circular Linked List
    Medium
    Companies: Facebook 2024

Given a Circular Linked List node, which is sorted in non-descending order, write a function to insert a value insertVal into the list such that it remains a sorted circular list. The given node can be a reference to any single node in the list and may not necessarily be the smallest value in the circular list.

If there are multiple suitable places for insertion, you may choose any place to insert the new value. After the insertion, the circular list should remain sorted.

If the list is empty (i.e., the given node is null), you should create a new single circular list and return the reference to that single node. Otherwise, you should return the originally given node.

Example 1:

Input: head = [3,4,1], insertVal = 2
Output: [3,4,1,2]
Explanation: In the figure above, there is a sorted circular list of three elements. You are given a reference to the node with value 3, and we need to insert 2 into the list. The new node should be inserted between node 1 and node 3. After the insertion, the list should look like this, and we should still return node 3.

Example 2:

Input: head = [], insertVal = 1
Output: [1]
Explanation: The list is empty (given head is null). We create a new single circular list and return the reference to that single node.

Example 3:

Input: head = [1], insertVal = 0
Output: [1,0]

Constraints:

The number of nodes in the list is in the range [0, 5 * 104].
-106 <= Node.val, insertVal <= 106

10-15 mins

https://leetcode.com/problems/insert-into-a-sorted-circular-linked-list/description/

A

Definition for a Node.

We handle the following cases:
1. The insertVal lies between 2 nodes
2. We reach the inflection point (eg. reaching 3 in 312) and the insertVal is either greater/eq than current (true tail) or smaller/eq than the next (true head)
If we do not hit either of these cases before we have reached starting point, then the list has all same elements, in which case we can insert anywhere.

"""
class Node:
    def \_\_init\_\_(self, val=None, next=None):
        self.val = val
        self.next = next
"""

class Solution:
    def insert(self, head: 'Optional[Node]', insertVal: int) -> 'Node':
        if not head:
            ret = Node(insertVal)
            ret.next = ret
            return ret
        cur = head
        insertNode = Node(insertVal)
        while cur.next!=head:
            if cur.val <= insertVal <= cur.next.val:
                break
            if cur.val > cur.next.val and (insertVal <= cur.next.val or insertVal >= cur.val):
                break
            cur = cur.next
        cur.next, insertNode.next = insertNode, cur.next
        return head

O(n), O(1) space

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
3
Q
  1. Diameter of Binary Tree
    Solved
    Easy
    Topics
    Companies Facebook
    Given the root of a binary tree, return the length of the diameter of the tree.

The diameter of a binary tree is the length of the longest path between any two nodes in a tree. This path may or may not pass through the root.

The length of a path between two nodes is represented by the number of edges between them.

Example 1:

Input: root = [1,2,3,4,5]
Output: 3
Explanation: 3 is the length of the path [4,2,1,3] or [5,2,1,3].
Example 2:

Input: root = [1,2]
Output: 1

Constraints:

The number of nodes in the tree is in the range [1, 104].
-100 <= Node.val <= 100

https://leetcode.com/problems/diameter-of-binary-tree/description/

A

class TreeNode:

Definition for a binary tree node.
#     def \_\_init\_\_(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution:
    def diameterOfBinaryTree(self, root: Optional[TreeNode]) -> int:        
        def diameterRec(node):
            if not node:
                return 0,0
            if not node.left and not node.right:
                return 1,0
            left_depth, ldiameter = diameterRec(node.left)
            right_depth, rdiameter = diameterRec(node.right)
            
            cur_diameter = left_depth + right_depth
            maxDepth = max(left_depth, right_depth) + 1
            maxDiameter = max(cur_diameter, ldiameter, rdiameter)
            return maxDepth, maxDiameter
        _, maxDiameter = diameterRec(root)
        return maxDiameter

O(n), O(1) Space

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
4
Q
  1. Binary Tree Right Side View
    Solved
    Medium
    Topics
    Companies Facebook
    Given the root of a binary tree, imagine yourself standing on the right side of it, return the values of the nodes you can see ordered from top to bottom.

Example 1:

Input: root = [1,2,3,null,5,null,4]
Output: [1,3,4]
Example 2:

Input: root = [1,null,3]
Output: [1,3]
Example 3:

Input: root = []
Output: []

Constraints:

The number of nodes in the tree is in the range [0, 100].
-100 <= Node.val <= 100

https://leetcode.com/problems/binary-tree-right-side-view/description/

A

Definition for a binary tree node.

from collections import deque
# Definition for a binary tree node.
# class TreeNode(object):
#     def \_\_init\_\_(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution(object):
    def rightSideView(self, root):
        """
        :type root: TreeNode
        :rtype: List[int]
        """
        if not root:
            return []
        q = deque()
        ret = []
        q.append(root)
        while q:
            ret.append(q[0].val)
            for i in range(len(q)):
                node = q.popleft()
                if node.right:
                    q.append(node.right)
                if node.left:
                    q.append(node.left)
        return ret

O(n), O(n)

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
5
Q
  1. Find K Closest Elements
    Solved
    Medium

Topics

Companies
Given a sorted integer array arr, two integers k and x, return the k closest integers to x in the array. The result should also be sorted in ascending order.

An integer a is closer to x than an integer b if:

|a - x| < |b - x|, or
|a - x| == |b - x| and a < b

Example 1:

Input: arr = [1,2,3,4,5], k = 4, x = 3

Output: [1,2,3,4]

Example 2:

Input: arr = [1,1,2,3,4,5], k = 4, x = -1

Output: [1,1,2,3]

Constraints:

1 <= k <= arr.length
1 <= arr.length <= 104
arr is sorted in ascending order.
-104 <= arr[i], x <= 104

https://leetcode.com/problems/find-k-closest-elements/

A
import bisect
class Solution:
    def findClosestElements(self, arr: List[int], k: int, x: int) -> List[int]:
        if k == len(arr):
            return arr
        if x <= arr[0]:
            return arr[:k]
        elif x >= arr[-1]:
            return arr[-k:]
        insert_idx = bisect.bisect_left(arr, x)
        l = insert_idx - 1
        r = insert_idx
        while r-l-1 < k:
            if l < 0:
                r+=1
                continue
            if r == len(arr) or abs(x-arr[l]) <= abs(x-arr[r]):
                l-=1
            else:
                r+=1             
        return arr[l+1:r]

O(log(n) + k), O(1)

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
6
Q
  1. Find Leaves of Binary Tree
    Medium

Given the root of a binary tree, collect a tree’s nodes as if you were doing this:

Collect all the leaf nodes.
Remove all the leaf nodes.
Repeat until the tree is empty.

Example 1:

Input: root = [1,2,3,4,5]
Output: [[4,5,3],[2],[1]]
Explanation:
[[3,5,4],[2],[1]] and [[3,4,5],[2],[1]] are also considered correct answers since per each level it does not matter the order on which elements are returned.
Example 2:

Input: root = [1]
Output: [[1]]

Constraints:

The number of nodes in the tree is in the range [1, 100].
-100 <= Node.val <= 100

https://leetcode.com/problems/find-leaves-of-binary-tree/

A
from collections import defaultdict
# 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 findLeaves(self, root: Optional[TreeNode]) -> List[List[int]]:
        leaf = defaultdict(list)
        
        def rec(node):
            nonlocal leaf
            if not node:
                return -1
            val_l = rec(node.left)
            val_r = rec(node.right)
            valthis = max(val_l, val_r) + 1
            leaf[valthis].append(node.val)
            return valthis
        rec(root)
        return leaf.values()

O(n) time O(n) space

How well did you know this?
1
Not at all
2
3
4
5
Perfectly