본문 바로가기

CS ﹒ Algorithm/Programmers

Java 프로그래머스 문제풀이 (4) 없는 숫자 더하기

 

 

엄청 쉬운 문제이기 때문에 여러가지 방법으로 풀어보자.

스트림으로 풀면 예쁘긴 한데, 속도 차이가 얼마나 나는지도 확인해보자.

 

 

 

 

 

 

 

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
import java.util.*;
 
class Solution {
    public int solution(int[] numbers) {
    ArrayList<Integer> numList = new ArrayList<>();
    int sum = 0;    
        
    for (int i=0; i<numbers.length; i++) {
        numList.add(numbers[i]);
    }
        
    for (int i=0; i<=9; i++) {
        if (!numList.contains(i)) sum+=i;
    }
        
    return sum;
    }
}
cs

 

 

우선 스트림을 사용하지 않는 방법이다.

Set이나 List나 Contains에 대한 시간 복잡도는 O(1)이므로 별 차이가 없겠다.

기본값 타입의 배열로는 이보다 빠르게 돌릴 방법이 마땅히 생각나지 않는다.

 

 

 

 

 

 

 

 

 

1
2
3
4
5
6
7
8
9
10
import java.util.*;
import java.util.stream.*;
 
class Solution {
    public int solution(int[] numbers) {
    return IntStream.range(0,10)
        .filter(num -> Arrays.stream(numbers).noneMatch(n->num==n))
        .sum();
    }
}
cs

스트림을 읽을 줄 모르는 사람을 위해 설명하자면

IntStream.range(0,10)은 for(i=0; i<10; i++)랑 같다.

그냥 순회시키면서 numbers에 없는 i만 골라낸뒤 sum+=i했다고 생각하면 된다.

 

그런데 성능이 왜 이렇게 안 좋을까?

1. 2중 반복문을 돌린 것이나 마찬가지니까 당연히 더 느릴 수 밖에 없다.

2. 스트림은 오버헤드 때문에 같은 연산을 해도 시간복잡도가 작은 연산일 수록 기본 반복문보다 더더더 느리다

 

띠용~ 그러면 앞으로 스트림 쓰면 안되는 거 아냐?

쩝.. 스트림은 단순한 연산일수록 + 성능이 중요할수록 안 쓰면 좋은 건 맞다.

 

근데 반복문만 쓰던 사람이 스트림 못 쓰는 건 맞는데

스트림만 쓰던 사람이 반복문 못 쓰는 건 아니거든요.. 안 풀리면 바꾸면 그만이다.

 

어차피 코딩 테스트가 아닌 Real world에서는 그런 약간의 성능차이 때문에 굳이 반복문을 택하는 일은 거의 없다고 한다.

단순히 팀원들이 스트림을 잘 못 쓰거나 하는 경우가 아니라면..

 

 

 

 

 

 

 

1
2
3
4
5
6
7
8
import java.util.*;
import java.util.stream.*;
 
class Solution {
    public int solution(int[] numbers) {
    return 45 - Arrays.stream(numbers).sum();
    }
}
cs

 

아니면 애초에 0에서 9까지 더한 숫자인 45에서 배열을 빼는 방법도 있다. (이건 나도 보고 알았다)

기발한 방법이긴 하지만 범용적으로 쓰일 수 있는 방법이 아니므로 예능으로만 보자.