※ 본 사진과 해당 게시글 내용의 문제 모두 프로그래머스[Programmers]사이트에 발췌해왔습니다.
배열 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]
def solution(arr):
answer = [arr[0]]
for x in arr :
if answer[len(answer)-1] != x :
answer.append(x)
return answer
<정확성 : 71.9 / 효율성 : 28.1>
이유가 무엇일까...
효율성이 떨어지는 것은 아마도... arr 안에 매우 많은 값들이 들었을 경우에 발생하는
너무 오래 걸리는 것이 문제이겠지... 100만 개까지 들어간다 했으니...
사실 pandas를 import해서 .unique()
를 해야할까 했는데
import도 안되는 뿐더러 순서를 지켜서 나와야하는 조건 때문에 포기했고
그 후, 머리를 쥐어 싸매다가 풀었던 문제이다.
어쨋든
내가 작성한 코드는
우선 순서대로 주르르 비교해야 하기 때문에
입력된 배열의 첫값을 먼저 결과로 반환할 빈 리스트 안에 넣은 채 시작한다.
그 다음, 순서대로 answer리스트의 끝값과 비교해서
동일한 숫자가 연속적으로 나오는지 확인해야하기 때문에 answer[len(answer)-1]
으로
끝값이 x와 같은 숫자인지 다른 숫자인지 비교하여
일치하지 않는 경우만 answer리스트에 append하는 방법을 사용했다.
(1)
def no_continuous(s):
result = []
for c in s:
if (len(result) == 0) or (result[-1] != c):
result.append(c)
return result
전체적인 구조는 필자의 코드와 유사하지만
조건문의 내용에서 살짝 차이가 있어 가져오게 되었다.
우선 끝 값 비교를 역인덱싱으로 간단하게 해결하였다. (result[-1] != c
)
그리고 처음에 빈 리스트로 시작해서
len(result)==0
을 위 역인덱싱 조건에 or로 중첩하여 처음 시작하는 경우를 해결했다.
(2)
def no_continuous(s):
a = []
for i in s:
if a[-1:] == [i]: continue
a.append(i)
return a
알고 있으면 효과적인 정보일 것 같아 갖고 오게 되었다.
바로 슬라이싱은 인덱스값이 "해당 배열의 범위를 초과/미달해도" 오류가 발생하지 않는다는 사실이였다.
비어있으면 오류가 발생하는 것이 아니고 []로 출력된다.
이 특징을 활용하여
비어있을 경우까지 포괄적으로 해결한 방법이다.
a[-1:] == [i]
일 경우 continue로 append하는 과정을 건너뛰고
아닌 경우에 append하게끔 설계했다.
위 조건식에서 [i]로 입력한 이유는
앞서 ":"로 범위를 호출했기 때문에 리스트 형태로 반환되는 것이다.
-1:는 "끝에서 시작해서 끝까지"라는 의미이고 이는 끝값 하나만 갖고오게 하는 것이다.
알면 알수록 놀라운 각기 다른 사람들의 센스에
늘 알고리즘 푸는 것이 기대되고 재밌는 것 같다..
더 가져와...
더...
(더 풀러 가야지..)