[Leetcode]Valid Parentheses

Icarus<Wing>ยท2025๋…„ 4์›” 13์ผ
post-thumbnail

https://leetcode.com/problems/valid-parentheses/description/

๐Ÿ“œ๋ฌธ์ œ ํ•ด์„

'(', ')', '{', '}', '[' ,']'์˜ ๋ฌธ์ž๊ฐ€ ํฌํ•จ๋œ ๋ฌธ์ž์—ด s๊ฐ€ ์ฃผ์–ด์กŒ์„ ๋•Œ, ์ž…๋ ฅ ๋ฌธ์ž์—ด์ด ์œ ํšจํ•œ์ง€ ๊ฒ€์‚ฌํ•˜๋ผ.

๋ฌธ์ž์—ด์ด ์œ ํšจํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š”:
1. ์—ด๋ฆฐ ๊ด„ํ˜ธ๋“ค์€ ๊ฐ™์€ ํƒ€์ž…์˜ ๊ด„ํ˜ธ๋“ค๋กœ ๋‹ซํ˜€์•ผ ํ•œ๋‹ค.
2. ์—ด๋ฆฐ ๊ด„ํ˜ธ๋“ค์€ ์˜ฌ๋ฐ”๋ฅธ ์ˆœ์„œ๋กœ ๋‹ซํ˜€์•ผ ํ•œ๋‹ค.
3. ๋ชจ๋“  ๋‹ซํžŒ ๊ด„ํ˜ธ๋Š” ์ผ์น˜ํ•˜๋Š” ์—ด๋ฆฐ ๊ด„ํ˜ธ ํƒ€์ž…์ด ์žˆ๋‹ค.

๐Ÿšง์ œ์•ฝ ์กฐ๊ฑด
1 <= s.length <= 10^4
=> ์‹œ๊ฐ„๋ณต์žก๋„ O(N^2)์„ ๋„˜์ง€ ๋ง๋ผ๋Š” ์˜๋ฏธ
2. ๋ฌธ์ž์—ด s๋Š” ์˜ค์ง '()[]{}'๋กœ ๊ตฌ์„ฑ๋˜์–ด ์žˆ๋‹ค.

โš™๏ธ์ฝ”๋“œ ์„ค๊ณ„

๋ฌธ์ž์—ด s๋ฅผ for๋ฌธ์œผ๋กœ ์ˆœํšŒํ•˜๋Š”๋ฐ:
if ์—ด๋ฆฐ ๊ด„ํ˜ธ: stack.push()
else ๋‹ซํžŒ ๊ด„ํ˜ธ: stack.peek()๋กœ top ์›์†Œ๋ฅผ ํ™•์ธํ•œ ํ›„, ๋งค์นญ๋˜๋Š” ์—ด๋ฆฐ ๊ด„ํ˜ธ๊ฐ€ ์žˆ์œผ๋ฉด stack.pop()

์šฐ์„  ๋‚ด๊ฐ€ ๊ธฐ์กด์— ์ƒ๊ฐํ•œ ์•Œ๊ณ ๋ฆฌ์ฆ˜์€ ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค:
1. ๊ด„ํ˜ธ์— ์ƒ๊ด€์—†์ด ๋ฌด์กฐ๊ฑด ์Šคํƒ์— ์ถ”๊ฐ€
2. (์Šคํƒ์˜ ์Œ์„ ๋งž์ถ”๊ธฐ ์œ„ํ•ด)์Šคํƒ์˜ ํฌ๊ธฐ๊ฐ€ 2 ์ด์ƒ์ด๋ฉด:
ํ˜„์žฌ์˜ ๋ฌธ์ž๊ฐ€ ๋‹ซํžŒ ๊ด„ํ˜ธ๊ณ  ์Šคํƒ์˜ top - 1 ์›์†Œ๊ฐ€ ๋งค์นญ๋˜๋Š” ์—ด๋ฆฐ ๊ด„ํ˜ธ๋ฉด
3. ์Šคํƒ์„ 2๋ฒˆ ์‚ญ์ œ
4. ์Šคํƒ์ด ๋น„์–ด์žˆ์œผ๋ฉด true๋ฅผ, ๊ทธ๋ ‡์ง€ ์•Š์œผ๋ฉด false๋ฅผ ๋ฆฌํ„ด

