Coding Test/Programmers

[프로그래머스] Lv.2: n^2 배열 자르기 - java

찬 주 2023. 8. 10. 15:14

문제

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

 

프로그래머스

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

programmers.co.kr

 

접근법

문제를 처음에 봤을 때는 문제에서 요구하는 그대로 2차원 배열을 만들어서 하면 되겠다고 생각했지만, n의 범위가 최대 $10^7$ 이므로 2차원 배열을 생성하기엔 힘드니 규칙을 찾아야겠다고 생각했다. 규칙을 찾기 위해 문제를 그려보며 생각했다.

 

예제

입출력 예의 두번째를 한번 그려보자. 

n = 4, left = 7, right = 14

이 2차원 배열을 각 행씩 잘라서 붙이면 아래와 같고, 색칠한 부분을 구하면 된다.

다시 2차원 배열에 left ~ right 배열을 색칠해보자.

즉 우리는 arr[1][3] ~ arr[3][3]를 구해야 되는 것이다. 여기서 우리는 규칙을 찾을 수 있다.

left / n = 시작점의 행
left % n = 시작점의 열
right / n = 마지막점의 행
right % n = 마지막점의 열

 

이제 각 위치에서 갖는 값의 규칙을 찾으면 된다.

i번째 행에서 i번째 열까지는 전부 i 인 것을 쉽게 알 수 있다. (i + 1)열까지는 하나씩 증가해주면 된다. 간단하게 정리해보자.

[i][0] ~ [i][i] = i
[i][j] = i + (j - i), i < j

 

이제 코드를 작성하기만 하면 된다. 코드로 바꾸는 과정이 약간 어려웠던 것 같다. 아래 내 코드를 보지 말고 먼저 작성해보는 것을 추천한다!

 

코드

class Solution {
    public int[] solution(int n, long left, long right) {
        // 시작, 끝 행과 열 계산
        int startR = (int) (left / n);
        int startC = (int) (left % n);
        int endR = (int) (right / n);
        int endC = (int) (right % n);
        
        int length = (endR - startR + 1) * n - (startC + n - endC - 1); // 자른 배열의 길이
        int[] answer = new int[length];
        int idx = 0;
        
        while (idx < length) {
            int c = startC % n;
            
            if (c <= startR) {
                answer[idx++] = startR + 1;
            } else {
                answer[idx++] = startR + (c - startR) + 1;
            }
            
            if (++startC % n == 0) {
                startR++;
            }
        }
        
        return answer;
    }
}