(*김태원님의 알고리즘 문제 풀이(JAVA)를 수강하면서 공부 중이다.)
N*N격자에서 어떤 수와 그 수의 상하좌우에 있는 수를 비교했을때, 가운데 위치한 수가 제일 큰 경우가 몇 번인지 횟수를 세는 프로그램을 짜보았다.
아래는 강의를 보기 전 직접 구현한 코드의 일부이다.
public int solution(int n, int[][] arr){
int cnt=0; //봉우리 개수를 세는 변수 선언
for(int i=1; i<=n; i++){
for(int j=1; j<=n; j++){
int[] maxArr={arr[i+1][j], arr[i-1][j], arr[i][j+1], arr[i][j-1]}; //상하좌우의 수를 배열에 저장
Arrays.sort(maxArr); //오름차순으로 정렬
int maxNum=maxArr[maxArr.length-1]; //가장 큰수를 변수에 저장
if(arr[i][j]>maxNum){ //중간의 수와 상하좌우의 수 중 가장 큰수를 비교
cnt++;
}
}
}
return cnt;
}
문제에서 예를들어 2*2격자가 주어질 때, 아래 그림처럼 그 격자의 가장자리가 0으로 초기화 되어있는걸로 치자고 하길래,
문득 '만약 가장자리를 만들지 않고 N*N격자만 입력받았을때, 'out of range'오류가 안 나게 하려면 어떻게 해야할까?🤨'라는 생각이 들어 구현 방법을 한참 고민해봤다.
결론은 마땅한 방법이 생각이 안나서 그냥 2차원 배열을 arr[N+2][N+2]로 선언해버렸다.
↓↓↓ (가장자리도 다 만들어버리기~)
int[][] arr=new int[n+2][n+2];
for(int i=1; i<=n; i++){
for(int j=1; j<=n; j++){
arr[i][j]=kb.nextInt();
}
근데 알고보니 조건 연산자로 아래와 같이 조건을 걸면 가장자리를 만들지 않고서도 상하좌우의 수를 비교할 때 'out of range'오류가 안 나게할 수 있었다. 🫠
if(row>=0 && row<N && column>=0 && column<N && arr[row][column])
그리고 필자의 코드를 보면 알겠지만, 필자는 배열을 선언해서 상하좌우의 수를 다 저장하고, 그걸 다시 sort()메서드로 정렬해서 가장 큰 수를 뽑아 중간에 있는 수랑 비교하는 방법을 택했다.
(주변 수를 가운데 수와 하나씩 비교하다가, 주변에 있는 어떤 수가 가운데 위치한 수보다 클 때 반복문을 탈출하는 방법도 있다.)
int[] maxArr={arr[i+1][j], arr[i-1][j], arr[i][j+1], arr[i][j-1]}; //상하좌우의 수를 배열에 저장
Arrays.sort(maxArr); //오름차순으로 정렬
int maxNum=maxArr[maxArr.length-1]; //가장 큰수를 변수에 저장
if(arr[i][j]>maxNum){ //중간의 수와 상하좌우의 수 중 가장 큰수를 비교
cnt++;
}
추가로 강의를 보면서 위의 방법 말고도 상하좌우의 수를 비교할 수 있는 새로운 방법을 배울 수 있었다.
int[] dx={-1, 0, 1, 0}; //12시, 3시, 6시, 9시 순서로 행을 지정하기 위한 배열
int[] dy={0, 1, 0, -1}; //12시, 3시, 6시, 9시 순서로 열을 지정하기 위한 배열
for(int i=0; i<n; i++){
for(int j=0; j<n; j++){
for(int k=0; k<4; k++){
int nx=i+dx[k]; //행
int ny=j+dy[k]; //열
}
}
}
3중 for문이라 좀 헷갈릴 수 도 있지만 몹시 흥미로웠다.
'프로그래밍 > JAVA 프로그래밍' 카테고리의 다른 글
[코딩연습_JAVA] 올바른 괄호 (0) | 2024.02.17 |
---|---|
[코딩연습_JAVA] K번째 큰 수 (0) | 2024.02.14 |
[코딩연습_JAVA] 학급 회장(Hash) (24.02.12) (0) | 2024.02.13 |
[코딩연습_JAVA] 연속 부분수열 (1) | 2024.02.06 |
[코딩연습_JAVA] 격자판 최대합 구하기 (1) | 2024.01.31 |