코드 그라데이션

[Lv.0] 콜라츠 수열 만들기 본문

Java/알고리즘

[Lv.0] 콜라츠 수열 만들기

완벽한 장면 2023. 7. 3. 23:14

https://school.programmers.co.kr/learn/courses/30/lessons/181919

 

프로그래머스

코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

programmers.co.kr

 

문제 설명

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

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

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

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

 

제한 사항

 

입출력 예

 

입출력 예 설명

 

 

아이디어

현재 x // 짝수-> x/2 , 홀수 x->3*x+1 ====> 1

 

  • 배열 만들어서 반환해야 할 것 같다는 생각
  • 그런데 상황에 따라 크기는 달라질 수 있으므로 배열은 쓸 수 없다. 리스트를 쓰는 게 적절.

초기 코드

import java.util.*;
class Solution {
    public int[] solution(int n) {
    
        int a =0;
            if(n%2 ==0) {
                n = n/2;
            }
            else {
                n = 3*n+1;
            }
        List<Integer> abc = new ArrayList<>();
        for(int i = 0; i<abc.size(); i++) {
            abc.add(a);
        }
        return answer;
    }
}

이건 문제가 있음.

이 코드에서는 연산이 한 번만 일어나고 끝. 의도는 1이 될 때까지 계속해서 연산이 일어나야 함.

그리고 a를 안 쓰고 있음.

 

반복문도 필요할 것 같긴 한데, 1이 아닐 때까지 지속해야하므로 for문보다는 while문이 적합.

 

수정한 코드

import java.util.*;
class Solution {
    public int[] solution(int n) {
    
        int a =0;
        while(n != 1) {
            if(n%2 ==0) {
                n = n/2;
            }
            else {
                n = 3*n+1;
            }
        }    
        List<Integer> abc = new ArrayList<>();
        for(int i = 0; i<abc.size(); i++) {
            abc.add(a);
        }
        return answer;
    }
}

지금 보면 여기서는 a가 계속 업데이트만 되고 있음.

그 값을 저장하고, 다시 연산에 투입이 되어야 하는데...

연산의 결과를 위에서 추가해주면 된다!!!

 

즉, ArrayList를 위에서 만들고,

연산결과를 바로바로 추가할 수 있게 만들면 됨.

반복문도 굳이 돌릴 필요 없이 그때그때 추가해주면 되니까.

 

그리고 연산 결과를 다시 n에 넣어야, 원하는 흐름으로 간다.

 

그리고 억지로... LIST에 있는 것을 배열에 다시 담아 반환하는 과정이 굳이 필요하다(정답 맞추기 위함)

리스트에서 원소 끌어오려면 get() 메서드 사용.

 

수정한 코드

import java.util.*;
class Solution {
    public int[] solution(int n) {
        
        List<Integer> abc = new ArrayList<>();
        while(n!=1) {
            if(n%2 ==0) {
                n = n/2;
                abc.add(n);
            }
            else {
                n = 3*n+1;
                abc.add(n);
            }
        }
        int[] answer = new int[abc.size()];
        for(int i = 0; i<abc.size(); i++) {
            answer[i] = abc.get(i);
        }
        return answer;
    }
}

 

그런데 문제가 여기서 초깃값이 반영(추가)이 안 되게 나옴.

그럼 반복문 타기 전에 초기값을 미리 넣어주고 들어가면 된다.

나의 코드

import java.util.*;
class Solution {
    public int[] solution(int n) {
        
        List<Integer> abc = new ArrayList<>();

        abc.add(n); // 요기 이렇게
        while(n!=1) {
            if(n%2 ==0) {
                n = n/2;
                abc.add(n);
            }
            else {
                n = 3*n+1;
                abc.add(n);
            }
        }
        int[] answer = new int[abc.size()];
        for(int i = 0; i<abc.size(); i++) {
            answer[i] = abc.get(i);
        }
        return answer;
    }
}
// 현재 x // 짝수-> x/2 , 홀수 x->3*x+1 ====> 1
728x90

'Java > 알고리즘' 카테고리의 다른 글

[Lv.0] 마지막 두 원소  (0) 2023.07.10
[Lv.0] 주사위 게임 1  (0) 2023.07.06
[Lv.0] 조건 문자열  (0) 2023.06.28
[Lv.0] 수열과 구간 쿼리  (0) 2023.06.24
[Lv.0] 자릿수 더하기  (0) 2023.06.21
Comments