[Java] 콜라츠 수열 만들기

peace w·2023년 10월 8일
0

프로그래머스

목록 보기
22/25
post-thumbnail

문제

  • 모든 자연수 x에 대해서 현재 값이 x이면 x가 짝수일 때는 2로 나누고, x가 홀수일 때는 3 * x + 1로 바꾸는 계산을 계속해서 반복하면 언젠가는 반드시 x가 1이 되는지 묻는 문제를 콜라츠 문제라고 부릅니다.

  • 그리고 위 과정에서 거쳐간 모든 수를 기록한 수열을 콜라츠 수열이라고 부릅니다.

  • 계산 결과 1,000 보다 작거나 같은 수에 대해서는 전부 언젠가 1에 도달한다는 것이 알려져 있습니다.

  • 임의의 1,000 보다 작거나 같은 양의 정수 n이 주어질 때 초기값이 n인 콜라츠 수열을 return 하는 solution 함수를 완성해 주세요.

  • 제한사항

    • 1 ≤ n ≤ 1,000

입출력 예

문제 풀이

  • ArrayList를 사용하여 수를 추가했다.
  • 몇 번 반복할지 알 수 없으니 while을 사용하여 n이 1이 아니라는 조건을 만족하기까지 반복했다.
  • n이 짝수면 n 을 2로 나눈 값을, n이 홀수면 n 에 3 을 곱하고 1을 더한 값을 추가했다.
  • Stream, toArray를 이용해서 integer 타입의 리스트를 int 배열로 바꾸어 반환했다.
import java.util.ArrayList;

class Solution {
    public int[] solution(int n) {
        ArrayList<Integer> answer = new ArrayList<>();
        answer.add(n);
        while (n != 1) { // n이 1이 아닌 동안
            if (n % 2 == 0) { // n이 짝수면
                n /= 2;
            } else { // n이 홀수면
                n = 3 * n + 1;
            }
            answer.add(n);
        }
        return answer.stream().mapToInt(i->i).toArray();
    }
}

다른 사람의 코드를 참고 해서 ArrayList를 쓰지 않고도 작성해보았다.

class Solution {
   public int[] solution(int n) {
       String str = n + " ";
       while (n != 1) { // n이 1이 아닌 동안
           n = n % 2 == 0 ? n / 2 : 3 * n + 1;
           str += n + " ";
       }
       String[] arr = str.split(" ");
       int[] answer = new int[arr.length];
       for(int i=0; i<answer.length; i++){
           answer[i] = Integer.parseInt(arr[i]);
       }
       return answer;
   }
}

두 코드가 실행시간에서 확연한 차이를 보였다. ArrayList를 사용하는 것이 모든 케이스에서 10ms정도 빠른 속도를 보여줬다.


📢 ArrayList<Integer> 를 int 배열로 바꾸는 법

방법 1.

int[] arr1 = new int[list.size()];
for (int i = 0 ; i < list.size() ; i++ ) {
	arr1[i] = list.get(i).intValue();
}
  

가장 기본적인 방법이다. 반복문을 통해 각 요소별로 접근한다.

  1. list의 사이즈를 int 형의 배열 arr 의 길이로 설정하여 선언한다.
  2. list의 사이즈만큼 반복문을 돌면서, arr의 i 번째에 list의 i번째를 intValue()를 통해 int형으로 변환해주고 대입한다.

방법 2.

int[] arr2 = list.stream()
			.mapToInt(i -> i)
            .toArray();

방법 3.

int[] arr3 = list.stream()
			.mapToInt(Integer :: intValue)
            .toArray()

방법 2와 3은 list를 stream으로 변환 후, map을 이용해서 intStream을 가져오고, 그 후에 toArray()를 통해 배열로 만드는 방법이다.

두 방법의 차이는 map 연산 시 int형으로 변경하는 방법의 차이이다.
방법 2 : 자바가 자동으로 각 요소의 Integer 요소를 int형으로 unboxing 해준다. (java 5 이상)
방법 3 : intValue 메서드를 통해 각 요소를 int형으로 변경해준다.

방법 4.

int[] arr4 = list.stream()
				.filter(i -> i != null)
                .mapToInt(i -> i)
                .toArray();

방법 2에 필터를 추가한 것이다. 필터를 통해 null인 요소를 걸러내는 방법이다.


참고
[Java] Integer ArrayList을 int 배열로 변환 방법

profile
더 성장하자.

0개의 댓글