쇠막대기(stack 개념)




여러 개의 쇠막대기를 레이저로 절단하려고 한다.

효율적인 작업을 위해서 쇠막대기를 아래에 서 위로 겹쳐 놓고, 레이저를 위에서 수직으로 발사하여 쇠막대기들을 자른다.

쇠막대기와 레 이저의 배치는 다음 조건을 만족한다.

• 쇠막대기는 자신보다 긴 쇠막대기 위에만 놓일 수 있다.

  • 쇠막대기를 다른 쇠막대기 위에 놓는 경우 완전히 포함되도록 놓되, 끝점은 겹치지 않도록 놓는다. • 각 쇠막대기를 자르는 레이저는 적어도 하나 존재한다. • 레이저는 어떤 쇠막대기의 양 끝점과도 겹치지 않는다.

아래 그림은 위 조건을 만족하는 예를 보여준다.

수평으로 그려진 굵은 실선은 쇠막대기이고, 점은 레이저의 위치, 수직으로 그려진 점선 화살표는 레이저의 발사 방향이다.

이러한 레이저와 쇠막대기의 배치는 다음과 같이 괄호를 이용하여 왼쪽부터 순서대로 표현할 수 있다.

  1. 레이저는 여는 괄호와 닫는 괄호의 인접한 쌍 ‘( ) ’ 으로 표현된다. 또한, 모든 ‘( ) ’는 반 드시 레이저를 표현한다.

  2. 쇠막대기의 왼쪽 끝은 여는 괄호 ‘ ( ’ 로, 오른쪽 끝은 닫힌 괄호 ‘) ’ 로 표현된다. 위 예의 괄호 표현은 그림 위에 주어져 있다.

쇠막대기는 레이저에 의해 몇 개의 조각으로 잘려지는데,

위 예에서 가장 위에 있는 두 개의 쇠막대기는 각각 3개와 2개의 조각으로 잘려지고,

이와 같은 방식으로 주어진 쇠막대기들은 총 17개의 조각으로 잘려진다.

쇠막대기와 레이저의 배치를 나타내는 괄호 표현이 주어졌을 때,

잘려진 쇠막대기 조각의 총 개수를 구하는 프로그램을 작성하시오.


▣ 입력예제 1 : ()(((()())(())()))(())

▣ 출력예제 1 : 17

▣ 입력예제 2 : (((()(()()))(())()))(()())

▣ 출력예제 2 : 24




<개념 & 문제 접근방식>

괄호가 문제에 들어있다면 10에 8은 stack문제라고 생각하면 된다.

여는 괄호를 넣으면 무조건 stack에 푸시

아는 괄호는 1. 여는 괄호 2. 막대기 시작점 이렇게 2가지 종류로 생각해볼 수 있다.

닫는 괄호는 1. 레이저의 괄호 2. 막대기 끝

닫는 괄호를 만나면 무조건 바로 앞의 괄호를 찾아봐야한다.

i번째가 닫는 괄호라면 i-1의 요소를 찾아 그게 여는 괄호인지 바로 체크를 해주고,

만약 바로 앞의 요소가 여는 괄호라면 i번째 괄호는 레이저의 닫는 괄호이다.

만약 바로 앞의 요소가 여는 괄호가 아니라면 i번째 괄호는 막대기의 끝 괄호라고 생각하면 된다.

막대기의 갯수는 stack에 들어있는 여는괄호의 갯수와 같다.

그리고, 닫는괄호를 만나면 앞의 여는 괄호를 무조건 하나 빼야한다.

왜냐면 레이저의 괄호이건, 막대기의 끝 괄호이건 stack에 들어있는 열린괄호는 제거해주어야함.

그리고 answer에다가는 +1 해주어야한다.

레이저로 자르면 막대기가 하나 생기기 때문에 +1해주어야함.

그리고 pop을 해주고 나면 (새로운 열린괄호가 들어오기전에) answer에서는 stack의 size를 누적시켜준다.

막대기의 객수를 누적해줘야하기때문에..


CASE 1

function solution(s){
    let answer=0;
    let stack=[];
    for(let i=0; i<s.length; i++){  //idx를 뽑기 위해 for of문 안씀
        if(s[i]==='(') stack.push('('); //열린괄호를 만나면 push하기
        else{   //닫힌괄호라면
            stack.pop(); //괄호를 제일 먼저 빼주어야함. if문 위에서 미리 빼줘야함
            if(s[i-1]==='('){   //i-1(바로전)괄호가 열린괄호라면 => 레이저
                answer+=stack.length; //stack에 쌓여있는 열린괄호 갯수를 넣어준다
            }else{  //레이저가 아닌 막대기의 끝
                answer++;
            } 
            //stack.pop(); 이 위치에 하면 레이저까지 카운팅한다.
        }
    }                          
    return answer;
}

let a="()(((()())(())()))(())";
console.log(solution(a));




출처 : 자바스크립트 알고리즘 문제풀이 입문(코딩테스트 대비)를 보고 작성!




© 2018. by sora

Powered by sora