mediumGeeksforGeeksNot Started

Postfix to Infix

A curated StudyFlow practice problem with comprehensive editorial and multi-language solutions.

Solve on GeeksforGeeks
Lesson

Problem Statement

You are given a string exp that represents a Postfix expression. Convert it into an Infix expression.

Infix expression: An expression where operators are placed between operands (e.g. ((A+B)*C)). Postfix expression: An expression where operators follow operands (e.g. AB+C*).

Example 1 · Standard Postfix:

Input: exp = "ab*c+"
Output: "((a*b)+c)"
Explanation: ab* becomes (a*b). Adding c+ produces ((a*b)+c).

Example 2 · Multi-Operator Expression:

Input: exp = "ab+c+de+*"
Output: "(((a+b)+c)*(d+e))"
Explanation: Converted following standard binary operations into parenthesized infix.

Constraints:

  • 1 <= exp.length <= 104
  • exp contains lowercase and uppercase alphabets and operators (+, -, *, /, ^).

What You'll Learn

Key principles and algorithmic techniques you will master from this problem:

  • Understand bottom-up tree reconstruction from postfix notation using an operand stack.
  • Correctly order popped operands: first popped is right operand b, second popped is left operand a.
  • Produce fully parenthesized expressions to preserve exact operator precedence.

Pattern Recognition Trigger

How to instantly recognize this algorithmic pattern when encountering unseen interview questions:

Algorithmic Decision Tree:

  • Traverse postfix string left to right.
  • If operand (alphanumeric), push string directly to stack.
  • If operator (op), pop b then a, format "(" + a + op + b + ")", and push result.
  • Return top of stack at end.

Connected Patterns:

Infix to PostfixPrefix to InfixEvaluate Reverse Polish Notation

1. Dynamic Array Substring Replacement

Intuition

Maintain an explicit dynamic array of token strings. Whenever an operator is seen, collapse the preceding 2 elements into a parenthesized string.

Algorithm

  1. Step 1: Loop through each character c in exp.
  2. Step 2: If c is alphanumeric, append c to list.
  3. Step 3: If c is operator, remove last two items b and a, format (a + c + b), and append to list.
  4. Step 4: Return the only remaining item in list.
C++ SOLUTIONCLEAN & OPTIMIZED
1#include <iostream>
2#include <string>
3#include <vector>
4
5class Solution {
6public:
7 std::string postToInfix(std::string exp) {
8 std::vector<std::string> list;
9 for (char c : exp) {
10 if (isalnum(c)) {
11 list.push_back(std::string(1, c));
12 } else {
13 std::string b = list.back(); list.pop_back();
14 std::string a = list.back(); list.pop_back();
15 list.push_back("(" + a + c + b + ")");
16 }
17 }
18 return list.front();
19 }
20};
21
22int main() {
23 Solution solver;
24 std::cout << "Infix: " << solver.postToInfix("ab*c+") << std::endl;
25 return 0;
26}

Time & Space Complexity

  • Time complexity: O(N^2) — Repeated string concatenation and array allocations scale quadratically with expression length.
  • Space complexity: O(N) — O(N) space for intermediate strings.

Why Brute Force Doesn't Scale:

Splice operations on large token lists become quadratic.

Stack approach converts 10,000 characters in <3ms.


2. Deque String Accumulation

Intuition

Use an explicit Deque stack container for storing building blocks.

Algorithm

  1. Step 1: Initialize Deque st.
  2. Step 2: Traverse string left to right.
  3. Step 3: If alphanumeric, push string.
  4. Step 4: If operator, pop b and a, push "(" + a + op + b + ")".
  5. Step 5: Return st.peek().
C++ SOLUTIONCLEAN & OPTIMIZED
1#include <iostream>
2#include <string>
3#include <deque>
4
5class Solution {
6public:
7 std::string postToInfix(std::string exp) {
8 std::deque<std::string> st;
9 for (char c : exp) {
10 if (isalnum(c)) {
11 st.push_back(std::string(1, c));
12 } else {
13 std::string b = st.back(); st.pop_back();
14 std::string a = st.back(); st.pop_back();
15 st.push_back("(" + a + c + b + ")");
16 }
17 }
18 return st.back();
19 }
20};
21
22int main() {
23 Solution solver;
24 std::cout << "Infix: " << solver.postToInfix("ab*c+") << std::endl;
25 return 0;
26}

