프로그래머스 Level2 - 삼각달팽이

2023. 7. 18. 18:05·알고리즘

문제 풀이1 - 2차원 배열에 값을 담기

해당 문제에서는 삼각형을 표현 해야하는데, 이는 n x n의 2차원 배열로 표현할 수 있습니다.

달팽이 형태를 채우는것은 2차원 배열에서 아래 → 오른쪽 → 왼쪽으로 진행하면서 값을 채워나가게 됩니다.

문제풀이 흐름

  1. n x n 2차원 배열을 선언한다.
  2. 현재 위치 (0,0) 에서부터 방향에 따라 이동할 수 없을 때까지 숫자를 채운다.
  3. 아래로 이동 → 오른쪽으로 이동 → 왼쪽위로 이동
  4. 채워진 숫자를 차례대로 1차원 배열에 옮겨서 반환한다.

1. n x n 2차원 배열 선언

int[][] triangle = new int[n][n];
int v = 1;

v변수는 채워넣은 값으로 1씩 증가할 값입니다.

2. 현재위치를 (0, 0)으로 초기화

int x = 0;
int y = 0;

3. 방향에 따라 이동할 수 없을때까지 숫자 채우기

while(true) {
    //아래

    //오른쪽

    //왼쪽위
}
  1. 아래로 이동
    while (true) {
                triangle[y][x] = v++;
                if( y + 1 == n || triangle[y + 1][x] != 0) break;
                y += 1;
            }
    if (x + 1 == n || triangle[y][x + 1] != 0) break;
    x += 1;
  2. 오른쪽으로 이동
    while (true) {
                    triangle[y][x] = v++;
                    if(triangle[y - 1][x - 1] != 0) break;
                    x -= 1;
                    y -= 1;
                }
                if (y + 1 == n || triangle[y + 1][x] != 0) break;
                y += 1;
  3. 왼쪽위로 이동
    while (true) {
                triangle[y][x] = v++;
                if(triangle[y - 1][x - 1] != 0) break;
                x -= 1;
                y -= 1;
            }
            if (y + 1 == n || triangle[y + 1][x] != 0) break;
            y += 1;

4. 채워진 숫자를 1차원 배열에 옮겨 반환

int[] result = new int[v - 1];
int index = 0;
for(int i = 0; i < n; i++) {
   for (int j = 0; j <= i; j++) {
       result[index++] = triangle[i][j];
       }
   }

전체코드

class Solution {
    public int[] solution(int n) {
        int[][] triangle = new int[n][n];
        int v = 1;
        int x = 0;
        int y = 0;

        while(true) {

            //아래
            while (true) {
                triangle[y][x] = v++;
                if( y + 1 == n || triangle[y + 1][x] != 0) break;
                y += 1;
            }
            if (x + 1 == n || triangle[y][x + 1] != 0) break;
            x += 1;

            //오른쪽
            while (true) {
                triangle[y][x] = v++;
                if (x + 1 == n || triangle[y][x + 1] != 0) break;
                x += 1;
            }
            if (triangle[y - 1][x - 1] != 0) break;
            x -= 1;
            y -= 1;
            //왼쪽위
            while (true) {
                triangle[y][x] = v++;
                if(triangle[y - 1][x - 1] != 0) break;
                x -= 1;
                y -= 1;
            }
            if (y + 1 == n || triangle[y + 1][x] != 0) break;
            y += 1;

        }
        int[] result = new int[v - 1];
            int index = 0;
            for(int i = 0; i < n; i++) {
                for (int j = 0; j <= i; j++) {
                    result[index++] = triangle[i][j];
                }
            }
        return result;
    }
}

문제풀이2 - dx, dy로 방향 정하기

dx와 dy는 x의 변화량과 y의 변화량을 의미합니다.

특정방향으로 이동할때, 해당 좌표값이 어떻게 변화하는지에 대한것을 중심으로 알아봅시다.

특정 좌표 (x, y) 가 있을 때, 상하좌우의 움직임에 따른 좌표의 변화량은 다음과 같습니다.

  상 하 좌 우
dx 0 0 -1 1
dy -1 1 0 0

해당 값을 배열에 담아서 dx, dy 변수를 생성해 줍니다.

private static final int[] dx = {0, 0, -1, 1};
private static final int[] dy = {-1, 1, 0, 0};

이동에 따른 값의 변화량을 배열에 옮겻으니 해당 배열의 인덱스가 방향이 됩니다.

인덱스 0은 상, 1은 하, 2는 좌, 3은 우 방향이 되지요.

1. 변화량 상수 생성

해당 문제에서는 3개의 방향을 사용합니다. 아래, 오른쪽 왼쪽 위

  아래 오른쪽 왼쪽 위
dx 0 1 -1
dy 1 0 -1

이를 배열에 담아서 변수로 나타내 봅시다.

private static final int[] dx = {0, 1, -1};
private static final int[] dy = {1, 0, -1};

2. 방향 변수 생성

int x = 0; //x좌표
int y = 0; //y좌표
int d = 0; //방향 변수

3. 배열에 값 넣기

