원소들의 곱과 합을 비교하는 알고리즘 문제 풀이 (Java & Python)
이번 글에서는 정수 리스트 num_list
가 주어졌을 때, 모든 원소들의 곱이 모든 원소들의 합의 제곱보다 작으면 1을, 크면 0을 반환하는 알고리즘 문제를 Java와 Python으로 풀어보겠습니다. 이 문제는 간단한 산술 연산과 조건문을 활용한 문제로, 배열의 원소들 간의 관계를 파악하는 좋은 연습이 될 것입니다. 자바와 파이썬의 코드 예시와 함께, 다양한 풀이 방법과 각 풀이 방법의 시간 및 공간 복잡도에 대해 설명해 보겠습니다.
문제 설명
정수 리스트 num_list
가 주어졌을 때, 리스트의 모든 원소들의 곱이 모든 원소들의 합의 제곱보다 작으면 1
을 반환하고, 그렇지 않으면 0
을 반환하는 함수를 구현하세요.
제한사항
num_list
의 길이는 최소 2에서 최대 10까지입니다.- 각 원소는 1 이상 9 이하의 정수입니다.
입출력 예
num_list | 결과 |
---|---|
[3, 4, 5, 2, 1] | 1 |
[5, 7, 8, 3] | 0 |
입출력 예 #1: 모든 원소의 곱은 120이고, 합의 제곱은 225이므로 곱이 합의 제곱보다 작으므로 1
을 반환합니다.
입출력 예 #2: 모든 원소의 곱은 840이고, 합의 제곱은 529이므로 곱이 더 크기 때문에 0
을 반환합니다.
해결 방법
이 문제를 해결하기 위해 배열의 원소들을 곱하고 더하는 기본적인 산술 연산을 수행한 뒤, 조건문을 사용하여 비교합니다. 각 언어별로 코드와 설명을 제공하고, 시간 및 공간 복잡도도 분석하겠습니다.
Java 코드
class Solution {
public int solution(int[] num_list) {
int product = 1;
int sum = 0;
for (int num : num_list) {
product *= num;
sum += num;
}
int sumSquared = sum * sum;
return product < sumSquared ? 1 : 0;
}
}
시간 복잡도
- 시간 복잡도: O(n) - 배열의 모든 원소에 대해 곱셈과 덧셈을 한 번씩 수행하므로, 배열의 길이
n
에 비례하는 시간이 소요됩니다. - 공간 복잡도: O(1) - 추가적인 배열을 사용하지 않고, 고정된 크기의 변수(
product
,sum
,sumSquared
)만 사용하므로 공간 복잡도는 상수입니다.
Python 코드
def solution(num_list):
product = 1
total_sum = 0
for num in num_list:
product *= num
total_sum += num
sum_squared = total_sum ** 2
return 1 if product < sum_squared else 0
시간 복잡도
- 시간 복잡도: O(n) - 리스트의 모든 원소에 대해 곱셈과 덧셈을 각각 수행하기 때문에 배열의 길이
n
에 비례하는 시간이 필요합니다. - 공간 복잡도: O(1) - 추가 메모리를 사용하지 않으며, 고정된 크기의 변수들만 사용합니다.
다양한 Java 풀이 방법 소개
위의 기본 풀이 외에도 자바에서는 다양한 방법으로 이 문제를 해결할 수 있습니다. 몇 가지 추가적인 풀이 방법을 살펴보겠습니다.
1. Streams 사용
Java 8 이상의 버전에서는 Stream API를 이용해 간결하게 문제를 해결할 수 있습니다.
import java.util.Arrays;
class Solution {
public int solution(int[] num_list) {
int product = Arrays.stream(num_list).reduce(1, (a, b) -> a * b);
int sum = Arrays.stream(num_list).sum();
int sumSquared = sum * sum;
return product < sumSquared ? 1 : 0;
}
}
설명
Arrays.stream()
: 배열을 스트림으로 변환합니다.reduce(1, (a, b) -> a * b)
: 스트림의 모든 원소에 대해 곱셈을 수행합니다.sum()
: 스트림의 모든 원소를 더합니다.
장점 및 단점
- 장점: 코드가 간결하고 가독성이 높습니다.
- 단점: 작은 배열에서는 성능 차이가 없지만, 스트림 사용에 따른 약간의 성능 오버헤드가 발생할 수 있습니다.
2. for-each 루프 대신 일반 for 루프 사용
기존의 for-each 루프 대신 일반적인 인덱스를 사용하는 for 루프를 이용하여 문제를 해결할 수 있습니다.
class Solution {
public int solution(int[] num_list) {
int product = 1;
int sum = 0;
for (int i = 0; i < num_list.length; i++) {
product *= num_list[i];
sum += num_list[i];
}
int sumSquared = sum * sum;
return product < sumSquared ? 1 : 0;
}
}
설명
- 일반 for 루프를 사용하여 배열의 인덱스를 명시적으로 다루기 때문에, 인덱스 접근이 필요한 경우에 유리합니다.
- 성능 측면에서 for-each와 큰 차이는 없지만, 코드 스타일의 차이로 인해 상황에 따라 유용하게 사용할 수 있습니다.
장점 및 단점
- 장점: 인덱스가 필요한 추가 로직을 쉽게 적용할 수 있습니다.
- 단점: 코드가 다소 길어지고 가독성이 떨어질 수 있습니다.
비교 및 결론
- 기본 for-each 루프는 코드가 간단하고 명료하여 가독성이 좋습니다. 특별한 인덱스 접근이 필요하지 않을 때 사용하기 좋습니다.
- Streams를 사용하면 함수형 프로그래밍 스타일로 코드를 작성할 수 있어 더 간결하고 직관적입니다. 하지만 스트림은 작은 데이터셋에서는 성능상의 이점이 없을 수 있으며, 오히려 약간의 오버헤드가 발생할 수 있습니다.
- 일반 for 루프는 인덱스를 이용한 배열 접근이 필요한 경우 유리하며, 배열 요소에 대한 명시적인 접근이 가능해 추가 로직을 적용할 때 유용합니다.
문제의 제한 조건(배열의 길이가 최대 10)에 비추어 볼 때, 각 방법의 성능 차이는 거의 없으며, 개인의 선호도와 코드 스타일에 따라 선택하면 됩니다. 함수형 스타일의 간결함을 선호한다면 Streams를, 명시적인 인덱스 접근을 원한다면 일반 for 루프를 사용하는 것이 좋습니다.
이 글을 통해 배열의 곱과 합을 비교하는 문제를 다양한 방식으로 해결해 보았습니다. 여러분의 상황에 맞는 방법을 선택하여 효율적으로 문제를 해결해 보세요! 😊
'여러가지 > 알고리즘 & 자료구조' 카테고리의 다른 글
[프로그래머스] 나머지가 1이되는 수 찾기 (0) | 2024.10.12 |
---|---|
[프로그래머스] 뒤에서 5등까지 (0) | 2024.10.12 |
[프로그래머스] 마지막 두 원소 (0) | 2024.10.12 |
[프로그래머스] 수 조작하기1 (0) | 2024.10.12 |
[백준] 문어 - 21313번 (0) | 2024.06.17 |