코딩테스트
[ 프로그래머스 ] n^2 배열자르기
Adose
2025. 2. 4. 16:36
📘요구 사항 정리
- 정수 n, left, right 가 주어진다. 아래의 과정대로 만들어진 1차원 배열을 return하도록 한다.
- n행 n열 크기의 비어있는 2차원 배열을 만든다.
- i = 1, 2, 3, … n 번 반복한다.
- 1행 1열부터, i행 i열까지의 영역 내의 모든 빈 칸을 숫자 i로 채운다.
- 1행, 2행, …n행을 잘라내어 모두 이어붙인 새로운 1차원 배열을 만든다.
- 새로운 1차원 배열을 arr이라고 할때, arr[left] , arr[left +1 ] … arr[right] 만 남기고 나머지는 모두 지운다.
- 완성된 배열을 return 한다.
📌 제약 조건
- 1 ≤ n ≤ 10^7
- 0 ≤ left ≤ right < n^2
- right - left < 10^5
📌 문제 분석 첫 번째 (실패)
🔥 처음 틀린 분석
⇒ 어림도 없지 ,,문제 분석 다 틀림
- 배열 하나에 n 만큼 i 로 채운다
- 예를들어 n =3 , i = 1 일때
- arr[0] = 1, arr[1] =1, arr[2] = 1
- arr[3 ] = 2 , arr[4] = 2, arr[5 ] = 2
- 이런식으로 n 만큼 i 숫자를 채우고, 다음 n 만큼 i+1 이런식으로 값을 채워준다.
- 그렇게 만든 배열을 arr[left] - arr[right] 이렇게 나눠주면 되지 않을까?
📌 문제 분석 두 번째 (성공)
- 1… n → k 라고 정했다.
- 행은 k+1 순서로 증가 한다.
- 첫 번째 행 1 , 2 , 3 k =1
- 두 번째 행 2, 2, 3 k=2
- 세 번째 행 3, 3, 3 k=3
- 결과적으로 k 열까지는 k값이 채워지고, 그 뒤부터는 k+1 씩 증가한다는걸 알 수 있다.
- 만약 해당되는 index 값을 알게 된다면 ?
- (2, 3) 이면 2행 3열, 2를 포함하면서 3세번째 자리이다.
- (x, y)라고 한다면 , x ≤ y인 상황이기 때문에 2를 포함한다고 할 수 있다.
- 식으로는 x + (y-x) 이렇게 되면
- (x, y)의 위치로 값을 알 수 있다.
- 결과적으로 left, right index 값만 알게 된다면, left right만으로 배열을 만들 수 있다.
- 또한 (x, y) 좌표 값으로 해당되는 index의 값이 무엇인지도 구할 수 있다.
- 2차원 배열에서 n=3 일때 길이는 9이다. → 그럼 1차원 배열은 0 ~8로 이루어진걸 알 수 있다.
- 그럼 0~8로 이루어진 index 값을 3으로 나눈다면 나올 수 있는 몫 나머지는 0~2 이다.
- left index 번호로 x, y값을 구한다
- left 에서 right까지 각각의 x,y값을 구한 후 그 x ,y 값에서 답을 배출한다.
- 배출한 값은 배열에 넣어준 후 return
- 배열을 선언할때 처음에는 int [] 문으로 했는데, left ~ right 사이의 값을 구하려면 left가 0부터 시작하는게 아니므로 [] → List로 수정했다.
📌 구현코드
public static int [] solution(long n, long left, long right){
// int [] arr = new int [(right-left)+1];
ArrayList<Integer> arr = new ArrayList<>();
//left의 좌표를 구해보자
long count = (right-left)+1; //return 해야할 값 개수
for(long i=left;i<=right;i++){
int x = (int)(i/n)+1; //행
int y = (int)(i%n)+1; //열
if(x >= y){
// arr[i] = x;
arr.add(x);
}else{
// arr[i] = x+(y-x);
arr.add(x+(y-x));
}
}
return arr.stream().mapToInt(Integer::intValue).toArray();
}
📌 구현코드 해설
- i/n, i%n 는 각 x, y 값을 구할 수 있다.
- 2차원 배열에서 n=3 일때 길이는 9이다. → 그럼 1차원 배열은 0 ~8로 이루어진걸 알 수 있다.
- 그럼 0~8로 이루어진 index 값을 3으로 나눈다면 나올 수 있는 몫 나머지는 0~2에서 나온다
- 예를들어 5번째 index의 좌표는 ? ⇒ 몫 1, 나머지 2 인걸 알 수 있다.
- 하지만 우리는 n이 1부터 시작하기 때문에 나온 값들에 +1 씩을 해주어야 한다.
- 아니면 수식을 구한 후에 +1을 해주어도 무관하다.
- 2차원 배열에서 n=3 일때 길이는 9이다. → 그럼 1차원 배열은 0 ~8로 이루어진걸 알 수 있다.
- 만약 y가 x보다 작은 경우라면, x의 값이 들어가야 한다.
- 예를들어 2행 1열 ,2 열 → 2가 들어가야 함 , 3부터는 2행 +1 → 3이 들어가야 한다.
- 만약 y가 x보다 큰 경우라면, 식 x + (y -x )를 사용하면된다.
- 여기서 좀 곰곰히 생각해본게 어차피 y값이 들어가는거 아닌가 ? 굳이 식을 써야 하나 ?
- x + (y -x ) = max(x,y) 아닌가 ? → 오 이거 맞네 다시 해봐야겠다
- for(long i=left;i<=right;i++) 문을 사용하여 left 부터 right까지 x,y값을 구하고 arr에 넣고 return 해주었다.