Longest Valid Parentheses in TypeScript

function longestValidParentheses(s: string): number {
    // Initialize maxLen to track the length of the longest valid parentheses substring.
    let maxLen = 0;

    // Initialize a stack and start with -1 in it. The -1 serves a crucial role as a reference point. 
    // It represents a position before the beginning of the string. This helps in calculating the length
    // of valid substrings that start from the beginning of the string.
    const stack: number[] = [-1];

    // Iterate through each character of the string to process the parentheses.
    for (let i = 0; i < s.length; i++) {
        if (s[i] === '(') {
            // When encountering '(', push its index onto the stack. This index could potentially be the start
            // of a valid parentheses substring.
            stack.push(i);
        } else {
            // For a closing parenthesis ')', pop the top of the stack. This pop operation either:
            // 1. Removes the index of a matching '(', forming a valid pair, or
            // 2. Removes -1 if there's no matching '(' (i.e., the substring so far is invalid).
            stack.pop();

            if (stack.length === 0) {
                // If the stack is empty after popping, the current ')' doesn't have a matching '('.
                // Push the current index onto the stack. This index now acts as a new reference point for future valid substrings.
                stack.push(i);
            } else {
                // If the stack is not empty, calculate the length of the current valid substring. 
                // The length is the current index (i) minus the top element of the stack. The top element 
                // is the index right before the start of the current valid substring or -1 if the current valid substring 
                // starts from the beginning of the string. Update maxLen if the newly calculated length is greater.
                maxLen = Math.max(maxLen, i - stack[stack.length - 1]);
            }
        }
    }

    // Return the maximum length of valid parentheses found.
    return maxLen;
}
function longestValidParentheses(s: string): number {
    // Initialize maxLen to keep track of the maximum length of valid parentheses found.
    let maxLen = 0;

    // Initialize a dp (dynamic programming) array filled with 0s. Each element dp[i] will represent
    // the length of the longest valid parentheses substring ending at index i in the string.
    let dp: number[] = new Array(s.length).fill(0);

    // Iterate through the string, starting from index 1 because a valid substring cannot start at the first character.
    for (let i = 1; i < s.length; i++) {
        // Check if the current character is a closing parenthesis.
        if (s[i] === ')') {
            // Scenario 1: Simple pair formation
            // If the character before the current one is '(', it forms a valid pair "()".
            if (s[i - 1] === '(') {
                // Add 2 for the pair formed, and also add the length of the valid substring (if any) 
                // that ends right before this pair.
                dp[i] = (i >= 2 ? dp[i - 2] : 0) + 2;
            } 
            // Scenario 2: Complex pair formation with a valid substring before current ')'
            // Check if the character before the current ')' is also ')' and forms a valid substring.
            else if (i - dp[i - 1] > 0 && s[i - dp[i - 1] - 1] === '(') {
                // The length of the current valid substring is the length of the valid substring ending at i-1,
                // plus the length of the valid substring (if any) that ends just before the matching '(' for the current ')',
                // plus 2 for the pair just formed.
                dp[i] = dp[i - 1] + ((i - dp[i - 1]) >= 2 ? dp[i - dp[i - 1] - 2] : 0) + 2;
            }
            // Update maxLen with the maximum of its current value and dp[i].
            maxLen = Math.max(maxLen, dp[i]);
        }
    }

    // Return the maximum length of the longest valid parentheses substring found.
    return maxLen;
}

PrevNext