简体   繁体   中英

Can someone explain what is wrong with my approach?

I was trying to attempt this problem. https://leetcode.com/problems/valid-parentheses/ . However, I was confused if in the second for loop I can compare s.charAt(i) and stack.pop().

Basically, my approach was such. Push the entire string to a stack, and then run through the first half of the stack using stack.charAt(i) and compare it to the second half using stack.pop(). I just wanted to know what might be going wrong in my code as I get a false value when expecting a true value. I am just trying to understand if my concept is flawed or not?

class Solution {
    public boolean isValid(String s) {
        Stack<Character> stack = new Stack<>();
        
        boolean done = false;
        
        if(s.length() < 2)
            return true;
        
        for(int i = 0; i < s.length(); i++){
            stack.push(s.charAt(i));
        }
        
        for(int i = 0; i < s.length()/2; i++){
            if(s.charAt(i) == stack.pop())
                done = true;
        }
        
        return done;   
    }
}

While your code might work for strings such as " {([])} " and " (()) ", you are assuming that the strings will be symmetrical. A valid input such as " {()[]} " will not pass in your code because it is not symmetrical. Modify your code to account for asymmetry. Hint: maybe pop 2 elements when the character is a closing character such as ")" "}" and "]".

You are supposed to check if the parentheses in a string match: that for a '(' there is a matching ')' . However, note that the character '(' is not equal to the character ')' .

Your code is checking if the string matches a pattern where the second half of the string is the first half of the string in reverse, like {[))[{ . In other words, you're checking if the input is a palindrome .

The approach you should take is storing only the starting brackets in the stack:

    for(int i = 0; i < s.length(); i++){
        if s.charAt(i) is an open bracket:
            stack.push(s.charAt(i));
        else:
            "pop" a character from stack
            if it's '(' make sure that s.charAt(i) is ')'
            if it's '[' make sure that s.charAt(i) is ']'
            if it's '{' make sure that s.charAt(i) is '}'
    }

Your code first iterates up to the middle of the string and populates the stack, and then from the middle to the end and pops the stack. In other words, you're implicitly assuming that the first half of a valid string is opening parentheses of various types, and the second is their corresponding closing parentheses (eg ([]) or {[()]} ). However, these aren't the only valid strings - there is no limitation that states that a closing parenthesis can't be followed by an opening one, as long as the pairs are matched - eg, (()()) is a valid string.

Instead of making assumptions on the position within the string, you should iterate over the string, and for each character, if it's an opening parenthesis push it to the stack, and if it's a closing parenthesis pop the stack and compare the two:

private static final Map<Character, Character> PARENS = new HashMap<>();
static {
    PARENS.put('(', ')');
    PARENS.put('[', ']');
    PARENS.put('{', '}');
}
public static boolean isValid(String s) {
    Stack<Character> stack = new Stack<>();

    for (int i = 0; i < s.length(); ++i) {
        char ch = s.charAt(i);
        if (PARENS.containsKey(ch)) {
            stack.push(ch);
        } else {
            if (stack.isEmpty()) {
                return false;
            }
            char match = stack.pop();
            if (ch != PARENS.get(match)) {
                return false;
            }
        }
    }

    return stack.isEmpty();
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM