Coding Test/Data Structure & algorithm

[์ž๋ฃŒ๊ตฌ์กฐ] ์Šคํƒ(Stack)

๊ต ๋ฏผ 2024. 9. 6. 18:23

๐Ÿ“Œ์Šคํƒ : ํ›„์ž…์„ ์ถœ(Last In First Out, LIFO) ๋ฐฉ์‹์„ ๋”ฐ๋ฅด๋Š” ์ž๋ฃŒ๊ตฌ์กฐ๋กœ, ๊ฐ€์žฅ ๋‚˜์ค‘์— ์‚ฝ์ž…๋œ ๋ฐ์ดํ„ฐ๊ฐ€ ๊ฐ€์žฅ ๋จผ์ € ๊บผ๋‚ด์ง€๋Š” ๊ตฌ์กฐ๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ๋‹ค.

 

์Šคํƒ ๊ตฌํ˜„

 

  1. Deque<E>๋ฅผ ์Šคํƒ์ฒ˜๋Ÿผ ์‚ฌ์šฉ
    Deque<Integer> stack = new ArrayDeque<>();
  2. Stack<E> ์‚ฌ์šฉ
    Stack<Integer> stack = new Stack<>();

 

๊ธฐ๋ณธ ๋ฉ”์„œ๋“œ
  • push(E item) : ์Šคํƒ์˜ ๋งจ ์œ„์— ์š”์†Œ๋ฅผ ์ถ”๊ฐ€
  • pop() : ์Šคํƒ์˜ ๋งจ ์œ„์— ์žˆ๋Š” ์š”์†Œ๋ฅผ ์ œ๊ฑฐํ•˜๊ณ  ๋ฐ˜ํ™˜
  • peek() : ์Šคํƒ์˜ ๋งจ ์œ„์— ์žˆ๋Š” ์š”์†Œ๋ฅผ ์ œ๊ฑฐํ•˜์ง€ ์•Š๊ณ  ๋ฐ˜ํ™˜
  • isEmpty() : ์Šคํƒ์ด ๋น„์–ด ์žˆ๋Š”์ง€ ์—ฌ๋ถ€๋ฅผ ํ™•์ธ
  • size() : ์Šคํƒ ์•ˆ์˜ ์š”์†Œ ๊ฐœ์ˆ˜ ๋ฐ˜ํ™˜

 

์ฝ”๋”ฉ ํ…Œ์ŠคํŠธ ๋นˆ์ถœ ์œ ํ˜•

 

๊ด„ํ˜ธ ์œ ํšจ์„ฑ ๊ฒ€์‚ฌ

: "๋‹ค์–‘ํ•œ ์œ ํ˜•์˜ ๊ด„ํ˜ธ (), {}, [] ๊ฐ€ ํฌํ•จ๋œ ๋ฌธ์ž์—ด์—์„œ ์˜ฌ๋ฐ”๋ฅด๊ฒŒ ๊ด„ํ˜ธ๊ฐ€ ์ง์ง€์–ด์ ธ ์žˆ๋Š”๊ฐ€? "

  • ํ’€์ด๋ฒ• ) ์—ฌ๋Š” ๊ด„ํ˜ธ๋Š” ์Šคํƒ์— ์Œ“๊ณ  ๋‹ซ๋Š” ๊ด„ํ˜ธ๊ฐ€ ๋‚˜์˜ฌ ๋•Œ๋งˆ๋‹ค ์Šคํƒ์—์„œ ์ง์ด ๋งž๋Š” ์—ฌ๋Š” ๊ด„ํ˜ธ๋ฅผ ๊บผ๋‚ธ๋‹ค.

๐Ÿ“„ ์œ ํ˜• ์ดํ•ด ์ฝ”๋“œ ๐Ÿ“„

public boolean isValid(String s) {
	//ArrayDeque<>์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ํ†ตํ•ด ์Šคํƒ ๊ตฌํ˜„
    Deque<Character> stack = new ArrayDeque<>();
    for (char c : s.toCharArray()) {
    	// ์—ฌ๋Š” ๊ด„ํ˜ธ -> ์Šคํƒ์— ์Œ“๊ธฐ
        if (c == '(' || c == '{' || c == '[') {
            stack.push(c);
        } 
        else {
        	//์Šคํƒ์ด ๋น„์–ด์žˆ์„ ๊ฒฝ์šฐ false๊ฐ’ ๋ฐ˜ํ™˜
            if (stack.isEmpty()) return false;
            //์Šคํƒ์˜ ๋งจ ์œ„์— ์žˆ๋Š” ์š”์†Œ ์ œ๊ฑฐ ํ›„, open๊ฐ’์— ๋ฐ˜ํ™˜
            char open = stack.pop();
            //isMatching๋ฉ”์„œ๋“œ ์ด์šฉํ•˜์—ฌ ๋‹ค๋ฅธ ๊ฒฝ์šฐ false๊ฐ’ ๋ฐ˜ํ™˜
            if (!isMatching(open, c)) return false;
        }
    }
    //isEmpty๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์Šคํƒ์ด ๋น„์–ด์žˆ๋Š”์ง€ ์—ฌ๋ถ€ ํ™•์ธ
    return stack.isEmpty();
}

