211008_자료구조&알고리즘(4)

nais·2021년 10월 9일
0

네카라쿠배

목록 보기
18/27

1. 2차원 배열

  • 2차원 배열은 말그대로 2차원 배열을 사용하여 문제를 푸는 방식으로 주로 for 문과 같은 반복문을 사용하여 말그대로 구현하는 능력이 중요시되는 기법이다.

(1) 격자판 최대합

5*5 격자판에 주어진 각 행의 합, 각 열의 합, 두 대각선의 합 중 가장 큰 합을 출력하라

function solution(nums){
  
  let sum1 = 0 , sum2 = 0 , max = 0;
  let answer = 0;
  let len = nums.length;

  //(1)
  for(let i = 0; i<len; i++ ){

    for(let  j =0; j<len ; j++){

      sum1 += nums[i][j];
      sum2 += nums[j][i];
    }
  }

//(2) 
  max = Math.max(sum1, sum2);
  sum1 = 0, sum2 = 0; 

  for(let i = 0; i<len ; i++){
    //(3) 
    sum1 += nums[i][i];
//(4)
    for(let j = len ; j< 0;  j++ ){

      sum2 += nums[i][j];
      
    }
  }

  max =Math.max(sum1,sum2);
  answer = max;

  return answer;
}

(1) n * n 의 행렬에 맞게 먼저 각 행과 열의 합을 구하는 for 문 행과 열을 서로 반대되는 값으로 구하는 것이 가능하기 때문에 이 for문에서 합계를 같이 구할 수 있다

(2) 합계 중 max 값을 구한다

(3) ' \' 방향의 대각선은 (0,0) (1,1) 의 형태로 i 하나로도 값을 구할 수 있어서 첫번 째 세번째 for 아래에서 합계 구하기

(4) '/' 방향의 대각선은 (0,4) , (1,3) 의형태로 x 축은 늘어나도 y 축은 감소로 j의 시작을 격자판의 길이로 잡고 감소하는 것으로 for문 동작

(2) 봉우리

지도 정보 N * N 격자판에서 각 격자에 그 지역의 높이가 쓰여있는데 각 격자 판의 숫자 중 상하좌우 수자보다 큰 숫자를 봉우리 지역이라고 한다 이 지역의 개수를 알아내는 문제

function solution2(nums){

 let answer = 0;
 let n = nums.length ;
 //(1)
 let dx = [-1, 0, 1, 0]; 
 let dy = [0, 1, 0, -1];
 let cnt = 0;

//(2)
 for( let i = 0; i < n ; i++){
   for(let j = 0 ; j < n; j++){
   //(3)
     let flag = 1;
     //(4) 
     for(let k = 0; k < 4 ; k++){

       let nx = dx[k] + i;
       let ny = dy[k] + j;
	  //(5)
       if( nx <n  && ny <n && nx >=0 && ny >=0 && nums[nx][ny] >= nums[i][j]){  
         flag = 0; 
         break;
       }
       
     }
     //(6) 
     if(flag === 1) cnt++;    
   }
 }

 answer = cnt ; 
 return answer;
}

(1) 판의 상하좌우를 구하기 위한 좌표 배열을 지정
- dx[0],dy[0] => 12시 방향
- dx[1],dy[1] => 3시 방향
- dx[2],dy[2] => 6시 방향
- dx[3], dy[3] => 9시 방향

(2) N x N 의 판을 탐색할 2중 for문 선언

(3) N x N 의 범위를 벗어 났는지를 판단 할 flag변수
1-> 벗어나지 않고 봉우리 지역이다
0 -> 벗어난 범위 && 상하좌우 중 (i, j) 위치가 봉우리 지역이 아님

(4) (i,j) 위치에서 상하좌우 검사하는 for문

(5) 계산된 nx , ny 값 중에 N 보다 밖으로 나가는 위치인지 -1 값이 아닌지를 확인 , 값도 i,j 의 위치보다 큰가?

(6) 봉우리 지역이면 cnt (봉우리 개수 측정) +1 시켜준다

(3) 임시반장 정하기

선생님께서 임시로 반장을 정하는데 각 학생들이 1학년부터 5학년까지 몇반에 속했는지 보고 전체 학생 중에서 같은 반이었던 학생 수가 제일 많은 사람을 임시반장으로 정하는 문제

