2차 공부/알고리즘

n^2 배열 자르기

공대탈출 2024. 7. 19. 11:55

프로그래머스 - n^2 배열 자르기

 

 

먼저 작성한 코드

function solution(n, left, right) {
    var answer = [];
    
    let answerStr = ''
    for (let i = 1; i<=n; i++) {
        let tempStr = `${i}`.repeat(i)
        for (let j=i+1; j<=n; j++) {
            tempStr += `${j}`
        }
        answerStr+=tempStr
    }
    
    
    return answerStr.slice(left, right+1).split('').map((el) => Number(el));
}
// i일 때 i를 i개만큼 넣고, n까지 1씩 더하며 추가
// [1 2 3 4]
// [2 2 3 4]
// [3 3 3 4]
// [4 4 4 4]

만드려는 배열을 문자열로 만들고 한 문자열에 모두 저장한 다음, left와 right에 맞춰 자르고, 배열화시킨 뒤 모든 요소를 숫자화 시키는 방식으로 풀이했다.

테스트코드는 모두 성공했으나, 데이터가 매우 크게 들어올 수 있는 점을 생각하지 않아 시간초과로 실패하였다.

 

두번째로 작성한 코드

function solution(n, left, right) {
    var answer = [];
    
    let leftRow = Math.floor(left/n)
    let leftPos = left%n
    let rightRow = Math.floor(right/n)
    let rightPos = right%n
    //left와 right가 같은 행에 있을 때
    if (leftRow === rightRow) {
        console.log('같은행에 있음')
        //반복숫자 값 추가
        for (let i = leftPos; i<=leftRow; i++) {
            answer.push(leftRow+1)
        }
        //등차수열값 추가
        for (let j = leftRow+2; j<=n; j++){
            answer.push(j)
        }
        return answer;
    } else {
        console.log('같은 행에 없음')
    //먼저 시작행의 값을 더한다.
        //반복숫자 값 추가
        for (let i = leftPos; i<=leftRow; i++) {
            answer.push(leftRow+1)
        }
        //등차수열값 추가
        for (let j = leftRow+2; j<=n; j++){
            answer.push(j)
        }
    //사이행의 값을 더한다.
        for (let k = leftRow+1; k<rightRow; k++) {
            console.log('사이행 더하기')
        //사이행의 반복값 더하기
            for (let l = 0; l<=k; l++) {
                answer.push(k+1)
            }
        //사이행의 등차수열 더하기
            for (let m = k+2; m<=n; m++) {
                answer.push(m)
            }
        }
    //right행의 값을 더한다.
        console.log(rightPos, rightRow)
        if (rightPos > rightRow) {
            console.log('분리하여 더한다.')
        } else {
            console.log('반복값만 더한다.')
        }
        return answer;
    }
}
// i일 때 i를 i개만큼 넣고, n까지 1씩 더하며 추가
// [1 2 3 4 5]
// [2 2 3 4 5]
// [3 3 3 4 5] [3 3 4 5]
// [4 4 4 4 5] [4 4 4 4 5]
// [5 5 5 5 5] [5 5 5]
// left부터 생성할 방법은?
// n 모양의 정사각 행렬 각 행마다 n개씩 생김
// left가 행렬에서 어디에 위치하는지 알아내고, 해당 행부터 생성한다.
// right이 포함된 행까지 제작하면
// [1 2 3 4 5 6 7]
// [2 2 3 4 5 6 7]
// [3 3 3 4 5 6 7]
// [4 4 4 4 5 6 7] 22 [4, 4, 4, 5, 6, 7, 5, 5, 5, 5, 5, 6] 33
// [5 5 5 5 5 6 7]
// [6 6 6 6 6 6 7]
// [7 7 7 7 7 7 7]
  • left와 right이 같은 행에 있을 때
    1. 해당 행의 반복숫자를 더한다.
    2. 해당 행의 등차수열 숫자를 더한다.
  • left와 right이 다른 행에 있을 때
    1. left 행의 숫자를 더한다.
      • 반복값의 숫자를 더한다.
      • 등차수열 숫자를 더한다.
    2. 사이 행의 숫자를 더한다.
      • 반복값의 숫자를 더한다.
      • 등차수열 숫자를 더한다.
    3. right 행의 숫자를 더한다.
      • 반복값만 더하면 되는 조건
      • 등차수열까지 더해야하는 조건

위와 같이 예외처리를 하여 풀이를 하려 했지만 아무리봐도 요구하는 해석을 풀이하는 방법이 아닌 것 같아 도중에 멈추게 되었다.

 

 

다음으로 작성한 코드

function solution(n, left, right) {
    var answer = [];
    
    for (let i = left; i<=right; i++) {
        let row = Math.floor(i/n)
        let column = i%n
        answer.push(Math.max(row, column)+1)
    }
    
    return answer;
}

행렬의 각 번호마다의 행과 열 중 큰 값을 선택하여 1을 더해주면 해당 위치의 값이 된다.

 

이전에 작성했던 코드들은 행렬을 처음부터 끝까지 만들어 잘라서 내보내기, 원하는 위치부터 행렬을 만들어 배열에 넣기였다.

이것은 문제에서 제시해준 행렬의 속성을 잘 사용하지 못하여 코드작성에 어려움이 있었던 것으로 생각한다.

행렬문제가 나온다면 해당 요소의 좌표를 잘 이용해야한다.

프로그래머스에서 이해를 돕기위해 제공해준 gif파일을 보고 행렬을 만들어 리턴해야겠다!하면서 늪에 빠졌던 것 같다.

'2차 공부 > 알고리즘' 카테고리의 다른 글

의상  (0) 2024.07.24
할인 행사  (0) 2024.07.23
괄호 회전하기  (0) 2024.07.17
이진 변환 반복하기  (0) 2024.07.09
JadenCase 문자열 만들기  (0) 2024.07.08