갱스터하우스

[Python] Lv1. 같은 숫자는 싫어 본문

코테 문제/프로그래머스

[Python] Lv1. 같은 숫자는 싫어

승갱 2022. 4. 11. 16:38

https://programmers.co.kr/learn/courses/30/lessons/12906

 

코딩테스트 연습 - 같은 숫자는 싫어

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

programmers.co.kr

 

 

 

 

 

문제 설명

배열 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보다 작거나 같은 정수

입출력 예

arr answer
[1, 1, 3, 3, 0, 1, 1] [1, 3, 0, 1]
[4, 4, 4, 3, 3] [4, 3]

 


나의 접근 방법 및 풀이

단순히 리스트 내의 중복을 제거하는 문제였다면 set()을 사용해서 금방 끝냈겠지만, 이 문제는 연속되는 숫자 중 하나는 남기고 제거하는 문제였다.

그래서 for()문을 이용해서 그다음 인덱스의 요소와 비교해서 제거하면 되겠구나라고 생각했다.

하지만 아래처럼 구현했을 경우, [i+1]가 range(len(arr))의 범위를 벗어나는 경우가 생겨 에러가 발생하고 결론적으로 실패했다.

def solution(arr):
    answer = []
    for i in range(len(arr)):
        if arr[i] == arr[i+1]:
            del arr[i]
    return arr

 

다른 사람들의 풀이를 참고 하던 중 가장 많이 보였던 풀이들의 공통점이 있었다.

내가 생각했던 구현은 아래의 그림에서 파란색처럼 현재 인덱스와 그다음 인덱스와의 비교를 통해 이루어졌다. 그러다 보니 마지막 인덱스에서는 [i+1]에 해당하는 인덱스가 없다 보니 에러가 발생했다.

하지만 다른 풀이들에서는 먼저 첫 번째 인덱스는 배열에 저장후, 비교는 2번째 인덱스부터 시작하였다. 그리고 그다음 인덱스가 아니라, 이전의 인덱스와의 비교해 나아갔다. 이전 인덱스와의 비교에서는 첫 번째 인덱스의 경우를 if() 문으로 설정한다면, 에러가 날 일이 없었다.

def solution(arr):
    answer = []
    for i in range(len(arr)):
        if i == 0:      ## 0번째 인덱스는 비교없이 먼저 배열에 추가
            answer.append(arr[i])
        elif arr[i] != arr[i-1]:    ## 현재 인덱스와 이전 인덱스가 같지 않을 경우 추가
            answer.append(arr[i])
    return answer

 

 

다른 사람 풀이 참고

배열의 길이가 0일때, 새로운 배열의 마지막 요소가 현재 값과 같지 않을 경우(= 이전 인덱스와 중복이 아닌 경우) 추가하도록 한다.

처음 len(result)==0은 c가 첫 번째 요소일 때를 고려하였고, result[-1] != c는 인덱스가 1부터인 경우이다.

def no_continuous(s):
    result = []
    for c in s:
        if (len(result) == 0) or (result[-1] != c):		
            result.append(c)
    return result

 

다음 풀이는 슬라이싱을 이용하였다.

빈 리스트에서 마지막 요소와 for()문을 이용하여 리스트 s의 요소를 비교하였는데, 

여기서 새로운 리스트의 마지막 요소를 꺼내올때 a [-1]이 아니라 a [-1:]을 사용했다. [-1:]을 사용하여 빈 리스트여도 비교가 가능하게 했다.

 

def no_continuous(s):
    a = []
    for i in s:
        if a[-1:] == [i]: continue
        a.append(i)
    return a