function solution3(students){

  let cnt = 0 ,max = 0 , answer =0;
  
  //(1)
  for(let i = 0; i<students.length; i++ ){
  //(2)
    for( let j = 0;  j < students.length; j++){
  //(3)
      for( let k = 0; k < 5 ; k++){ //자기가 자기 자신 돌려도 된다 신경쓰지마라  ,학년을 제일 안쪽으로 돌려라 
  //(4)
        if(students[i][k] === students[j][k]){
          cnt++;
          break;
        }

    }
  }
//(5)
  if(max < cnt){
      max = cnt;
      answer = i;
    }
    
  }

  return answer;
}


console.log(solution3([[2, 3, 1, 7, 3], [4, 1, 9, 6, 8], [5, 5, 2, 4, 4], [6, 5, 2, 6, 7], [8, 4, 2, 2, 2]]));

(1) 비교를 위한 기준이 되는 학생을 정하는 for문

(2) (1)번에서 현재 대상이되는 i번 학생을 제외한 나머지 학생들을 탐색하는 for 문

(3) 각 학생들의 학년별 반을 탐색하는 for문

(4) 기준이 되는 학생과 비교대상의 학생의 학년이 같다면 카운트 상승

(5) 같은 반인 횟수가 많아아야 하기 때문에 카운트 최대값을 반환

(4) 빙고

우리가 기존에 알고있던 빙고게임을 구현 사회자가 부르는 수의 순서가 주어질 때 사회자가 몇번 째 수를 부른 후 빙고를 외치게 되는지를 출력하는 문제

function solution2(board, nums){


    let answer = 0 , sum = 0;  
    //(1)
    let s1,s2,s3,s4 ; 
    
    
	//(2)
    let pan =  Array.from(Array(2), () => Array(30).fill(0));
    //(3)
    let binggo = Array.from(Array(5),() => Array(5).fill(0));
    for(let i = 0; i < 5 ; i++){
        for(let j = 0; j < 5; j++){

            let value = board[i][j]; 
            //(4)
            pan[0][value] = i; 
            //(5)
            pan[1][value] = j;

        }
    }

    for(let i = 0; i < nums.length ; i++){

        let value = nums[i]; 
        //(6)
        binggo[pan[0][value]][pan[1][value]] = 1; 
        s1=s2=s3=s4=1;

        //(7) 
        if(pan[0][value] === pan[1][value]){ 
            for(let i = 0; i < 5; i++){
            (8) 
                if(binggo[i][i] === 0){ 
                    s1= 0;
                }
            }
        }
        //(9)
        else{
            s1 = 0; 
        }
        
        //(10)
        if(pan[0][value] + pan[1][value] === 4){ 
            for(let i = 0 ; i < 5; i++){
                if(binggo[i][4-i]=== 0){ 
                    s2 = 0;
                }
            }
        }
        else{
            s2 = 0; 
        }

        for(let i = 0 ; i < 5 ; i++){
        //(11)
            if(binggo[pan[0][value]][i]===0){ 
                s3 = 0;
            }
        //(12)
            if(binggo[i][pan[1][value]]===0){ 
                s4 = 0;
            }
        }
        
        sum += s1+s2+s3+s4 ; 
        if( sum >=3 ){
            answer = i+1;
            break;
        }
        
    }
    return answer;
}


console.log(solution2([[11, 12, 2, 24, 10], [16, 1, 13, 3, 25], [6,

(1) 대각선 \ ,/ , 행, 열 각각의 빙고 체크 변수

(2) board의 각각 행과 열의 값들을 인덱스로 기록하기 위한 2차원 배열

(3) 사회자가 부르는 nums 의 값들이 board 에 있는지 체크해주는 2차원 배열

(4) board의 value 값을 pan 인덱스로 x 축 값 선언

(5) board의 value 값을 pan 인덱스로 y 축 값 선언

(6) 사회자가 부른 값의 좌표 값을 가져와 빙고 체크의 기본값의 의미로 1로 세팅 (1 : 빙고 ,0: x )

(7) \ 대각선 판별 , (0,0) ,(1,1),(2,2) 이 대각선들의 위치이기때문에 조건을 이렇게 세팅

(8) 한개라도 0이라면 반복문 중단

(9) 사회자가 부른 값이 대각선 방향이 아니므로 x 표시

(10) '/' 대각선은 (0,4) , (4,0) 여기도 마찬가지로 한개라도 0이라면 반복문 중단

(11) 행 중에서 한개라도 0이 발견되면 빙고 x

profile
왜가 디폴트값인 프론트엔드 개발자

0개의 댓글