//isMatching ๋ฉ”์„œ๋“œ ์ •์˜: open๊ฐ’๊ณผ close๊ฐ’์ด ์ง์„ ์ด๋ฃจ๋ฉด true, ๊ทธ๋ ‡์ง€ ์•Š์œผ๋ฉด false๊ฐ’ ๋ฐ˜ํ™˜
private boolean isMatching(char open, char close) {
    return (open == '(' && close == ')') || (open == '{' && close == '}') || (open == '[' && close == ']');
}

 

 

2. ์ตœ์†Ÿ๊ฐ’ ์Šคํƒ ๊ตฌํ˜„

  • ๊ธฐ๋ณธ ์Šคํƒ ์™ธ์— ์ตœ์†Ÿ๊ฐ’์„ ์ €์žฅํ•˜๋Š” ๋ณด์กฐ ์Šคํƒ์„ ์‚ฌ์šฉํ•ด์•ผ ํ•œ๋‹ค.

๐Ÿ“„ ์œ ํ˜• ์ดํ•ด ์ฝ”๋“œ ๐Ÿ“„

class MinStack {
    //๊ธฐ๋ณธ ์Šคํƒ ๊ตฌํ˜„
    private Deque<Integer> stack = new ArrayDeque<>();
    //์ตœ์†Œ๊ฐ’์„ ์ €์žฅํ•˜๋Š” ๋ณด์กฐ ์Šคํƒ ๊ตฌํ˜„
    private Deque<Integer> minStack = new ArrayDeque<>();
    
    //push ๋ฉ”์„œ๋“œ ์ž‘์„ฑ
    public void push(int x) {
        stack.push(x);
        //๋ณด์กฐ์Šคํƒ์ด ๋น„์–ด์žˆ๊ฑฐ๋‚˜, ๋งค๊ฐœ๋ณ€์ˆ˜ x๊ฐ€ ๋ณด์กฐ ์Šคํƒ ๋งจ ์œ„์˜ ์š”์†Œ๋ณด๋‹ค ๊ฐ™๊ฑฐ๋‚˜ ์ž‘์„ ๊ฒฝ์šฐ
        if (minStack.isEmpty() || x <= minStack.peek()) {
        	//์Šคํƒ์— ์ถ”๊ฐ€
            minStack.push(x);
        }
    }
    
    //pop ๋ฉ”์„œ๋“œ ์ž‘์„ฑ
    public void pop() {
    	//๊ธฐ๋ณธ ์Šคํƒ์˜ ๋งจ ์œ„์˜ ์š”์†Œ ๊ฐ’์ด ๋ณด์กฐ ์Šคํƒ์˜ ๋งจ ์œ„์˜ ์š”์†Œ๊ฐ’๊ณผ ๊ฐ™์„ ๊ฒฝ์šฐ
        if (stack.pop().equals(minStack.peek())) {
        	//๋ณด์กฐ ์Šคํƒ์˜ ๋งจ ์œ„์˜ ์š”์†Œ๋ฅผ ์ œ๊ฑฐํ•œ๋‹ค.
            minStack.pop();
        }
    }
    //top ๋ฉ”์„œ๋“œ ์ž‘์„ฑ
    public int top() {
    	//๊ธฐ๋ณธ ์Šคํƒ์˜ ๋งจ ์œ„ ์š”์†Œ ๋ฐ˜ํ™˜
        return stack.peek();
    }
    
    //getMin() ๋ฉ”์„œ๋“œ ์ž‘์„ฑ
    public int getMin() {
    	//๋ณด์กฐ ์Šคํƒ์˜ ๋งจ ์œ„ ์š”์†Œ ๋ฐ˜ํ™˜
        return minStack.peek();
    }
}

 

์Šคํƒ ์‚ฌ์šฉ ์‹œ ์œ ์˜ ์‚ฌํ•ญ
  • ์‹œ๊ฐ„ ๋ณต์žก๋„
  • ๋ฉ”๋ชจ๋ฆฌ ๊ด€๋ฆฌ : ์žฌ๊ท€ํ•จ์ˆ˜์˜ ๊นŠ์ด๊ฐ€ ๋„ˆ๋ฌด ๊นŠ์„ ๊ฒฝ์šฐ ์Šคํƒ ์˜ค๋ฒ„ํ”Œ๋กœ์šฐ ๋ฐœ์ƒ. 
    → ์žฌ๊ท€๋ฅผ ๋ฐ˜๋ณต๋ฌธ์œผ๋กœ ๋Œ€์ฒดํ•ด์•ผ ํ•œ๋‹ค
  • Deque ์‚ฌ์šฉ ๊ถŒ์žฅ : Stack๋Š” ๋™๊ธฐํ™” ๋ฌธ์ œ๋กœ ์ƒ๋Œ€์ ์œผ๋กœ ์„ฑ๋Šฅ์ด ์ข‹์ง€ ์•Š๋‹ค.