정수 배열 numbers가 주어집니다. numbers에서 서로 다른 인덱스에 있는 두 개의 수를 뽑아 더해서 만들 수 있는 모든 수를 배열에 오름차순으로 담아 return 하도록 solution 함수를 완성해주세요.
numbers | result |
---|---|
[2,1,3,4,1] | [2,3,4,5,6,7] |
[5,0,2,7] | [2,5,7,9,12] |
입출력 예 #1
[2,3,4,5,6,7]
을 return 해야 합니다.입출력 예 #2
[2,5,7,9,12]
를 return 해야 합니다.이 문제는 서로 다른 인덱스의 숫자끼리 더하여 중복되지 않고 오름차순정렬된 합계들을 반환해야 하는 문제입니다.
처음에는 아래의 순서대로 문제를 해결하려 시도하였습니다.
0
일 경우에는 [0]
반환하기0
번방을 합계의 0
번방의 값으로 초기화하기이러한 풀이 방법의 소스 코드는 다음과 같습니다.
class Solution {
public int[] solution(int[] numbers) {
int[] sum = new int[numbers.length*numbers.length];
int idx = 0;
boolean b = true;
// 다른 인덱스의 값의 합 구하기
for ( int i = 0; i < numbers.length; i++) {
for ( int j = 0; j < numbers.length; j++) {
if ( i != j )
sum[idx++] = numbers[i] + numbers[j];
}
}
// 합 오름차순 정렬
for ( int i = 0;i < sum.length; i++) {
for ( int j = 0;j < sum.length; j++) {
if ( sum[i] < sum[j] ) {
int tmp = sum[i];
sum[i] = sum[j];
sum[j] = tmp;
}
}
}
// 전부 다 0일 경우
int zero = 0;
for ( int i = 0; i < sum.length; i++) {
if ( sum[i] == 0 ) {
zero++;
}
}
if ( zero == sum.length ) {
int[] arr = new int[1];
arr[0] = 0;
return arr;
}
// 겹치지 않는 sum개수 구하기
int cnt = 0;
for ( int i = 1; i < sum.length; i++) {
if ( sum[i-1] == sum[i] )
continue;
cnt++;
}
// 정답을 담을 answer
int[] answer = new int[cnt];
answer[0] = sum[0];
idx = 1;
for ( int i = 1; i < sum.length; i++ ) {
if ( answer[idx-1] != sum[i] ) {
answer[idx] = sum[i];
}
}
return answer;
}
}
하지만 "제출 후 채점하기"의 8
번째 테스트케이스에서 실패가 나오게 됩니다.
제 예상으로는 아마 배열에 0
과 0
이 아닌 수가 같이 있을 때 예외가 발생하게 된 것 같습니다.
따라서 저는 조금 다른 방식으로 다시 풀기 시작하였습니다.
아래는 개선된 풀이 순서입니다.
sum[0]
으로 초기화 시킵니다.n
번째 방의 값과 같지 않을 경우, 기준값을 업데이트하고 겹치지 않는 합계값의 개수를 구합니다. public int[] solution(int[] numbers) {
int[] sum = new int[numbers.length*numbers.length-numbers.length];
int idx = 0;
for ( int i = 0; i < numbers.length; i++) {
for ( int j = 0; j < numbers.length; j++) {
if ( i != j )
sum[idx++] = numbers[i] + numbers[j];
}
}
주어진 숫자배연 numbers
길이의 제곱만큼의 sum
배열을 만들어줍니다.
이는 이중 for문
을 사용하기 때문입니다.
이 때 numbers.length
만큼 다시 빼주어야 합니다.
만약 빼주지 않는다면 인덱스가 같음으로 인해 합계가 계산이 되지 않은 0
값을 포함하게 되므로 쓰레기 값이 생겨나게 됩니다.
이중 for문
을 사용하여 인덱스가 다른 numbers
의 값일 경우 둘의 값을 더하여 sum
에 저장합니다.
이 때 sum
의 인덱스인 idx
를 1
증가시킵니다.
for ( int i = 0; i < sum.length; i++) {
for ( int j = 1; j < sum.length; j++) {
if ( sum[j-1] > sum[j] ) {
int tmp = sum[j-1];
sum[j-1] = sum[j];
sum[j] = tmp;
}
}
}
구한 합계인 sum
을 오름차순 정렬시킵니다.
java.util.Arrays
를 import
하여 Arrays.sort(sum);
으로도 구현할 수 있습니다.
int std = sum[0];
int cnt = 0;
for ( int i = 1; i < sum.length; i++) {
if ( std != sum[i]) {
cnt++;
std = sum[i];
}
}
이제 중복이 없는 합계의 수를 구할 것입니다.
이러한 절차는 정답 배열의 길이를 정하기 위해 필요합니다.
기준값이 될 std
를 sum[0]
으로 초기화를 시켜 비교가 가능하도록 만들어줍니다.
중복되지 않는 sum[i]
값의 개수를 판단할 cnt
변수를 0
으로 초기화시킵니다.
for문
을 통해 만약 기준값이 sum[i]
과 같지 않다면 중복된 값이 아니므로 cnt++
하고 기준값을 sum[i]
로 변경시킵니다.
이렇게 저희는 정답 배열을 만들 수 있는 길이값을 구하는 것에 성공하였습니다.
int[] answer = new int[cnt+1];
answer[0] = sum[0];
idx = 1;
for ( int i = 0; i < sum.length; i++) {
if ( answer[idx-1] != sum[i]) {
answer[idx++] = sum[i];
}
}
return answer;
정답 배열인 answer
의 길이를 cnt+1
로 설정합니다.
애먹었던 부분이었는데요, cnt
만을 길이로 가지게 된다면 앞서 보았던 int std = sum[0];
의 개수를 무시하게 됩니다.
지금 보니 앞의 cnt
값을 1
로 초기화를 시켜도 될 것 같군요!
다시금 answer
에 있는 값과 sum[i]
값을 비교하여 겹치지 않을 시에 answer[idx]
방에 넣어준 뒤 idx++
을 수행합니다.
이렇게 answer
에는 오름차순 정렬이 된 겹치지 않는 합의 값들이 담겨지게 되는 것입니다.
class Solution {
public int[] solution(int[] numbers) {
int[] sum = new int[numbers.length*numbers.length-numbers.length];
int idx = 0;
for ( int i = 0; i < numbers.length; i++) {
for ( int j = 0; j < numbers.length; j++) {
if ( i != j )
sum[idx++] = numbers[i] + numbers[j];
}
}
for ( int i = 0; i < sum.length; i++) {
for ( int j = 1; j < sum.length; j++) {
if ( sum[j-1] > sum[j] ) {
int tmp = sum[j-1];
sum[j-1] = sum[j];
sum[j] = tmp;
}
}
}
int std = sum[0];
int cnt = 1;
for ( int i = 1; i < sum.length; i++) {
if ( std != sum[i]) {
cnt++;
std = sum[i];
}
}
int[] answer = new int[cnt];
answer[0] = sum[0];
idx = 1;
for ( int i = 0; i < sum.length; i++) {
if ( answer[idx-1] != sum[i]) {
answer[idx++] = sum[i];
}
}
return answer;
}
}