코딩테스트/프로그래머스

배열 만들기 2 ~ 카운트업

구너드 2023. 6. 2. 19:03

l 과 r 사이에 0과 5로만 이루어진 정수를 오름차순으로 저장한 배열을 return하는 문제

문제를 처음 봤을 때, r부터 시작해서 l로끝나는 숫자들을 추출하는 반복문, 그리고 조건식을 사용해야겠다고 접근하였다. 문제는 어떻게 조건식을 작성하여 l과 r사이의 숫자를 판별할 것인지인데, 조금 생각해보니까 5로 나누어서 나머지가 0인 숫자들만 추출하면 구할 수 있을 것 같았다. 

위의 기본 논리를 바탕으로 코드를 작성해보면,

 

        for(int i = l, i <= r; i++) {
            if(i % 5 == 0) {
                
            }
        }
        return answer;

이렇게 뼈대를 잡을 수 있다.

문제는 answer의 배열인데, l과 r의 크기에 따라 answer배열의 크기는 가변적으로 바뀔 수 있으므로, 이 부분에서 ArrayList를 사용해야겠다는 생각이 들었다.

 

import java.util.*;

class Solution {
    public int[] solution(int l, int r) {
        ArrayList answer = new ArrayList();
        
        for(int i = l; i <= r; i++) {
            if(i % 5 == 0) {
                answer.add(i);
            }
        }
        return answer;
    }
}

코드를 작성하고 보니 이상한 부분이 생각났다. l과 r 사이에 15라는 정수가 있다면, 이는 0과 5로 이루어지지 않았음에도 불구하고, 5의 배수로 판별되어 answer에 추가될 것이다.

 

        for(int i = l; i <= r; i++) {
            if(i % 5 == 0 && i % 10 == 0) {
                answer.add(i);
            }
        }

이처럼 5와 10의 공배수들을 가지고 작성하려고 했으나, 이러면 순전히 5로 이루어진 숫자들은 추출되지 못한다. 즉 50,550과 같은 숫자들은 추출할 수 있는 반면, 505,555와 같은 숫자들은 추출할 수 없다.

이를 해결하기 위해 잠시동안 머리를 굴려봤는데, 쉽게 답을 찾을 수는 없었다. 

문제를 구글링 해본 결과 코드는 생각보다 복잡했음을 알았다.

 

https://velog.io/@superscman/%EB%B0%B0%EC%97%B4-%EB%A7%8C%EB%93%A4%EA%B8%B02-%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4%EC%9E%90%EB%B0%94

 

배열 만들기2 - 프로그래머스(자바)

예전에 3의 저주인가 하는 문제의 해결법이라고 생각한다. 검증해야 되는 횟수만큼 순회하는 반복문을 만든뒤 String str을 i를 타입변환해서 선언, 그리고 검증에 필요한 int count를 0을 초기화해준

velog.io

import java.util.*;

class Solution {
    public int[] solution(int l, int r) {
        List<Integer> list = new ArrayList<>();
        for(int i = l; i<=r; i++) {
            String str = i + "";
            int count = 0;
            for(int j = 0; j < str.length(); j++) {
                if(str.charAt(j) == 48 || str.charAt(j) == 53) {
                    count ++;
                }
            }
            if(count == str.length()) {
                list.add(i);
            }
        }
        int[] answer = list.stream().mapToInt(i->i).toArray();
        int[] empty = {-1};
        if(answer.length == 0) return empty;
        return answer;
    }
}
  • 검증해야 되는 횟수만큼 순회하는 반복문을 만든뒤 String str을 i를 타입변환해서 선언, 그리고 검증에 필요한 int count를 0을 초기화해준다.
    • 반복문 안에 반복문을 한번 더 도는데 첫 번째 반복문 안에 들어오는 str의 length()만큼 순회하면서 str의 char가 0이나 5면 카운트가 올라가게 만들어준다.
    • 그리고 카운트가 str의 length()와 같으면 그것은 검증에 성공한것이므로 list안에 담아준다.
  • 담은 리스트를 배열로 바꾸어 리턴하면 정답이다.
  • 하지만 아무것도 없을 경우가 있는데 그때는 answer의 길이가 0일 경우이니 조건문을 걸어 -1이 담긴 배열을 반환한다.

완벽하게 이해하기는 어려웠지만, i를 String str로 바꿔준 후, str의 길이만큼 반복하는 j가 아스키 코드의 0과 5를 뜻하는 48과 53이라면 0으로 초기화 해준 count 변수에 ++연산을 시행한다.

이후 시행한 count의 값과 str의 길이가 같다면 answer에 저장한다.

만약 answer의 길이가 0이라면 -1을 반환한다

 

꽤 복잡한 코드라고 느꼈다.


앞선 문제와 비교해서 굉장히 쉬운 문제라고 느꼈다. 반복문을 통해 answer에 i를 추가해주는 방식으로 접근했다.

이번에도 answer의 크기는 가변적이므로 ArrayList를 사용했다.

 

import java.util.*;

class Solution {
    public List solution(int start, int end) {
        List answer = new ArrayList<>();
        for(int i = start; i<=end;i++){
            answer.add(i);
        }
        return answer;
    }
}

 

import java.util.stream.IntStream;

class Solution {
    public int[] solution(int start, int end) {
        return IntStream.rangeClosed(start, end).toArray();
    }
}

다른 사람의 풀이에선 Stream을 사용했는데, Stream에 대해서는 곧 배울테니 일단은 패스.