18. Level Order in spiral form

The problem can be found at the following link: ๐Ÿ”— Question Link

๐Ÿงฉ Problem Description

Given a binary tree, return its spiral (zigzag) level-order traversal. In spiral order traversal:

  • At even-indexed levels (0-based), traverse nodes from right to left.

  • At odd-indexed levels, traverse nodes from left to right.

Return a list containing all node values in spiral order.

๐Ÿ“˜ Examples

Example 1:

Input:

root = [1, 3, 2]

Output:

[1, 3, 2]

Explanation:

Level 0 (even) โ†’ right to left: 1 Level 1 (odd) โ†’ left to right: 3 2

Example 2:

Input:

root = [10, 20, 30, 40, 60]

Output:

[10, 20, 30, 60, 40]

Example 3:

Input:

root = [1, 2, N, 4]

Output:

[1, 2, 4]

๐Ÿ”’ Constraints

  • 1 โ‰ค number of nodes โ‰ค 10โต

  • 0 โ‰ค node->data โ‰ค 10โต

โœ… My Approach

Using Double-Ended Queue (Deque)

We use a deque to simulate two-directional traversal:

  • For even-indexed levels, we traverse from right to left using pop_back() and push children to the front.

  • For odd-indexed levels, we traverse from left to right using pop_front() and push children to the back.

We alternate the direction at each level using a boolean flag.

Algorithm Steps:

  1. Initialize deque q and push root node.

  2. While q is not empty:

    • Traverse the current level based on direction:

      • If flag is True (even), pop from back and push rightโ†’left children to front.

      • If flag is False (odd), pop from front and push leftโ†’right children to back.

    • Flip the flag at the end of each level.

๐Ÿงฎ Time and Auxiliary Space Complexity

  • Expected Time Complexity: O(n), as we visit each node exactly once in level order.

  • Expected Auxiliary Space Complexity: O(n), due to storing up to an entire level of nodes in the deque.

๐Ÿง  Code (C++)

class Solution {
  public:
    vector<int> findSpiral(Node* r) {
        if (!r) return {};
        vector<int> a;
        deque<Node*> q{r};
        bool f = 1;
        while (!q.empty()) {
            int n = q.size();
            while (n--) {
                Node* x = f ? q.back() : q.front();
                f ? q.pop_back() : q.pop_front();
                a.push_back(x->data);
                if (f) {
                    if (x->right) q.push_front(x->right);
                    if (x->left) q.push_front(x->left);
                } else {
                    if (x->left) q.push_back(x->left);
                    if (x->right) q.push_back(x->right);
                }
            }
            f = !f;
        }
        return a;
    }
};
โšก Alternative Approaches

๐Ÿ“Š 2๏ธโƒฃ Two-Stacks Method

Algorithm Steps:

  1. If root is null, return {}.

  2. Initialize two stacks: s1 (for current level), s2 (for next level).

  3. Push root to s1.

  4. While either s1 or s2 is non-empty:

    • Process s1 (rightโ†’left):

      1. While s1 isnโ€™t empty:

        • Pop u from s1, append u->data.

        • Push u->right then u->left onto s2.

    • Process s2 (leftโ†’right):

      1. While s2 isnโ€™t empty:

        • Pop u from s2, append u->data.

        • Push u->left then u->right onto s1.

  5. Return the combined result.

class Solution {
  public:
    vector<int> findSpiral(Node* root) {
        if (!root) return {};
        vector<int> ans;
        stack<Node*> s1, s2;
        s1.push(root);
        while (!s1.empty() || !s2.empty()) {
            while (!s1.empty()) {
                Node* u = s1.top(); s1.pop();
                ans.push_back(u->data);
                if (u->right) s2.push(u->right);
                if (u->left)  s2.push(u->left);
            }
            while (!s2.empty()) {
                Node* u = s2.top(); s2.pop();
                ans.push_back(u->data);
                if (u->left)  s1.push(u->left);
                if (u->right) s1.push(u->right);
            }
        }
        return ans;
    }
};

โœ… Why This Approach?

  • Clear separation of two traversal directions via two stacks.

  • No deque operationsโ€”pure LIFO.

