[코딩테스트]프로그래머스 - 큰 수 만들기

Adela·2020년 5월 3일
0

프로그래머스

목록 보기
2/30
post-thumbnail

결국 친구의 도움으로 해결했다 ㅜㅜ 갈길이 먼 코린이의 하루..

큰 수 만들기

문제 설명

어떤 숫자에서 k개의 수를 제거했을 때 얻을 수 있는 가장 큰 숫자를 구하려 합니다.
예를 들어, 숫자 1924에서 수 두 개를 제거하면 [19, 12, 14, 92, 94, 24] 를 만들 수 있습니다. 이 중 가장 큰 숫자는 94 입니다.
문자열 형식으로 숫자 number와 제거할 수의 개수 k가 solution 함수의 매개변수로 주어집니다. number에서 k 개의 수를 제거했을 때 만들 수 있는 수 중 가장 큰 숫자를 문자열 형태로 return 하도록 solution 함수를 완성하세요.

제한 조건

  • number는 1자리 이상, 1,000,000자리 이하인 숫자입니다.
  • k는 1 이상 number의 자릿수 미만인 자연수입니다.

입출력 예

number		k	return
1924		2	94
1231234		3	3234
4177252841	4	775841

해결한 코드 (나의 코드)

function solution(number, k){
	var answer = ''
    var length = number.length - k
    
    for(let i=0; i<number.length;){
    	var pointer = number[i]
        if(answer.length = length){ // k개만큼 빼면
        	break; // 반복문 나가기
        }
        
        if(pointer == 9){ // number에 들어올 수 있는 제일 큰 숫자 
        	answer += pointer.toString()
            i++
            continue // 밑에 짜놓은 코드는 무시하도록 
        }
        var bigNum = biggerNumber(number, i)
        if(bigNum.val == -1){ // number중에 제일 큰 수면
        	answer += pointer.toString()
            i++
        } else {
        	// pointer ~ bigNum있는 곳까지의 length 크기
        	var pointer_len = bigNum.idx - i 
            
            // 그 사이의 거리(length)가 k보다 작으면
            if(pointer_len <= k){             	
            	k = k - pointer_len // k 줄이기
            	i = bigNum.idx // i는 bigNum의 인덱스가 됨 
                
            } else { // k랑 같거나 크면 
            	answer += pointer.toString()
                i++
            }
        }
    }
    return answer
}

// number와 해당 pointer의 인덱스를 매개변수로 받는 함수 만들어줌 
function biggerNumber(number, pointerIndex){ 
	let value, idx = 0
    
    for(let i = pointerIndex; i<number.length; i++){
    /* 처음이 아닌 "pointer가 있는 곳"부터 ~ number의 끝까지 돌아야 하므로 
     pointerIndex로 시작해야 한다.
    그렇지 않으면 number의 뒤쪽에 위치한 수가 앞쪽의 위치한 수랑 일치할 때 
    애먼 값으로 계산해버릴 수 있기 때문이다. */
    
    	if(number[i]>number[pointerIndex]){
    		value = number[i]
        	idx = i
        	break // pointer ~ number끝까지 중 pointer보다 큰 "제일 첫번째 수"
    	} else {
    		value = -1 // pointer가 제일 크면 -1을 반환  
    	}
    }
    
    return {val: value, idx: idx}
}

내가 생각한 알고리즘

  1. 우선 입출력 예시와 같이 만약 number = 4177252841 이 들어온다면
  2. 맨 첫 원소 4를 pointer로 잡는다.
  3. number를 돌며 pointer보다 큰 수가 있는지 파악한다.
    3-1. 주의: 순서대로 돌면서 만나는 pointer보다 큰 첫번째 수여야 한다.
    3-2. 7이 4보다 크고, 4가 만나는 첫번째 큰 수이다.
  4. pointer부터 7까지 그 사이에 몇 개의 원소가 있는지 확인한다.
    4-1. 4, 1이 있으므로 총 두개이다.
    4-2. 이는 곧 7의 index에서 pointer의 index를 뺀 값과 동일하다. (2-0 = 2)
  5. 그 사이에 있는 원소 개수가 k보다 작으면, 그 원소들은 제외시켜도 되는 수들이다.
    5-1. pointer를 해당 큰 수의 인덱스로 바꾼다.
  6. 그 사이에 있는 원소 개수가 k보다 크면, 더이상 원소를 제외시킬 수 없다.
    6-1. 현재 pointer는 뺄 수 없는 수이므로 answer에 합친다.
  7. answer의 길이가 number의 길이에서 k를 뺀 값이 될 때까지 반복한다.

예외 처리 사항

E1. 만약 number에 9999999999 가 들어온다면
1-1. 9를 일일이 다 돌면 시간초과가 된다. 따라서 9의 경우 어차피 뺄 수 없는 제일 큰 수라는 것을 인지하고 answer에 합친다.

알고리즘은 틀리지 않았지만, 구현에 많은 시간이 들었다.
우선, pointer보다 큰 첫번쨰 수를 구하는 부분에서 어려움을 겪었다. 단순하게 find() 함수를 사용했는데, 그렇게 하다보니 number의 처음부터 끝까지 중 가장 첫번째로 등장하는 큰 수를 반환하였다.

나는... pointer 앞에 있는 애들 말고 뒤에 있는 애들을 찾아야 하는데 ...

또한, (아직 코린이라 그런지) for문에서 i++을 안써줘도 되는지 몰랐다.

어쩔땐 i++이 되도록, 어쩔땐 i = bigNum이 되도록 다르게 짜도 되대..? 허허

마지막으로, continue에 대한 복습을 할 수 있었다. 9가 들어오면 굳이 bigNum을 찾는 과정은 생략하고 빠르게 answer에 넣어준 후 다음 인덱스로 가야 하는데 continue를 빼먹어서 또 실패했었다.

그 외에도 사실 조급한 마음이나 실패에 대한 내부귀인을 일삼는 요즘 나의 바람직하지 못한 마음가짐 때문에 더 더뎌진 것도 있다.. 이제 시작한 코린이가 급히 실력을 쌓고 싶어 안절부절하는지 모르겠다. 코린이라는 걸 명심하고, 멋진 코른이는 긴 호흡으로 꾸준히 이어가야 될 수 있다는 것을 계속해서 인지하자 !! 성장하고 있는 느낌이 팍팍 들지 않는다고 (부디 제발) 의미없는 자책은 하지 말기를 !

profile
개발 공부하는 심리학도

0개의 댓글