๐Ÿ’ป์ฝ”๋“œ ๊ตฌํ˜„

public class ValidSolution {
    public boolean isValid(String s) {
        List<Character> stack = new ArrayList<>();
        for (int i = 0; i < s.length(); i++) {
            char c = s.charAt(i);
            stack.add(c); // ๋‹ซํžŒ ๊ด„ํ˜ธ๋งŒ ์ฃผ์–ด์ง„ ๊ฒฝ์šฐ๋„ ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ๋ฌด์กฐ๊ฑด ๋„ฃ์–ด์ค˜์•ผ๋จ

            // ๋นˆ stack์„ pop()ํ•˜์ง€ ์•Š๊ธฐ ์œ„ํ•ด if ์กฐ๊ฑด ๊ฑธ์–ด๋‘ 
            // stack.get(stack.lastIndexOf(c) - 1): stack(top - 1)์˜ ์›์†Œ๋ฅผ ๊ฐ€์ ธ์˜ด
            if (stack.size() > 1) {
                if (c == ')' && stack.get(stack.lastIndexOf(c) - 1) == '(') {
                    stack.removeLast();
                    stack.removeLast();
                } else if (c == '}' && stack.get(stack.lastIndexOf(c) - 1) == '{') {
                    stack.removeLast();
                    stack.removeLast();
                } else if (c == ']' && stack.get(stack.lastIndexOf(c) - 1) == '[') {
                    stack.removeLast();
                    stack.removeLast();
                }
            }

        }
        return stack.isEmpty() ? true : false;
    }
}

๐Ÿšฉ๊ด„ํ˜ธ๋ฅผ ๊ฒ€์‚ฌํ•˜๋Š” ๋ถ€๋ถ„์ด ํ•˜๋“œ์ฝ”๋”ฉ๋˜์–ด ์žˆ์–ด์„œ ๋งŒ์•ฝ์— ๊ด„ํ˜ธ ์ข…๋ฅ˜๊ฐ€ ๋” ๋งŽ์œผ๋ฉด ์ ํ•ฉํ•œ ํ’€์ด๋Š” ์•„๋‹˜!
๐Ÿคฆโ€โ™‚๏ธsubmit์—๋Š” ์„ฑ๊ณตํ–ˆ๋Š”๋ฐ, ๋ฆฌ์ŠคํŠธ๋ฅผ stack์ฒ˜๋Ÿผ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ์–ด์„œ ์ง๊ด€์ ์ธ ํ’€์ด๋Š” ์•„๋‹ˆ๋‹ค. ์™œ ์ด๋Ÿฐ ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ–ˆ์„๊นŒ?
๐Ÿ‘‰ํŒŒ์ด์ฌ์—์„œ stack = []์™€ ๊ฐ™์ด ๋ฆฌ์ŠคํŠธ๋กœ ์‚ฌ์šฉํ•˜๋ผ๊ณ  ํ•ด์„œ, ์ž๋ฐ”๋„ ๋˜‘๊ฐ™์ด ArrayList๋กœ ์‚ฌ์šฉํ–ˆ๊ธฐ ๋•Œ๋ฌธ.

๊ทธ๋Ÿฌ๋‚˜, ์ž๋ฐ”์—๋Š” Stack์ด๋ผ๋Š” ์ปฌ๋ ‰์…˜ ํ”„๋ ˆ์ž„์›Œํฌ๊ฐ€ ์กด์žฌํ•œ๋‹ค.
๐Ÿ‘‡๋‹ค์‹œ ํ•œ๋ฒˆ ์•„๋ž˜์˜ ๊ตฌ์กฐ๋„๋ฅผ ์Œ๋ฏธํ•ด๋ณด์ž.


๋”ฐ๋ผ์„œ, ์ž๋ฐ”์˜ Stack ์ž๋ฃŒ๊ตฌ์กฐ์˜ ๋ฉ”์„œ๋“œ๊ฐ€ ๋ฌด์—‡์ด ์žˆ๋Š”์ง€ ํŒŒ์•…ํ•œ ํ›„, ์ˆ˜์ •๋œ ์ฝ”๋“œ ์„ค๊ณ„๋ฅผ ๋”ฐ๋ผ์„œ ์ฝ”๋“œ ๊ตฌํ˜„์„ ๋‹ค์‹œ ํ•ด๋ณด์ž.

