[1,2차원 배열 탐색][JS] 봉우리

Teasan·2022년 6월 24일
0

Algorythm

목록 보기
3/17
post-thumbnail

봉우리


문제 설명

지도 정보가 NxN 격자판에 주어집니다. 각 격자에는 그 지역의 높이가 쓰여있습니다. 각 격자 판의 숫자 중 자신의 상하좌우 숫자보다 큰 숫자는 봉우리 지역입니다. 봉우리 지역이 몇 개 있는 지 알아내는 프로그램을 작성하세요.
격자의 가장자리는 0으로 초기화 되었다고 가정한다.
만약 N=5 이고, 격자판의 숫자가 다음과 같다면 봉우리의 개수는 10개입니다.

제한 사항

없음

입력 설명

첫 줄에 자연수 N이 주어진다.(1<=N<=50)
두 번째 줄부터 N줄에 걸쳐 각 줄에 N개의 자연수가 주어진다. 각 자연수는 100을 넘지 않는 다.

출력 설명

봉우리의 개수를 출력하세요.

입출력 예제

▣ 입력예제 1

  • 53723
  • 37161
  • 72534
  • 43641
  • 87352

▣ 출력예제 1

  • 10

해답/풀이

function solution(arr) {
  let answer = 0;
  let n = arr.length;
  let dx = [-1, 0, 1, 0];
  let dy = [0, 1, 0, -1];
  for (let i = 0; i < n; i++) {
    for (let j = 0; j < n; j++) {
      let flag = 1;
      for (let k = 0; k < 4; k++) {
        let nx = i + dx[k];
        let ny = j + dy[k];
        if (
          nx >= 0 &&
          nx < n &&
          ny >= 0 &&
          ny < n &&
          arr[nx][ny] >= arr[i][j]
        ) {
          flag = 0;
          break;
        }
      }
      if (flag) answer++;
    }
  }

  return answer;
}

let arr = [
  [5, 3, 7, 2, 3],
  [3, 7, 1, 6, 1],
  [7, 2, 5, 3, 4],
  [4, 3, 6, 4, 1],
  [8, 7, 3, 5, 2],
];
console.log(solution(arr));

출력

  • 10

수도 코드

function solution(arr) {
  // 0. n*n 격자판 배열 arr를 매개변수로 받는다.
  let answer = 0;

  // 2. x 좌표를 기준으로 이동할 행의 움직임(위, 오, 아래, 왼)을 `x` 배열로 초기화한다.
  let x = [-1, 0, 1, 0];
  // 3. y 좌표를 기준으로 이동할 열의 움직임(위, 오, 아래, 왼)을 'y' 배열로 초기화한다.
  let y = [0, 1, 0, -1];

  // 4. 배열 arr 안의 요소 배열을 탐색하기 위해 이중 for 문을 작성한다.
  for (let i = 0; i < arr.length; i++) {
    for (let j = 0; j < arr.length; j++) {
      // 5. 봉우리를 체크할 flag 변수를 1로 초기화해준다. 1은 true가 된다.
      let flag = 1;

      // 6. 행[i]과 열[j]을 기준으로 행과 열을 이동시키기 위해 for 문을 작성한다.
      for (let k = 0; k < 4; k++) {
        // 7. 행 : 위-우-아래-좌 를 도는 4번 만큼 i를 기준으로 이동([-1, 0, 1, 0])한다.
        let nx = i + x[k];
        // 8. 열 : 위-우-아래-좌 를 도는 4번 만큼 j를 기준으로 이동([0, 1, 0, -1])한다.
        let ny = j + y[k];

        // 9. 봉우리가 아닌 경우를 체크하는 if 문을 작성한다.
        if (
          // 10.1 격자의 가장자리는 0으로 초기화 되었기 때문에 행의 위치 index인 `nx`와 열의 위치 index인 `ny`은 index 0번째와 같거나(격자의 가장자리) 커야 한다.
          nx >= 0 &&
          // 10.2 행의 위치 index인 `nx`와 열의 위치 index인 `ny`은 `arr.length` 보다는 작아야 하기 때문에 `if`문에 `&&` 연산자로 체크해줄 수 있도록 한다.
          nx < arr.length &&
          ny >= 0 &&
          ny < arr.length &&
          arr[nx][ny] >= arr[i][j]
        ) {
          // 11. 봉우리를 체크해줄 `flag`는 0으로 값을 할당하여 false로 만들고,
          flag = 0;

          // 12. 봉우리가 아님을 확인했을 때 남은 반복문이 멈추도록 `break`를 달아준다.
          break;
        }
      }
      // 13. 네 방향을 돌며 봉우리인지를 체크하는 `for` 반복문 바깥에 `if` 문을 달아 만약 `flag`가 true 라면, 봉우리 갯수를 카운트하는 `answer`를 1씩 더해줄 수 있도록 한다.
      if (flag) answer++;
    }
  }
  // 14. 최종적으로 누적한 봉우리의 값 answer를 반환한다.
  return answer;
}