int[][] triangle = new int[n][n];
int v = 1;
   while (true) {
      triangle[y][x] = v++;
      int nx = x + dx[d]; 
      int ny = y + dy[d];
      if (nx == n || ny == n || nx == -1 || ny == -1 || triangle[ny][nx] != 0) {
           d = (d + 1) % 3;
           nx = x + dx[d];
           ny = y + dy[d];
           if (nx == n || ny == n || nx == -1 || ny == -1 || triangle[ny][nx] != 0) break;
       }
  }

해당 코드에서는 d값에 따라서 다음 배열위치를 결정하게 됩니다.

int nx = x + dx[d]; 
int ny = y + dy[d];

배열위치를 결정한후, 더이상 진행할 수 없는 배열위치인 경우의 처리를 추가했습니다.

 if (nx == n || ny == n || nx == -1 || ny == -1 || triangle[ny][nx] != 0) {
}

nx == n || ny == n 은 아래와 오른쪽으로 이동하는 경우에 배열의 크기를 초과한 경우,

nx == -1 || ny == -1 은 왼쪽위로 이동하는 경우에 배열의 크기를 초과한 경우,

triangle[ny][nx] ≠ 0 은 이미 숫자가 써잇는 경우입니다.

만약 배열위치가 더이상 진행 되지 않는경우에,

d = (d + 1) % 3;
nx = x + dx[d];
ny = y + dy[d];

d = (d + 1) % 3; d의 값에 +1을 하여 방향을 바꾸었고, 2를 초과하는경우 다시 0으로 바꾸엇습니다.

방향을 바꾼후, nx = x + dx[d]; ny = y + dy[d]; 바뀐 방향에 따른 x와y의 변화값을 실행하였습니다.

전환된 방향으로도 진행을 못하는 경우 숫자채우기를 종료합니다.

if (nx == n || ny == n || nx == -1 || ny == -1 || triangle[ny][nx] != 0) break;
}

4. 현재 위치 업데이트

x = nx;
y = ny;

5. 1차원 배열로 값 리턴

int[] result = new int[v - 1];
            int index = 0;
            for(int i = 0; i < n; i++) {
                for (int j = 0; j <= i; j++) {
                    result[index++] = triangle[i][j];
                }
            }
        return result;

전체 코드

import java.util.*;
import java.util.stream.Collectors;

class Solution {
    // 변화량 상수 생성
    private static final int[] dx = {0, 1, -1};
    private static final int[] dy = {1, 0, -1};
    public int[] solution(int n) {
        int x = 0;
        int y = 0;
        //방향 변수 생성
        int d = 0;

        int[][] triangle = new int[n][n];
        int v = 1;
        while (true) {
            triangle[y][x] = v++;
            int nx = x + dx[d];
            int ny = y + dy[d];
            if (nx == n || ny == n || nx == -1 || ny == -1 || triangle[ny][nx] != 0) {
                d = (d + 1) % 3;
                nx = x + dx[d];
                ny = y + dy[d];
                if (nx == n || ny == n || nx == -1 || ny == -1 || triangle[ny][nx] != 0) break;
            }
            x = nx;
            y = ny;
        }

        int[] result = new int[v - 1];
        int index = 0;
        for(int i = 0; i < n; i++) {
            for (int j = 0; j <= i; j++) {
                result[index++] = triangle[i][j];
            }
        }
        return result;
    }

}
반응형
저작자표시 (새창열림)
'알고리즘' 카테고리의 다른 글
  • 프로그래머스 Level2 자바 - 교점에 별 만들기
  • 유클리드 호제법 - 최대공약수 구하기 : 백준 13241번으로 알아보기
  • 11650번 - 좌표 정렬하기(Stream, Comparator 사용)
  • 백준 10978번 : 세로읽기 - 자바
LightSource
LightSource
어제보단 발전한 오늘의 나를 위한 블로그
    반응형
  • LightSource
    LightSourceCoder
    LightSource
  • 전체
    오늘
    어제
    • 분류 전체보기 (152)
      • Git (4)
      • Language (6)
        • Java (6)
      • Back-End (63)
        • Spring Boot (4)
        • MyBatis (1)
        • Oracle (1)
        • PL SQL (3)
        • JPA (26)
        • Spring Data JPA (5)
        • Spring MVC (8)
        • Spring (12)
        • Spring Security (2)
        • Redis (1)
      • Front-End (38)
        • 아이오닉 (2)
        • JSP (7)
        • JavaScript (4)
        • React (16)
        • TypeScript (3)
        • Angular (6)
      • AWS (1)
      • CI & CD (1)
      • 개발지식 (13)
        • 네트워크 (9)
        • CS 지식 (4)
      • 데이터모델링 (2)
      • Tool (1)
      • 프로젝트 (5)
      • 독후감 (2)
      • 잡생각 (0)
      • 면접 준비 (1)
      • 알고리즘 (14)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    배열요소삭제
    배요소열추가
    배열요소수정
    리액트
    react
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.0
LightSource
프로그래머스 Level2 - 삼각달팽이
상단으로

티스토리툴바