์ž๋ฐ”์˜ stack ์„ ์–ธ ๋ฐ ๋ฉ”์„œ๋“œ

์„ ์–ธ์€ Stack<T> stackName = new Stack<>();ํ˜•ํƒœ๋กœ ์„ ์–ธํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ, ๋ฐ์ดํ„ฐ ํƒ€์ž…์€ ํด๋ž˜์Šค ๋˜๋Š” ๋ž˜ํผ ํด๋ž˜์Šค๋กœ ๋“ค์–ด๊ฐ€์•ผ ํ•œ๋‹ค.

  • push(T t): ๋ฐ์ดํ„ฐ๋ฅผ ์Šคํƒ์— ์ถ”๊ฐ€ํ•˜๊ณ , ํ•ด๋‹น ์ธ์ž๋ฅผ ๋ฐ˜ํ™˜ํ•œ๋‹ค.
  • add(): ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ ๋ฐ์ดํ„ฐ๋ฅผ ์Šคํƒ์— ์ถ”๊ฐ€ํ•˜์ง€๋งŒ, ๋ฆฌ์ŠคํŠธ ์ธํ„ฐํŽ˜์ด์Šค์— ์žˆ๋Š” ๋ฉ”์„œ๋“œ๋ฅผ ์˜ค๋ฒ„๋ผ์ด๋”ฉ ํ•ด์„œ boolean ๊ฐ’์„ ๋ฆฌํ„ดํ•œ๋‹ค.
  • peek(): ์Šคํƒ์˜ ๋งˆ์ง€๋ง‰ ์š”์†Œ, ์ฆ‰ top์˜ ์›์†Œ๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋ฉฐ, ์Šคํƒ์—๋Š” ๋ณ€ํ™”๋ฅผ ์ฃผ์ง€ ์•Š๋Š”๋‹ค.
    • ๋งŒ์•ฝ, ์Šคํƒ์ด ๋น„์—ˆ์„ ๊ฒฝ์šฐ, peek() ํ˜ธ์ถœ ์‹œ NoSuchElementException ์˜ˆ์™ธ๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค.
  • pop(): ์Šคํƒ์˜ ๋งˆ์ง€๋ง‰ ์š”์†Œ๋ฅผ ์ œ๊ฑฐํ•จ๊ณผ ๋™์‹œ์— ํ•ด๋‹น ๊ฐ’์„ ๋ฐ˜ํ™˜
  • empty(): ์Šคํƒ์ด ๋น„์–ด์žˆ๋Š”์ง€์˜ ์—ฌ๋ถ€๋ฅผ boolean์œผ๋กœ ๋ฐ˜ํ™˜
  • search(): ๋ฉ”์„œ๋“œ์˜ ์ธ์ž๋ฅผ ์Šคํƒ์—์„œ ๊ฒ€์ƒ‰ํ•˜์—ฌ ํ•ด๋‹น ์œ„์น˜๋ฅผ ๋ฐ˜ํ™˜
    • ์ด๋•Œ, ์Šคํƒ์— ๊ฐ€์žฅ top์— ์žˆ๋Š” item(or element)๋Š” 1์„ ๋ฆฌํ„ดํ•œ๋‹ค. ์ฆ‰, top์—์„œ ๋ฉ€์–ด์งˆ์ˆ˜๋ก 1์”ฉ ์ฆ๊ฐ€

