안녕하세요! 피피아노입니다 🎵
이번 포스팅에서는 프로그래머스에 있는 삼총사 문제 풀이 및 회고를 작성해보려고 합니다.
그럼 바로 시작하겠습니다!
문제 설명
삼총사 문제에 대해서 먼저 확인해 보겠습니다.
한국중학교에 다니는 학생들은 각자 정수 번호를 갖고 있습니다. 이 학교 학생 3명의 정수 번호를 더했을 때 0이 되면 3명의 학생은 삼총사라고 합니다. 예를 들어, 5명의 학생이 있고, 각각의 정수 번호가 순서대로 -2, 3, 0, 2, -5일 때, 첫 번째, 세 번째, 네 번째 학생의 정수 번호를 더하면 0이므로 세 학생은 삼총사입니다. 또한, 두 번째, 네 번째, 다섯 번째 학생의 정수 번호를 더해도 0이므로 세 학생도 삼총사입니다. 따라서 이 경우 한국중학교에서는 두 가지 방법으로 삼총사를 만들 수 있습니다.
한국중학교 학생들의 번호를 나타내는 정수 배열 number가 매개변수로 주어질 때, 학생들 중 삼총사를 만들 수 있는 방법의 수를 return 하도록 solution 함수를 완성하세요.
문제 이해
위에 주저리주저리 길게 나와 있는데 핵심만 뽑아내면
- 목표: 주어진 정수 배열 number에서, 서로 다른 세 숫자의 합이 0이 되는 경우(삼총사)의 개수를 구하기.
- 조건: 배열의 각 요소는 학생 번호를 나타내는 정수, 3명을 뽑아 합이 0이 되는 경우의 수를 찾아야 함.
- 제한 사항: number 배열의 길이는 3 이상 13 이하, 각 요소는 -1,000 이상 1,000 이하의 정수.
이렇게 정리할 수 있습니다.
문제 풀기
저는 이 문제를 읽고 푸는 법을 아래처럼 정리를 해봤습니다.
- 삼총사를 만들 수 있는 경우의 수를 담을 변수 선언하기 (초기값은 0)
- 세 숫자를 선택하는 반복문 만들기
- if문을 사용해서 3합이 0이 되면 선언해 둔 변수의 값을 1씩 증가시키기
일단 이렇게 풀긴 했지만 저는 이 방법이 그리 좋은 방법은 아니라고 생각을 합니다.
그 이유는 for문을 3번이나 연속해서 사용해야 하기 때문인데요.
왜 3번이나 반복해야 하는지는 밑에서 마저 설명하고 일단 코드를 차근차근 풀어보겠습니다.
변수 설정
먼저 가장 먼저 해주어야 할 것은 변수 설정인데, 저는 단순히 숫자를 1씩 카운팅 하는 것이 목적이라 변수의 이름은 count라고 설정하였습니다.
var count = 0
이 변수는 초기값이 0이지만 경우의 수가 생길 때마다 1씩 증가해야 하기 때문에 var로 변수 선언을 해주었습니다.
세 숫자를 선택하는 반복문 만들기
그리고 다음으로 해주어야 할 것은 세 숫자를 선택하는 반복문을 만드는 것입니다.
저는 이 과정을 풀기 위해 3중 for문을 사용해서 코드를 작성했습니다.
for num1 in 0..<number.count {
for num2 in num1+1..<number.count {
for num3 in num2+1..<number.count {
- for num1 in 0..<number.count: 첫 번째 숫자의 인덱스 num1를 배열의 처음부터 선택합니다.
- for num2 in num1+1..<number.count: 두 번째 숫자의 인덱스 num2는 항상 num1 다음부터 시작합니다.
- for num3 in num2+1..<number.count: 세 번째 숫자의 인덱스 num3는 항상 num2 다음부터 시작합니다.
for문을 이렇게 작성하게 되면 num1 < num2 < num3 조건이 항상 성립함과 동시에 같은 숫자가 중복 선택되지 않게 할 수 있습니다.
예시로 만약 배열 number = [1, 2, 3, 4]라고 가정을 해보자면
첫 번째 반복문 (num1):
- num1은 0, 1, 2, 3으로 반복합니다.
- 이때, num1이 선택한 인덱스 이후부터 두 번째 숫자와 세 번째 숫자를 선택하게 됩니다.
두 번째 반복문 (num2):
- num2는 항상 num1+1부터 시작합니다.
- 예를 들어, num1 = 0일 때, num2는 1, 2, 3 중에서 선택됩니다.
- num1 = 1일 때, num2는 2, 3 중에서 선택됩니다.
세 번째 반복문 (num3):
- num3는 항상 num2+1부터 시작합니다.
- 예를 들어, num1 = 0, num2 = 1일 때, num3는 2, 3 중에서 선택됩니다.
- num1 = 0, num2 = 2일 때, num3는 3만 선택됩니다.
세 숫자의 합이 0이라면 1씩 증가
이제 해야 할 것은 for문 안에 if문을 설정하는 것입니다.
세 숫자의 합이 0인지 확인하고 만약 맞다면 아까 선언한 count 변수에 1씩 증가해야 하기 때문에 저는 코드를 아래처럼 간단하게 작성했습니다.
if number[num1] + number[num2] + number[num3] == 0 {
count += 1
}
결과 반환
이제 마지막으로 결과를 반환하려면
return count
이렇게 작성해 주면 됩니다.
전체 코드
import Foundation
func solution(_ number:[Int]) -> Int {
var count = 0
for num1 in 0..<number.count {
for num2 in num1+1..<number.count {
for num3 in num2+1..<number.count {
if number[num1] + number[num2] + number[num3] == 0 {
count += 1
}
}
}
}
return count
}
전체 코드를 확인하면 이렇게 나오게 됩니다.
회고
문제 풀이의 단순성과 한계
3중 for문을 사용하여 세 숫자를 조합해 합이 0이 되는 경우를 찾는 방식은 문제를 정확히 해결하는 데 효과적이었습니다. 하지만 효율성 측면에서 아쉬움이 컸습니다. 특히 입력 배열의 길이가 커질수록 계산량이 급격히 늘어나기 때문에, 더 나은 알고리즘적 접근이 필요하다고 느꼈습니다.
개선 방향 탐색
이번 풀이에서는 조합의 모든 경우를 다루기 위해 3중 for문을 사용했지만, 다음번에는 고차함수나 다른 알고리즘 방식을 고려해서 코드를 간소화하고 효율성을 높이는 방향을 고민해 볼 계획입니다. 또한, 중복 계산을 줄이고 조건에 더 최적화된 방법을 찾아야겠다는 생각이 들었습니다.
배운 점
문제를 읽고 핵심만 정리하는 훈련이 도움이 되었습니다. 문제의 조건을 정확히 파악한 덕분에 풀이는 비교적 수월하게 진행되었습니다. 그리고 간단한 문제라도 “어떤 방법이 더 나은가? “를 고민하며 구현을 진행하는 습관이 중요하다는 것을 다시 한번 깨달았습니다.
다음 단계
효율적인 알고리즘 설계에 대한 학습을 더 깊이 있게 진행하고자 합니다. 특히, 다양한 입력 케이스에 대한 테스트와 성능 최적화를 염두에 두고 문제를 푸는 연습을 더 하려고 합니다.
오늘은 여기까지 :)
감사합니다.
잘못된 내용이 있거나 더 좋은 내용 피드백은 언제나 환영합니다!
궁금하신 부분은 댓글로 질문 부탁드립니다!
'Apple > Swift' 카테고리의 다른 글
[Swift] Actor 이해하기 (2/2) (4) | 2024.12.15 |
---|---|
[Swift] 두 정수 사이의 합 (4) | 2024.12.05 |
[Swift] stride와 enumerated 알아보기 (2) | 2024.11.24 |
[Swift] 과일 장수 문제 풀이 및 회고 (4) | 2024.11.20 |
[Swift] 제곱근 판별하기 (5) | 2024.11.16 |