Programmers Coding Quiz #4 같은 숫자는 싫어

김기욱·2021년 1월 24일
0

코딩테스트

목록 보기
4/68

문제 설명

배열 arr가 주어집니다. 배열 arr의 각 원소는 숫자 0부터 9까지로 이루어져 있습니다. 이때, 배열 arr에서 연속적으로 나타나는 숫자는 하나만 남기고 전부 제거하려고 합니다. 단, 제거된 후 남은 수들을 반환할 때는 배열 arr의 원소들의 순서를 유지해야 합니다.

예를 들면, arr = [1, 1, 3, 3, 0, 1, 1] 이면 [1, 3, 0, 1] 을 return 합니다.
arr = [4, 4, 4, 3, 3] 이면 [4, 3] 을 return 합니다.

배열 arr에서 연속적으로 나타나는 숫자는 제거하고 남은 수들을 return 하는 solution 함수를 완성해 주세요.

제한사항

배열 arr의 크기 : 1,000,000 이하의 자연수
배열 arr의 원소의 크기 : 0보다 크거나 같고 9보다 작거나 같은 정수

입출력 예

arranswer
[1,1,3,3,0,1,1][1,3,0,1]
[4,4,4,3,3][4,3]

풀이

제일 처음 제가 조건에서 보았던 키워드는 두 개 였습니다.
중복제거, 순서유지 그래서 단순하게 코드를 짰었죠.

import pandas
def solution(arr):
	return pandas.unique(arr).tolist()

예전에 기업협업 프로젝트에서도 썼던 판다스 메서드입니다. 정말 간단하게 중복제거와 순서유지를 해결해주죠. 하지만 당연히 실패합니다. 판다스 유니크 메서드는 '모든 중복'을 허용하지 않기 때문입니다. 첫 번째 예시처럼 나열된 리스트는 모든 중복이 제거되어 [1,3,0]이 리턴되버리고 맙니다.

그래서 중복제거가 아닌 나열된 숫자 중에 하나만 추출해서 새롭게 리스트를 만들어내자라고 생각을 바꿉니다.

def solution(arr):
    answer = []
    for i, v in enumerate(arr):
        if i == len(arr)-1:
            answer.append(arr[i])
            break
        if arr[i] != arr[i+1]:
            answer.append(arr[i])
    return answer

우선 i가 최대인덱스값에 도달하면, i+1은 리스트 범위를 벗어난 인덱스이기 때문에 에러가 뜨게됩니다. 그러므로 최대인덱스에선 최대인덱스에 해당하는 요소를 넣어주고, for문을 break로 끝냅니다.

그리고 아래 조건문에서는 i, i+1를 비교해 같지않으면 answer라는 새로운 리스트에 넣어줍니다. 왜 첫 번째 조건문에서 마지막 인덱스를 무조건 넣냐면 다음과 같은 이유 때문입니다.

1) 마지막 두개가 다른 경우
arr = [1, 2, 3, 3, 4, 5, 5, 6]
i가 두번째 5(index = 6)에 있을 때, 6과 다르므로 5를 넣어주고 그 다음 루프에서 마지막 인덱스인 6도 넣어준다.

2) 마지막 두개가 같은 경우
arr = [1, 2, 3, 3, 4, 5, 6, 6]
i가 첫 번째 6(index = 6)에 있을 때, 6과 같으므로 넣어지지 않아지고 6까지 오게됨. 마지막 인덱스인 6을 넣어줘야 함.

그러므로 마지막 인덱스는 무조건 넣고, 루프를 끝내줘야 합니다.

다른풀이

def solution(arr):
    answer = []
    for v in arr:
        if answer[-1:] == [v]: 
            continue
        answer.append(v)
    return answer

슬라이싱을 이용한 아주 센스있는 풀이입니다.

핵심은 answer[-1:]입니다. answer[-1]과 같은 인덱싱과 다르게 슬라이싱은 빈 리스트도 에러를 반환하지 않습니다. 그리고 요소가 있다면 가장 마지막 인덱스에 해당되어있는 리스트를 뱉어냅니다.

또한 continue를 통해 중복일 경우 건너뛰고 다음 루프를 돌게되죠.
저 처럼 비교를 주어진 배열에서 앞/뒤 인덱스로 하는게 아니라 새로운 배열에 마지막 값으로 계속 비교하기 때문에 코드가 간결하고 실행 속도도 더 빠릅니다. 또 배웠습니다. 😆

def solution(arr):
    # 리스트컴프리헨션 + 슬라이싱
    return [arr[i] for i in range(len(arr)) if [arr[i]] != arr[i+1:i+2]]

슬라이싱을 이용해 구현한 한 줄 짜리 풀이입니다.
다만 새로운 배열에 슬라이싱을 하는게 아니라 주어진 배열에 슬라이싱을 계속해서 하기 때문에
시간복잡도에선 좋지않은 결과를 보여줍니다.

profile
어려운 것은 없다, 다만 아직 익숙치않을뿐이다.

0개의 댓글

관련 채용 정보

Powered by GraphCDN, the GraphQL CDN