๋‹ค์‹œ ๋ฌธ์ œ๋กœ ๋Œ์•„์™€์„œ, ์šฐ๋ฆฌ๊ฐ€ ์‚ฌ์šฉํ•ด์•ผํ•  ๋ฉ”์„œ๋“œ๋Š” ๊ด„ํ˜ธ๋ฅผ ๋„ฃ๊ธฐ ์œ„ํ•œ push(), top์˜ ์›์†Œ๋ฅผ ํ™•์ธํ•˜๊ธฐ ์œ„ํ•œ peek(), ๊ด„ํ˜ธ๊ฐ€ ๋งค์นญ๋˜๋ฉด ๊บผ๋‚ด์•ผํ•˜๋Š” pop(), ๊ทธ๋ฆฌ๊ณ  ๋‹ซํžŒ ๊ด„ํ˜ธ๋Š” ๋ฐ˜๋“œ์‹œ ๊ฐ™์€ ํƒ€์ž…์˜ ์—ด๋ฆฐ ๊ด„ํ˜ธ๊ฐ€ ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ์Šคํƒ์ด ๋น„์—ˆ๋Š”์ง€ ํ™•์ธํ•˜๊ธฐ ์œ„ํ•œ empty()๋กœ ์ด 4๊ฐ€์ง€๋งŒ ์‚ฌ์šฉํ•˜๋ฉด ๋œ๋‹ค.

โš™๏ธ์ˆ˜์ •๋œ ์ฝ”๋“œ ์„ค๊ณ„

  1. for๋ฌธ ์•ˆ์—์„œ ๋ฌธ์ž์—ด s๋ฅผ str.charAt(idx)๋ฅผ ์‚ฌ์šฉํ•ด์„œ ๋ฌธ์ž c๋กœ ๋ณ€ํ™˜ํ•œ๋‹ค.
  2. if ์—ด๋ฆฐ ๊ด„ํ˜ธ: stack.push()
    ๐Ÿ‘‰๋งŒ์•ฝ์— ๋‹ซํžŒ ๊ด„ํ˜ธ๋งŒ ์ฃผ์–ด์ง€๋ฉด, ์œ„์˜ if๋ฌธ์„ ๊ฑฐ์น˜์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์— ๋ฐ”๋กœ false๋ฅผ ๋ฆฌํ„ด
  3. else ๋‹ซํžŒ ๊ด„ํ˜ธ: stack.peek()๋กœ top ์›์†Œ๋ฅผ ํ™•์ธํ•œ ํ›„, ๋งค์นญ๋˜๋Š” ์—ด๋ฆฐ ๊ด„ํ˜ธ๊ฐ€ ์žˆ์œผ๋ฉด stack.pop()
    ๐Ÿ‘‰๋งค์นญ๋˜๋Š” ๊ด„ํ˜ธ๊ฐ€ ์—†์œผ๋ฉด ๊ฐ€์ฐจ์—†์ด false๋ฅผ ๋ฆฌํ„ด
  4. for๋ฌธ์ด ๋๋‚˜๋ฉด return stack.isEmpty()๋กœ boolean๊ฐ’ ๋ฆฌํ„ด

๐Ÿ’ป์ˆ˜์ •๋œ ์ฝ”๋“œ ๊ตฌํ˜„

public class ValidSolution {
    public boolean isValid(String s) {
        Stack<Character> stack = new Stack<>();

        for (int i = 0; i < s.length(); i++) {
            char c = s.charAt(i);

            if (c == '(' || c == '{' || c == '[') {
                stack.push(c);
            } else if (stack.isEmpty()) {
                return false; // ์—ด๋ฆฐ ๊ด„ํ˜ธ๊ฐ€ ์Šคํƒ์— ์—†์œผ๋ฉด false
            } else if ((c == ')' && stack.peek() == '(') || (c == '}' && stack.peek() == '{') || (c == ']' && stack.peek() == '[')) {
                stack.pop();
            } else {
                return false;
            }
        }
        return stack.isEmpty();

    }

}

๐Ÿ“š์ฐธ๊ณ ์ž๋ฃŒ
๐Ÿ”—์ž๋ฐ” stack ๋ฉ”์„œ๋“œ ์ข…๋ฅ˜: https://ittrue.tistory.com/200

profile
๋ชจ๋“  ์ฝ”๋“œ์—๋Š” ์ด์œ ๊ฐ€ ์žˆ๊ธฐ์— ์›์ธ์„ ํŒŒ์•…ํ•  ๋•Œ๊นŒ์ง€ ์ง‘์š”ํ•˜๊ฒŒ ํƒ๊ตฌํ•˜๋Š” ๊ฒƒ์„ ์ข‹์•„ํ•ฉ๋‹ˆ๋‹ค.

0๊ฐœ์˜ ๋Œ“๊ธ€