let arr = [
  [5, 3, 7, 2, 3],
  [3, 7, 1, 6, 1],
  [7, 2, 5, 3, 4],
  [4, 3, 6, 4, 1],
  [8, 7, 3, 5, 2],
];
console.log(solution(arr)); // 10

풀이 순서

function solution(arr) {
  let answer = 0;

  return answer;
}
  • 먼저, 봉우리 갯수를 count 하도록 answer 값을 0으로 초기화 한다.
function solution(arr) {
  let answer = 0;

  let n = arr.length;
  let x = [-1, 0, 1, 0];
  let y = [0, 1, 0, -1];

  return answer;
}
  • arr.length를 변수 n으로 선언하고,
  • 어떤 좌표를 기준으로 이동할 행의 움직임(위, 오, 아래, 왼)을 x 배열로 초기화해준다.
  • 어떤 좌표를 기준으로 이동할 열의 움직임(위, 오, 아래, 왼)을 y 배열로 초기화해준다.
function solution(arr) {
  let answer = 0;

  let n = arr.length;
  let x = [-1, 0, 1, 0];
  let y = [0, 1, 0, -1];

  for (let i = 0; i < n; i++) {
    for (let j = 0; j < n; j++) {}
  }

  return answer;
}
  • 2차원 배열을 탐색하기 위해 2중으로 for 문을 작성한다.
function solution(arr) {
  let answer = 0;

  let n = arr.length;
  let x = [-1, 0, 1, 0];
  let y = [0, 1, 0, -1];

  for (let i = 0; i < n; i++) {
    for (let j = 0; j < n; j++) {
      let flag = 1;
    }
  }

  return answer;
}
  • 봉우리를 체크할 flag 변수를 1(true)로 초기화 해준다.
function solution(arr) {
  let answer = 0;

  let n = arr.length;
  let x = [-1, 0, 1, 0];
  let y = [0, 1, 0, -1];

  for (let i = 0; i < n; i++) {
    for (let j = 0; j < n; j++) {
      let flag = 1;

      for (let k = 0; k < 4; k++) {
        let nx = i + x[k];
        let ny = j + y[k];
      }
    }
  }

  return answer;
}
  • 행과 열의 방향 이동을 위한 for 문을 작성한다.
  • 해당 for 문은 4개의 방향만큼 돌아야 하기 때문에, 0을 기준으로 3까지(4개) 돌 수 있도록 k < 4 로 설정한다.
  • for 문 내부에서 행(i) 좌표가 가려고 하는 방향을 구해주기 위해 행(i) 좌표에 행 좌표 배열인 x의 배열을 k 만큼 반복하는 값을 더해준 nx 를 선언한다.
  • for 문 내부에서 열(j) 좌표가 가려고 하는 방향을 구해주기 위해 열(j) 좌표에 열 좌표 배열인 y의 배열을 k 만큼 반복해서 값을 더해준 ny 를 선언한다.
