githubEdit

17. Expression Contains Redundant Bracket or Not

βœ… GFG solution to check if an expression contains redundant brackets using stack-based approach for optimal validation. πŸš€

The problem can be found at the following link: πŸ”— Question Linkarrow-up-right

🧩 Problem Description

Given a string of balanced expression s, check if it contains a redundant parenthesis or not. A set of parentheses are redundant if the same sub-expression is surrounded by unnecessary or multiple brackets.

The expression may contain +, -, *, and / operators. The given expression is valid and there are no white spaces present.

πŸ“˜ Examples

Example 1

Input: s = "((a+b))"
Output: true
Explanation: ((a+b)) can be reduced to (a+b).

Example 2

Input: s = "(a+(b)/c)"
Output: true
Explanation: (a+(b)/c) can be reduced to (a+b/c) because b is surrounded by () which is redundant.

Example 3

πŸ”’ Constraints

  • $1 \le |s| \le 10^5$

βœ… My Approach

The optimal approach uses a Stack-Based technique to efficiently detect redundant parentheses by tracking operators between bracket pairs:

Stack-Based Operator Detection

  1. Initialize Stack:

    • Use a stack to store opening brackets and operators.

    • Process each character in the expression sequentially.

  2. Character Processing:

    • For opening brackets ( and operators (+, -, *, /), push them onto the stack.

    • Skip operands (variables/numbers) as they don't affect redundancy.

  3. Closing Bracket Detection:

    • When encountering ), pop elements from stack until ( is found.

    • Track if any operator exists between the bracket pair using a boolean flag.

  4. Redundancy Check:

    • If no operator is found between a parenthesis pair, return true (redundant).

    • If an operator exists, the brackets are necessary, continue checking.

  5. Final Result:

    • If all bracket pairs contain operators, return false (no redundancy).

πŸ“ Time and Auxiliary Space Complexity

  • Expected Time Complexity: O(n), where n is the length of the string. Each character is pushed and popped from the stack at most once, resulting in linear time processing.

  • Expected Auxiliary Space Complexity: O(n), as in the worst case (highly nested expression), the stack may store all opening brackets and operators, which is proportional to the input size.

πŸ§‘β€πŸ’» Code (C++)

chevron-right⚑ View Alternative Approaches with Code and Analysishashtag

πŸ“Š 2️⃣ Operator Count Approach

πŸ’‘ Algorithm Steps:

  1. Push all characters except closing parenthesis to stack.

  2. On encountering closing parenthesis, count operators between parentheses.

  3. If no operator exists between a pair, parentheses are redundant.

  4. Continue checking all parentheses pairs in the expression.

πŸ“ Complexity Analysis:

  • Time: ⏱️ O(n) - Single pass through the string

  • Auxiliary Space: πŸ’Ύ O(n) - Stack space for characters

βœ… Why This Approach?

  • Clear operator detection logic

  • Easy to extend for more operators

  • Intuitive flag-based checking

πŸ“Š 3️⃣ Minimal Element Count

πŸ’‘ Algorithm Steps:

  1. Maintain stack and track elements between each parenthesis pair.

  2. On closing bracket, pop until opening bracket is found.

  3. Check if at least one element exists between the pair.

  4. Empty or single-element pairs indicate redundancy.

πŸ“ Complexity Analysis:

  • Time: ⏱️ O(n) - Linear traversal of string

  • Auxiliary Space: πŸ’Ύ O(n) - Stack storage

βœ… Why This Approach?

  • Counts all elements including operands

  • Works for various expression formats

  • Simple counting mechanism

πŸ“Š 4️⃣ Character Type Tracking

πŸ’‘ Algorithm Steps:

  1. Use stack to store all non-closing parenthesis characters.

  2. When closing parenthesis found, extract substring between brackets.

  3. Analyze extracted content for meaningful operators or operands.

  4. Return true if parentheses wrap nothing useful.

πŸ“ Complexity Analysis:

  • Time: ⏱️ O(n) - Process each character once

  • Auxiliary Space: πŸ’Ύ O(n) - Stack for expression storage

βœ… Why This Approach?

  • Direct operator counting method

  • Efficient single-pass solution

  • Minimal condition checking

πŸ†š πŸ” Comparison of Approaches

πŸš€ Approach

⏱️ Time Complexity

πŸ’Ύ Space Complexity

βœ… Pros

⚠️ Cons

🏷️ Optimized Stack (Main)

🟒 O(n)

🟑 O(n)

πŸš€ Faster runtime (less pushing)

πŸ”§ Still uses stack memory

βš™οΈ Operator Count

🟒 O(n)

🟑 O(n)

πŸ“– Clear operator detection

πŸ”§ Operator list maintenance

πŸ“ Minimal Element

🟒 O(n)

🟑 O(n)

🎯 Generic element checking

🐌 Less specific validation

πŸ” Character Type

🟒 O(n)

🟑 O(n)

⭐ Efficient operator check

πŸ”§ Similar to other approaches

πŸ† Best Choice Recommendation

🎯 Scenario

πŸŽ–οΈ Recommended Approach

πŸ”₯ Performance Rating

πŸ… Optimal performance needed

πŸ₯‡ Optimized Stack

β˜…β˜…β˜…β˜…β˜…

πŸ“– Readability priority

πŸ₯ˆ Operator Count

β˜…β˜…β˜…β˜…β˜†

πŸ”§ Generic expression handling

πŸ₯‰ Minimal Element

β˜…β˜…β˜…β˜…β˜†

🎯 Interview/Competitive

πŸ… Optimized Stack

β˜…β˜…β˜…β˜…β˜…

β˜• Code (Java)

🐍 Code (Python)

🧠 Contribution and Support

For discussions, questions, or doubts related to this solution, feel free to connect on LinkedIn: πŸ“¬ Any Questions?arrow-up-right. Let's make this learning journey more collaborative!

⭐ If you find this helpful, please give this repository a star! ⭐


πŸ“Visitor Count

Visitor counter

Last updated