Time & Space Complexity

  • Time complexity: O(N) — Single pass utilizing a double-ended queue / stack container for O(1) removals.
  • Space complexity: O(N) — O(N) space to hold string tokens.

3. Optimal Stack Expression Reconstruction

Intuition

A single LIFO stack of strings reconstructs the AST expression bottom-up. Enclosing each binary combination in parentheses preserves operator precedence completely.

Algorithm

  1. Step 1: Initialize an empty stack st of strings.
  2. Step 2: Loop through each character c in exp.
  3. Step 3: If c is alphanumeric, push string(c) onto st.
  4. Step 4: If c is an operator, pop b = st.top(), pop a = st.top(), construct "(" + a + c + b + ")" and push back to st.
  5. Step 5: Return st.top().

Optimal Postfix to Infix Stack Trace

2 of 2 questions left today
Step 1 / 5
Trace timeline20% explored
Current operationSTEP 1 OF 5
Stack: ['a']
Visual state
Values and pointers at this exact step
stack
TOP
'a'
Push adds to the top · Pop removes from the top
Why this step matters

Stack: [a]

Step 1 / 5
C++ SOLUTIONCLEAN & OPTIMIZED
1#include <iostream>
2#include <string>
3#include <stack>
4
5class Solution {
6public:
7 std::string postToInfix(std::string exp) {
8 std::stack<std::string> st;
9 for (char c : exp) {
10 if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c >= '0' && c <= '9')) {
11 st.push(std::string(1, c));
12 } else {
13 std::string t2 = st.top(); st.pop();
14 std::string t1 = st.top(); st.pop();
15 std::string sub = "(" + t1 + c + t2 + ")";
16 st.push(sub);
17 }
18 }
19 return st.top();
20 }
21};
22
23int main() {
24 Solution solver;
25 std::cout << "Infix: " << solver.postToInfix("ab*c+") << std::endl;
26 return 0;
27}

Time & Space Complexity

  • Time complexity: O(N) — Single O(N) scan through postfix string with O(1) stack operations.
  • Space complexity: O(N) — O(N) space for operand stack.

Approach Comparison Matrix

Side-by-side comparison of time, space, and algorithmic trade-offs across each approach:

ApproachTimeSpaceCore IdeaTrade-off / Bottleneck
1.Dynamic Array Substring ReplacementO(N^2)O(N)Dynamic array with repeated splice operations.String copying during removals.
2.Deque String AccumulationO(N)O(N)Use double-ended queue for string token buffering.None.
3.Optimal Stack Expression ReconstructionOptimalO(N)O(N)Standard LIFO string stack building parenthesized expressions bottom-up.None (Optimal).

Common Pitfalls & Crucial Edge Cases

Pitfall 1:

Swapping operands: producing (b op a) instead of (a op b).

Pitfall 2:

Omitting parentheses around subexpressions, leading to incorrect precedence in infix.

Pitfall 3:

Iterating from right to left (Postfix is evaluated left to right).

Crucial Edge Cases to Validate:

  • Single operand `exp = 'A'` — Returns 'A' without parentheses.
  • Deeply nested expression — Parentheses nest cleanly to preserve associativity.
  • Repeated operators `exp = 'ab+cd+*'` — Returns '((a+b)*(c+d))'.

Interview Tips & Best Practices

How to communicate your thought process and address follow-ups in a live technical interview:

  1. State the rule clearly: 'Operands push directly to string stack; operators pop 2 strings, enclose with operator, and push back'.
  2. Highlight operand popping order: first popped is right, second is left.
  3. Explain that parentheses are necessary in infix to maintain the explicit postfix precedence.

Quick Comprehension Check

Test your intuitive understanding of the core concept in 30 seconds:

1.Why do we place parentheses around every binary operation '(a op b)' during postfix to infix conversion?

2.Which operand is popped first when an operator is encountered in Postfix?