๐Ÿ“ Complexity Analysis:

  • Time: ๐Ÿ”ธ O(N)

  • Auxiliary Space: ๐Ÿ”ธ O(N)

๐Ÿ“Š 3๏ธโƒฃ Level-Collection + Reverse

Algorithm Steps:

  1. Perform a standard level-order traversal using a queue, but collect each level into its own vector.

  2. After collecting all levels in levels[], iterate through levels:

    • If level index is even โ†’ reverse that level.

    • Append elements in order to final answer.

class Solution {
  public:
    vector<int> findSpiral(Node* root) {
        if (!root) return {};
        vector<vector<int>> levels;
        queue<Node*> q;
        q.push(root);
        while (!q.empty()) {
            int sz = q.size();
            vector<int> lvl;
            for (int i = 0; i < sz; ++i) {
                Node* u = q.front(); q.pop();
                lvl.push_back(u->data);
                if (u->left)  q.push(u->left);
                if (u->right) q.push(u->right);
            }
            levels.push_back(lvl);
        }
        vector<int> ans;
        for (int i = 0; i < levels.size(); ++i) {
            if (i % 2 == 0)
                reverse(levels[i].begin(), levels[i].end());
            ans.insert(ans.end(), levels[i].begin(), levels[i].end());
        }
        return ans;
    }
};

โœ… Why This Approach?

  • Simple to reason about by separating concerns.

  • Useful if you need per-level data later.

๐Ÿ“ Complexity Analysis:

  • Time: ๐Ÿ”ธ O(N)

  • Auxiliary Space: ๐Ÿ”ธ O(N) (for both queue and levels)

๐Ÿ†š Comparison

Approach

โฑ๏ธ Time

๐Ÿ—‚๏ธ Space

โœ… Pros

โš ๏ธ Cons

Deque Zigzag Traversal

๐ŸŸข O(n)

๐ŸŸข O(n)

Clean, single container

Requires deque logic

Two Stack Zigzag

๐ŸŸข O(n)

๐ŸŸข O(n)

Stack-based alternative

Slightly verbose

Level-Collect + Reverse

๐Ÿ”ธ O(N)

๐Ÿ”ธ O(N)

Simple to implement

Needs extra storage for all levels

โœ… Best Choice by Scenario

Scenario

Recommended Approach

๐Ÿš€ Performance & minimal passes

๐Ÿฅ‡ Deque-Based Traversal (Optimal)

๐ŸŽ“ Clarity in interview demos

๐Ÿฅˆ Two-Stacks

๐Ÿ“Š Need per-level data retained

๐Ÿฅ‰ Level-Collect + Reverse

๐Ÿง‘โ€๐Ÿ’ป Code (Java)

class Solution {
    public ArrayList<Integer> findSpiral(Node r) {
        if (r == null) return new ArrayList<>();
        ArrayList<Integer> a = new ArrayList<>();
        Deque<Node> q = new ArrayDeque<>();
        q.add(r);
        boolean f = true;
        while (!q.isEmpty()) {
            int n = q.size();
            while (n-- > 0) {
                Node x = f ? q.pollLast() : q.pollFirst();
                a.add(x.data);
                if (f) {
                    if (x.right != null) q.addFirst(x.right);
                    if (x.left != null) q.addFirst(x.left);
                } else {
                    if (x.left != null) q.addLast(x.left);
                    if (x.right != null) q.addLast(x.right);
                }
            }
            f = !f;
        }
        return a;
    }
}

๐Ÿ Code (Python)

class Solution:
    def findSpiral(self, r):
        if not r: return []
        a, q, f = [], deque([r]), True
        while q:
            for _ in range(len(q)):
                x = q.pop() if f else q.popleft()
                a.append(x.data)
                if f:
                    if x.right: q.appendleft(x.right)
                    if x.left: q.appendleft(x.left)
                else:
                    if x.left: q.append(x.left)
                    if x.right: q.append(x.right)
            f = not f
        return a

๐Ÿง  Contribution and Support

For discussions, questions, or doubts related to this solution, feel free to connect on LinkedIn: ๐Ÿ“ฌ Any Questions?. Letโ€™s make this learning journey more collaborative!

โญ If you find this helpful, please give this repository a star! โญ


๐Ÿ“Visitor Count

Last updated