Valid Parentheses in JavaScript: Two Solutions Explained (LeetCode Problem #20)

Valid Parentheses in JavaScript: Two Solutions Explained (LeetCode Problem #20)

The Valid Parentheses problem is a classic stack exercise on LeetCode. The task is straightforward: given a string containing only the characters (, ), {, }, [, and ], determine whether the input string is valid.

A string is valid when:

  • Every opening bracket is closed by the same type of bracket
  • Opening brackets are closed in the correct order
  • Every closing bracket has a corresponding opening bracket of the same type

For example, "()" and "()[]{}" are valid. "(]" and "([)]" are not.

The Approach: Stack

The right data structure here is a stack. The logic is simple: iterate through each character in the string. When you encounter an opening bracket, push it onto the stack. When you encounter a closing bracket, pop the last item off the stack and check whether it matches. If it doesn’t match, the string is invalid. If you reach the end and the stack is empty, every opening bracket was correctly closed and the string is valid.

Solution 1: Map-Based (Compact)

This version stores the bracket pairs in an object, which keeps the matching logic clean and easy to extend if needed.

var isValid = function(s) {
    const parentheses = {
        '(': ')',
        '[': ']',
        '{': '}'
    };

    let stack = [];

    for (let item of s) {
        if (parentheses[item]) {
            // Opening bracket — push onto stack
            stack.push(item);
        } else {
            // Closing bracket — pop last opening bracket and check match
            let last = stack.pop();
            if (item !== parentheses[last]) {
                return false;
            }
        }
    }

    // If stack is empty, all brackets were matched correctly
    return stack.length === 0;
};

When the loop encounters an opening bracket like (, parentheses[item] returns the expected closing bracket, which is truthy — so it gets pushed to the stack. When it encounters a closing bracket like ), parentheses[item] returns undefined, which is falsy — so we go to the else branch and check the match.

Solution 2: Explicit Checks (More Readable)

This version trades compactness for clarity. Each closing bracket is checked explicitly, and the edge case of an empty stack is handled separately before the pop. It also handles strings shorter than two characters upfront, since a single character can never be valid.

var isValid = function(s) {
    // A string with fewer than 2 characters cannot be valid
    if (!s || s.length < 2) {
        return false;
    }

    let stack = [];

    for (let c of s) {
        if (c === '(' || c === '[' || c === '{') {
            // Opening bracket — push onto stack
            stack.push(c);
        } else {
            // If stack is empty, there is no opening bracket to match
            if (!stack.length) {
                return false;
            }

            let last = stack.pop();

            // Check each closing bracket against its expected opening bracket
            if (c === ')' && last !== '(') return false;
            if (c === ']' && last !== '[') return false;
            if (c === '}' && last !== '{') return false;
        }
    }

    // Empty stack means all brackets were matched
    return !stack.length;
};

Key Difference Between the Two Solutions

Solution 1 uses an object to define bracket pairs, which makes the matching logic a single line regardless of how many bracket types exist. Solution 2 checks each pair explicitly, which is more verbose but easier to follow when reading the code for the first time. Both have the same time complexity of O(n) and space complexity of O(n).

One practical difference: Solution 2 returns false immediately for strings with fewer than two characters, since a valid string always needs at least one opening and one closing bracket. Solution 1 handles this implicitly — a single character will either be pushed onto the stack without a match, or trigger a pop on an empty stack returning undefined, which fails the match check.

JavaScript, LeetCode, Valid Parentheses, LeetCode problem 20, stack data structure, JavaScript algorithm, bracket matching, coding practice JavaScript, WordPress developer skills,


Related Posts