Open In App

Valid Parentheses in an Expression

Last Updated : 14 Aug, 2025
Comments
Improve
Suggest changes
Like Article
Like
Report

Given a string s containing three types of brackets {}, () and []. We have to determine whether the brackets are balanced.

An expression is balanced if each opening bracket has a corresponding closing bracket of the same type, the pairs are properly ordered and no bracket closes before its matching opening bracket.

  • Balanced:"[()()]{}" → every opening bracket is closed in the correct order.
  • Not balanced:"([{]})" → the ] closes before the matching { is closed, breaking the nesting rule.

Example

Input: s = "[{()}]"
Output: true
Explanation: All the brackets are well-formed.

Input: s = "[()()]{}"
Output: true
Explanation: All the brackets are well-formed.

Input: s = "([]"
Output: false
Explanation: The expression is not balanced as there is a missing ')' at the end.

Input: s = "([{]})"
Output: false
Explanation: The expression is not balanced because there is a closing ']' before the closing '}'.

Approach 1: Using Stack

The idea is to use a stack to track opening brackets. When a closing bracket is encountered, we check if it matches the topmost opening bracket. If all brackets match and the stack is empty at the end, the expression is balanced.

Implementation steps:

  • Declare a character stack (say temp).
  • Now traverse the string s
    • If the current character is an opening bracket ( '(' or '{'  or '[' ) then push it to stack.
    • If the current character is a closing bracket ( ')' or '}' or ']' ) and the closing bracket matches with the opening bracket at the top of stack, then pop the opening bracket. Else s is not balanced.
  • After complete traversal, if some starting brackets are left in the stack then the expression is not balanced, else balanced.

Illustration:


C++
#include <iostream>
#include <stack>
#include <vector>
#include <string>
using namespace std;

bool isBalanced(const string& s) {
    // Stack to store opening brackets
    stack<char> st; 
    for (char c : s) {
        if (c == '(' || c == '{' || c == '[') {
            st.push(c);
        }
        // Process closing brackets
        else if (c == ')' || c == '}' || c == ']') {
            // No opening bracket
            if (st.empty()) return false; 
            char top = st.top();
            if ((c == ')' && top != '(') ||
                (c == '}' && top != '{') ||
                (c == ']' && top != '[')) {
                return false;
            }
            // Pop matching opening bracket
            st.pop(); 
        }
    }
    // Balanced if stack is empty
    return st.empty(); 
}

int main() {
    vector<string> testCases = {"[{()}]", "[()()]{}", "(]", "([{]})"};
    for (const string& s : testCases) {
        cout << "Input: " << s << " -> Output: " << (isBalanced(s) ? "true" : "false") << endl;
    }
    return 0;
}
Java
import java.util.Stack;
import java.util.Vector;

public class GfG {
    public static boolean isBalanced(String s) {
        // Stack to store opening brackets
        Stack<Character> st = new Stack<>();
        for (char c : s.toCharArray()) {
            if (c == '(' || c == '{' || c == '[') {
                st.push(c);
            }
            // Process closing brackets
            else if (c == ')' || c == '}' || c == ']') {
                // No opening bracket
                if (st.isEmpty()) return false; 
                char top = st.peek();
                if ((c == ')' && top != '(') ||
                    (c == '}' && top != '{') ||
                    (c == ']' && top != '[')) {
                    return false;
                }
                // Pop matching opening bracket
                st.pop(); 
            }
        }
        // Balanced if stack is empty
        return st.isEmpty(); 
    }

    public static void main(String[] args) {
        String[] testCases = {"[{()}]", "[()()]{}", "(]", "([{]})"};
        for (String s : testCases) {
            System.out.println("Input: " + s + " -> Output: " + (isBalanced(s) ? "true" : "false"));
        }
    }
}
Python
from collections import deque

def isBalanced(s):
    # Stack to store opening brackets
    st = deque() 
    for c in s:
        if c == '(' or c == '{' or c == '[':
            st.append(c)
        # Process closing brackets
        elif c == ')' or c == '}' or c == ']':
            # No opening bracket
            if not st: return False 
            top = st[-1]
            if (c == ')' and top != '(') or
               (c == '}' and top != '{') or
               (c == ']' and top != '['):
                return False
            # Pop matching opening bracket
            st.pop() 
    # Balanced if stack is empty
    return not st 

def main():
    testCases = ["[{()}]", "[()()]{}", "(]", "([{]})"]
    for s in testCases:
        print(f'Input: {s} -> Output: {str(isBalanced(s)).lower()}')

if __name__ == '__main__':
    main()
C#
using System;
using System.Collections.Generic;

public class GfG {
    public static bool IsBalanced(string s) {
        // Stack to store opening brackets
        Stack<char> st = new Stack<char>();
        foreach (char c in s) {
            if (c == '(' || c == '{' || c == '[') {
                st.Push(c);
            }
            // Process closing brackets
            else if (c == ')' || c == '}' || c == ']') {
                // No opening bracket
                if (st.Count == 0) return false; 
                char top = st.Peek();
                if ((c == ')' && top != '(') ||
                    (c == '}' && top != '{') ||
                    (c == ']' && top != '[')) {
                    return false;
                }
                // Pop matching opening bracket
                st.Pop(); 
            }
        }
        // Balanced if stack is empty
        return st.Count == 0; 
    }

    public static void Main(string[] args) {
        string[] testCases = { "[{()}]", "[()()]{}", "(]", "([{]})" };
        foreach (string s in testCases) {
            Console.WriteLine("Input: " + s + " -> Output: " + (IsBalanced(s) ? "true" : "false"));
        }
    }
}
JavaScript
function isBalanced(s) {
    // Stack to store opening brackets
    let st = [];
    for (let c of s) {
        if (c === '(' || c === '{' || c === '[') {
            st.push(c);
        }
        // Process closing brackets
        else if (c === ')' || c === '}' || c === ']') {
            // No opening bracket
            if (st.length === 0) return false;
            let top = st[st.length - 1];
            if ((c === ')' && top !== '(') ||
                (c === '}' && top !== '{') ||
                (c === ']' && top !== '[')) {
                return false;
            }
            // Pop matching opening bracket
            st.pop();
        }
    }
    // Balanced if stack is empty
    return st.length === 0;
}

function main() {
    let testCases = ["[{()}]", "[()()]{}", "(]", "([{]})"];
    for (let s of testCases) {
        console.log(`Input: ${s} -> Output: ${String(isBalanced(s)).toLowerCase()}`);
    }
}

main();

Output
Input: [{()}] -> Output: true
Input: [()()]{} -> Output: true
Input: (] -> Output: false
Input: ([{]}) -> Output: false

Time Complexity: O(N)
Space Complexity: O(N)

Approach 2: Without using Stack

Simulate a stack using the input string itself by modifying it in-place, using a top variable to track the position of the last unmatched opening bracket. This approach is suitable for languages like C++ where strings (or character arrays) are mutable.

Note : Strings are immutable in Java, Python, C#, and JavaScript. Therefore, we cannot modify them in place, making this approach unsuitable for these languages.

Implementation steps:

  • Start with top = -1 to mark the simulated stack as empty.
  • Traverse each character in the string, pushing opening brackets by incrementing top and storing them at s[top].
  • For closing brackets, return false if top == -1 (no match), or if s[top] does not match the corresponding opening bracket; otherwise, decrement top to pop.
  • After the loop, the string is balanced if top == -1; otherwise, it is unbalanced.
C++
#include <iostream>
#include <vector>
#include <string>
using namespace std;

bool isBalanced(string& s) {
    // stack top index in string
    int top = -1;
    for (int i = 0; i < s.length(); i++) {
        if (s[i] == '(' || s[i] == '{' || s[i] == '[') {
            // push opening bracket
            s[++top] = s[i]; 
        } 
        else if (s[i] == ')' || s[i] == '}' || s[i] == ']') {
            // no opening bracket
            if (top == -1) return false; 
            if ((s[i] == ')' && s[top] != '(') ||
                (s[i] == '}' && s[top] != '{') ||
                (s[i] == ']' && s[top] != '[')) {
                return false;
            }
            top--;
        }
    }
    // balanced if stack empty
    return top == -1; 
}

int main() {
    vector<string> testCases = {"[{()}]", "[()()]{}", "(]", "([{]})"};
    for (auto& s : testCases) { // pass each string by reference
        cout << "Input: " << s << " -> Output: "
             << (isBalanced(s) ? "true" : "false") << endl;
    }
    return 0;
}

Output
Input: [{()}] -> Output: true
Input: [()()]{} -> Output: true
Input: (] -> Output: false
Input: ([{]}) -> Output: false

Time Complexity: O(N)
Space Complexity: O(1)


Balanced Parenthesis
Visit Course explore course icon

Similar Reads