8.9 Validate Properly Nested Brackets
8.9.1 Metadata
- Platform: HackerRank
- Problem ID: validate-properly-nested-brackets
- Difficulty: Easy
- URL: HackerRank - Validate Properly Nested Brackets
- Tags: Stack
- Techniques: 1.3.17">Stack
8.9.2 Description
Given a string, check if all brackets (‘()’, ‘{}’, ‘[]’) are properly matched and nested. Return 1 if valid, otherwise return 0.
Example 1:
Input:
code_snippet = "if (a[0] > b[1]) { doSomething(); }"
Output:
1
Explanation: All brackets are properly matched: ‘(’ with ‘)’, ‘[’ with ’]’, and ‘{’ with ‘}’. No mismatches or improper nesting.
Example 2:
Input:
code_snippet = "int x = 42; // no brackets here"
Output:
1
Example 3:
Input:
code_snippet = "() {} []"
Output:
1
Constraints:
- \(0 \le\) code_snippet.length \(\le 1000\)
- code_snippet consists of printable ASCII characters (character codes 32 to 126 inclusive)
- code_snippet may contain any combination of ‘(’, ‘)’, ‘{’, ‘}’, ‘[’, ’]’, letters, digits, symbols, and whitespace
- code_snippet may be empty
8.9.3 Walkthrough
This is a classic bracket matching problem that uses a stack to track opening brackets and validate proper nesting.
Key Insight: For valid bracket sequences: 1. Every closing bracket must have a corresponding opening bracket before it 2. The most recent unmatched opening bracket must match the current closing bracket 3. All opening brackets must eventually be closed
Strategy: - Use a stack to store opening brackets as we encounter them - When we see a closing bracket, check if it matches the top of the stack - If the stack is empty when we see a closing bracket, or if brackets don’t match, return false - After processing all characters, the stack should be empty (all brackets matched)
Example trace for "if (a[0] > b[1]) { doSomething(); }":
- Skip characters until
(→ Push(onto stack:['('] - Skip until
[→ Push[onto stack:['(', '['] - Hit
]→ Check top[matches → Pop → Stack:['('] - Hit
)→ Check top(matches → Pop → Stack:[] - Skip until
{→ Push{onto stack:['{'] - Skip until
}→ Check top{matches → Pop → Stack:[] - End of string, stack is empty → Valid!
8.9.4 Analysis
Time Complexity: \(O(n)\) where n is the length of the code snippet. We iterate through each character exactly once.
Space Complexity: \(O(n)\) in the worst case when all characters are opening brackets (e.g., "(((((("). The stack can grow up to the size of the input string.
8.9.5 Implementation Steps
Handle edge case: Return true for empty strings (no brackets to validate)
Initialize data structures:
- Create a stack to store opening brackets
- Create a map to pair opening brackets with their corresponding closing brackets
Iterate through each character:
- If it’s an opening bracket (
(,{,[), push it onto the stack - If it’s a closing bracket:
- Check if stack is empty → return false (no matching opening bracket)
- Check if top of stack matches this closing bracket → if not, return false
- Pop the matching opening bracket from the stack
- Otherwise, skip non-bracket characters
- If it’s an opening bracket (
Final validation: After processing all characters, check if stack is empty
- Empty stack → all brackets matched → return true
- Non-empty stack → unmatched opening brackets remain → return false
8.9.6 Java Code
class Result {
/*
* Complete the 'areBracketsProperlyMatched' function below.
*
* The function is expected to return a BOOLEAN.
* The function accepts STRING code_snippet as parameter.
*/
private static Map<Character, Character> bracketMap = new HashMap<>();
public static boolean areBracketsProperlyMatched(String code_snippet) {
if(code_snippet.isEmpty()) {
return true;
}
// Write your code here
Stack<Character> openParenStack = new Stack<>();
bracketMap.put('{', '}');
bracketMap.put('(', ')');
bracketMap.put('[', ']');
for(char c : code_snippet.toCharArray()) {
//System.out.println(c);
if(isOpenParenthesis(c)) {
openParenStack.add(c);
} else if(isCloseParenthesis(c)) {
if(openParenStack.isEmpty()) {
return false;
}
char expected = bracketMap.get(openParenStack.peek());
//System.out.println("expected " + expected + " vs actual " + c );
if(expected != c) {
return false;
}
//pop the top open parentheiss
openParenStack.pop();
} else {
//skip
}
}
// if there are still open parenthesis left in the stack
if(!openParenStack.isEmpty()) {
return false;
}
return true;
}
private static boolean isOpenParenthesis(char c) {
return bracketMap.keySet().contains(c);
}
private static boolean isCloseParenthesis(char c) {
return bracketMap.values().contains(c);
}
}