function solution(arr) {
  let answer = 0;

  let n = arr.length;
  let x = [-1, 0, 1, 0];
  let y = [0, 1, 0, -1];

  for (let i = 0; i < n; i++) {
    for (let j = 0; j < n; j++) {
      let flag = 1;

      for (let k = 0; k < 4; k++) {
        let nx = i + x[k];
        let ny = j + y[k];
        if (arr[nx][ny] >= arr[i][j]) {
        }
      }
    }
  }

  return answer;
}
  • 기준이 될 지점인 arr[i][j]가 봉우리가 아닐 때의 if 문을 작성해준다. 행과 열이 이동하려고 하는 방향 지점인 arr[nx][ny]가 기준이 될 지점인 arr[i][j] 보다 크다면 이 기준이 되는 지점은 봉우리가 아닐 것이다. 이것을 체크하는 값(arr[nx][ny] >= arr[i][j])을 적어준다.
function solution(arr) {
  let answer = 0;

  let n = arr.length;
  let x = [-1, 0, 1, 0];
  let y = [0, 1, 0, -1];

  for (let i = 0; i < n; i++) {
    for (let j = 0; j < n; j++) {
      let flag = 1;

      for (let k = 0; k < 4; k++) {
        let nx = i + x[k];
        let ny = j + y[k];
        if (
          nx >= 0 &&
          nx < n &&
          ny >= 0 &&
          ny < n &&
          arr[nx][ny] >= arr[i][j]
        ) {
        }
      }
    }
  }

  return answer; 
}
  • 격자의 가장자리는 0으로 초기화 되었기 때문에 행의 위치 index인 nx와 열의 위치 index인 ny은 index 0번째와 같거나(격자의 가장자리) 커야 하고, n 보다는 작아야 하기 때문에 if문에 && 연산자로 체크해줄 수 있도록 한다.
function solution(arr) {
  let answer = 0;

  let n = arr.length;
  let x = [-1, 0, 1, 0];
  let y = [0, 1, 0, -1];

  for (let i = 0; i < n; i++) {
    for (let j = 0; j < n; j++) {
      let flag = 1;

      for (let k = 0; k < 4; k++) {
        let nx = i + x[k];
        let ny = j + y[k];
        if (
          nx >= 0 &&
          nx < n &&
          ny >= 0 &&
          ny < n &&
          arr[nx][ny] >= arr[i][j]
        ) {
          flag = 0;
          break;
        }
      }
    }
  }

  return answer; 
}
  • 기준이 될 지점이 만약 if 봉우리가 아니라면에 대한 값을 작성해준다.
  • 봉우리를 체크해줄 flag는 0으로 값을 할당하여 false로 만들고, 봉우리가 아님을 확인했을 때 남은 반복문이 멈추도록 break를 달아준다.
function solution(arr) {
  let answer = 0;

  let n = arr.length;
  let x = [-1, 0, 1, 0];
  let y = [0, 1, 0, -1];

  for (let i = 0; i < n; i++) {
    for (let j = 0; j < n; j++) {
      let flag = 1;

      for (let k = 0; k < 4; k++) {
        let nx = i + x[k];
        let ny = j + y[k];
        if (
          nx >= 0 &&
          nx < n &&
          ny >= 0 &&
          ny < n &&
          arr[nx][ny] >= arr[i][j]
        ) {
          flag = 0;
          break;
        }
      }
      if (flag) answer++;
    }
  }

  return answer;
}
  • 그리고, 4 방향을 돌며 봉우리인지를 체크하는 for 반복문 바깥에 if 문을 달아 만약 flag가 true 라면, 봉우리 갯수를 카운트하는 answer를 1씩 더해줄 수 있도록 한다.

⚡️ Reference


✍🏻 자바스크립트 알고리즘 문제풀이 - 인프런

profile
일단 공부가 '적성'에 맞는 개발자. 근성있습니다.

0개의 댓글