Untitled

 avatar
unknown
plain_text
a month ago
6.0 kB
1
Indexable
To calculate the vertical order traversal of a binary tree with specific rules (sorting by row first and then by value in the case of ties), we can use a combination of a breadth-first search (BFS) traversal and a structured way to store and sort the nodes.

---

### **Approach**

1. **Track Node Positions:**
   - For each node, calculate its row and column.
   - Start with the root node at position (0, 0). For each node at position (row, col):
     - Its left child is at (row + 1, col - 1).
     - Its right child is at (row + 1, col + 1).

2. **Group Nodes by Columns:**
   - Use a `TreeMap<Integer, List<int[]>>` to group nodes by their column indices. The key is the column index, and the value is a list of pairs representing the (row, node value) of nodes in that column.

3. **Perform BFS:**
   - Use a queue to perform level-order traversal while tracking the row and column of each node. For each node:
     - Add its (row, value) pair to the list for its column in the `TreeMap`.
     - Enqueue its left and right children with updated row and column indices.

4. **Sort Nodes:**
   - For each column, sort the list of nodes first by row, then by value (for nodes in the same row).

5. **Prepare the Result:**
   - Extract the sorted node values from each column and add them to the result list.

---

### **Algorithm**

#### BFS and TreeMap
- **TreeMap:** Automatically sorts columns in ascending order.
- **Sorting Nodes:** Sort based on row first, and by value in case of ties.

---

### **Java Implementation**

```java
import java.util.*;

class TreeNode {
    int val;
    TreeNode left, right;

    TreeNode(int val) {
        this.val = val;
        this.left = this.right = null;
    }
}

public class VerticalOrderTraversal {
    public List<List<Integer>> verticalTraversal(TreeNode root) {
        if (root == null) return new ArrayList<>();

        // TreeMap to group nodes by column index
        TreeMap<Integer, List<int[]>> columnMap = new TreeMap<>();
        // Queue for BFS traversal, storing (node, row, col)
        Queue<Tuple> queue = new LinkedList<>();
        queue.offer(new Tuple(root, 0, 0));

        while (!queue.isEmpty()) {
            Tuple current = queue.poll();
            TreeNode node = current.node;
            int row = current.row;
            int col = current.col;

            // Add the node's (row, value) pair to the column list
            columnMap.putIfAbsent(col, new ArrayList<>());
            columnMap.get(col).add(new int[]{row, node.val});

            // Add left and right children to the queue with updated positions
            if (node.left != null) {
                queue.offer(new Tuple(node.left, row + 1, col - 1));
            }
            if (node.right != null) {
                queue.offer(new Tuple(node.right, row + 1, col + 1));
            }
        }

        // Prepare the result
        List<List<Integer>> result = new ArrayList<>();
        for (List<int[]> nodes : columnMap.values()) {
            // Sort nodes in the column by row first, then by value
            Collections.sort(nodes, (a, b) -> {
                if (a[0] != b[0]) return a[0] - b[0]; // Compare rows
                return a[1] - b[1]; // Compare values
            });

            // Extract sorted values
            List<Integer> sortedColumn = new ArrayList<>();
            for (int[] node : nodes) {
                sortedColumn.add(node[1]);
            }
            result.add(sortedColumn);
        }

        return result;
    }

    // Helper class for BFS
    static class Tuple {
        TreeNode node;
        int row, col;

        public Tuple(TreeNode node, int row, int col) {
            this.node = node;
            this.row = row;
            this.col = col;
        }
    }

    public static void main(String[] args) {
        // Example 1
        TreeNode root1 = new TreeNode(3);
        root1.left = new TreeNode(9);
        root1.right = new TreeNode(20);
        root1.right.left = new TreeNode(15);
        root1.right.right = new TreeNode(7);

        VerticalOrderTraversal vt = new VerticalOrderTraversal();
        System.out.println(vt.verticalTraversal(root1)); // Output: [[9], [3, 15], [20], [7]]

        // Example 2
        TreeNode root2 = new TreeNode(1);
        root2.left = new TreeNode(2);
        root2.right = new TreeNode(3);
        root2.left.left = new TreeNode(4);
        root2.left.right = new TreeNode(5);
        root2.right.left = new TreeNode(6);
        root2.right.right = new TreeNode(7);
        System.out.println(vt.verticalTraversal(root2)); // Output: [[4], [2], [1, 5, 6], [3], [7]]
    }
}
```

---

### **Explanation of the Example**

#### Input Tree:
```
    3
   / \
  9   20
      / \
     15  7
```

#### Step-by-Step Traversal:
1. Start with the root `3` at (row = 0, col = 0). Add it to column 0.
2. Visit `9` (row = 1, col = -1). Add it to column -1.
3. Visit `20` (row = 1, col = 1). Add it to column 1.
4. Visit `15` (row = 2, col = 0). Add it to column 0.
5. Visit `7` (row = 2, col = 2). Add it to column 2.

#### Columns:
- Column -1: \[(1, 9)\]
- Column 0: \[(0, 3), (2, 15)\]
- Column 1: \[(1, 20)\]
- Column 2: \[(2, 7)\]

#### Sort and Flatten:
- Column -1: [9]
- Column 0: [3, 15]
- Column 1: [20]
- Column 2: [7]

#### Output:
\[
[[9], [3, 15], [20], [7]]
\]

---

### **Complexity Analysis**
1. **Time Complexity:**
   - BFS traversal: \( O(n) \), where \( n \) is the number of nodes.
   - Sorting nodes in each column: \( O(k \log(k)) \), where \( k \) is the number of nodes in a column. In the worst case, \( k = n \).
   - Overall: \( O(n + n \log(n)) = O(n \log(n)) \).

2. **Space Complexity:**
   - Space for `TreeMap`: \( O(n) \), where \( n \) is the number of nodes.
   - Space for queue: \( O(n) \) in the worst case.
   - Overall: \( O(n) \).
Leave a Comment