λ³Έλ¬Έ λ°”λ‘œκ°€κΈ°
3️⃣ Swift/Problem Solving

[Swift Algorithm] κ°€μž₯ 큰 μ •μ‚¬κ°ν˜• μ°ΎκΈ° Programmers(Lv.2)

by seolhee2750 2021. 7. 20.
문제 μ„€λͺ…

1와 0둜 μ±„μ›Œμ§„ ν‘œ(board)κ°€ μžˆμŠ΅λ‹ˆλ‹€. ν‘œ 1칸은 1 x 1 의 μ •μ‚¬κ°ν˜•μœΌλ‘œ 이루어져 μžˆμŠ΅λ‹ˆλ‹€. ν‘œμ—μ„œ 1둜 이루어진 κ°€μž₯ 큰 μ •μ‚¬κ°ν˜•μ„ μ°Ύμ•„ 넓이λ₯Ό return ν•˜λŠ” solution ν•¨μˆ˜λ₯Ό μ™„μ„±ν•΄ μ£Όμ„Έμš”. (단, μ •μ‚¬κ°ν˜•μ΄λž€ 좕에 ν‰ν–‰ν•œ μ •μ‚¬κ°ν˜•μ„ λ§ν•©λ‹ˆλ‹€.)

 

예λ₯Ό λ“€μ–΄

0 1 1 1
1 1 1 1
1 1 1 1
0 0 1 0

κ°€ μžˆλ‹€λ©΄ κ°€μž₯ 큰 μ •μ‚¬κ°ν˜•μ€

0 1 1 1
1 1 1 1
1 1 1 1
0 0 1 0

κ°€ 되며 λ„“μ΄λŠ” 9κ°€ λ˜λ―€λ‘œ 9λ₯Ό λ°˜ν™˜ν•΄ μ£Όλ©΄ λ©λ‹ˆλ‹€.

 

μ œν•œ 쑰건
  • ν‘œ(board)λŠ” 2차원 λ°°μ—΄λ‘œ μ£Όμ–΄μ§‘λ‹ˆλ‹€.
  • ν‘œ(board)의 ν–‰(row)의 크기 : 1,000 μ΄ν•˜μ˜ μžμ—°μˆ˜
  • ν‘œ(board)의 μ—΄(column)의 크기 : 1,000 μ΄ν•˜μ˜ μžμ—°μˆ˜
  • ν‘œ(board)의 값은 1λ˜λŠ” 0으둜만 이루어져 μžˆμŠ΅λ‹ˆλ‹€.

 

μž…μΆœλ ₯ 예
board answer
[[0,1,1,1],[1,1,1,1],[1,1,1,1],[0,0,1,0]] 9
[[0,0,1,1],[1,1,1,1]] 4

 

λ‚΄ 문제 풀이
func solution(_ board:[[Int]]) -> Int {
    var block = board
    var result = 0
    
    // λ§Œμ•½ 주어진 ν–‰μ΄λ‚˜ 열이 1일 κ²½μš°μ—” μ–΄μ°¨ν”Ό μ •μ‚¬κ°ν˜• 넓이가 1보닀 클 수 μ—†μŒ
    if board.count == 1 || board[0].count == 1 {
        result = 1
    }
    
    // 1ν–‰ 1μ—΄λΆ€ν„° λκΉŒμ§€ 반볡문
    for i in 1..<board.count {
        for j in 1..<board[0].count {
            if board[i][j] == 1 {
                block[i][j] = min(block[i-1][j-1], block[i-1][j], block[i][j-1]) + 1
                result = result < block[i][j] ? block[i][j] : result
            }
        }
    }
    
    // result의 제곱 좜λ ₯
    return result * result
}
  • μ²˜μŒμ—” μ–΄λ–»κ²Œ 풀어야할지 μ „ν˜€ κ°€λŠ μ΄ μ•ˆλΌμ„œ,,γ…œγ…œ λ‹€λ₯Έ λΈ”λ‘œκ·Έλ₯Ό μ°Έκ³ ν•˜μ—¬ ν’€μ—ˆλ‹€.
    이 ν’€μ΄μ˜ 진행 방식을 그림으둜 그렀보자. (μž…μΆœλ ₯ 예제 1)
    [1][1]λΆ€ν„° μ›μ†Œκ°€ 1일 λ•Œ, κ·Έ μ „ μ›μ†Œλ“€(이 κ²½μš°μ—λŠ” [0][0], [0][1], [1][0]) 쀑 κ°€μž₯ μž‘μ€ 수λ₯Ό 더해쀀닀.
    μœ„μ˜ κ²½μš°μ—λŠ” κ·Έ μ „ μ›μ†Œλ“€μ΄ 0, 1, 1 이기 λ•Œλ¬Έμ— κ·Έ 쀑 κ°€μž₯ μž‘μ€ 0을 λ”ν•΄μ£Όμ—ˆλ‹€.

    이런 λ°©μ‹μœΌλ‘œ λͺ¨λ“  μ›μ†Œλ“€μ„ ν•˜λ‚˜ ν•˜λ‚˜ 계산해 λ‚˜κ°€λ©΄,
    μœ„μ™€ 같이 μ •μ‚¬κ°ν˜•μ΄ 될 수 μžˆλŠ” 경우의 수 쀑, κ°€μž₯ κΈ΄ ν•œ λ³€μ˜ 길이λ₯Ό ꡬ할 수 μžˆλ‹€.
  • μœ„μ˜ 둜직으둜 κ΅¬ν•œ μˆ˜λ“€ 쀑 κ°€μž₯ 큰 수λ₯Ό result 배열에 λ‹΄μ•„ λ§ˆμ§€λ§‰μ— μ œκ³±ν•˜μ—¬ λ¦¬ν„΄ν•΄μ£Όμ—ˆλ‹€.

 

πŸ’‘ ν”Όλ“œλ°±
  • μ²˜μŒμ— κ°€μž₯ 큰 μ •μ‚¬κ°ν˜•μ„ κ΅¬ν•˜λŠ” 방법을 생각해내지 λͺ»ν–ˆλŠ”데,,
    문제λ₯Ό 많이 ν’€μ–΄λ³΄λ©΄μ„œ 이런 μ €λŸ° 풀이방법듀을 읡히고,,
    슀슀둜 λ‹€μ–‘ν•œ 풀이 방법을 λ§Œλ“€ 수 μžˆλ„λ‘ 많이 곡뢀해야할 것 κ°™λ‹€.

 


 

πŸ– [ μΆ”κ°€ ] 1주일 ν›„ λ‹€μ‹œ 풀어보기

func solution(_ board:[[Int]]) -> Int
{
    var result = board
    var answer = 0
    
    if board.count == 1 || board[0].count == 1 {
        if board.flatMap{$0}.max()! == 1 { return 1 }
        else { return 0 }
    }
    
    for i in 0..<board.count-1 {
        for j in 0..<board[0].count-1 {
            if result[i][j] >= 1 && result[i+1][j+1] == 1 {
                result[i+1][j+1] += min(result[i][j], result[i+1][j], result[i][j+1])
                if result[i+1][j+1] > answer { answer = result[i+1][j+1] }
            }
        }
    }

    return answer * answer
}
  • μ €λ²ˆμ— κ³΅λΆ€ν•œ 덕뢄에 λ°”λ‘œ λ‘œμ§μ„ μƒκ°ν•΄μ„œ ν’€ 수 μžˆμ—ˆλ‹€.
  • 근데 λ‹€μ‹œ λ³΄λ‹ˆ, 첫 번째 ν’€μ΄μ—μ„œ μ²˜λ¦¬ν•΄μ£Όμ§€ μ•Šμ€ μ˜ˆμ™Έ ν•˜λ‚˜κ°€ λ³΄μ—¬μ„œ μ²˜λ¦¬ν•΄μ£Όμ—ˆλ‹€.
  • 첫 번째 ifλ¬Έμ—μ„œ, λ°°μ—΄μ˜ μ›μ†Œ 쀑 1이 ν•˜λ‚˜λ„ 없을 μˆ˜λ„ 있기 λ•Œλ¬Έμ—,, λ°°μ—΄μ˜ κ°€μž₯ 큰 μˆ˜κ°€ 1이 아닐 경우 0을 λ¦¬ν„΄ν•˜λ„λ‘ ν–ˆλ‹€.
    μ–Όλ§ˆ μ „ κ³΅λΆ€ν•œ flatMap을 μ‚¬μš©ν•˜μ—¬ 2차원 배열을 1μ°¨μ›μœΌλ‘œ λ§Œλ“€μ–΄μ£Όμ–΄ μ‰½κ²Œ κ°€μž₯ 큰 수λ₯Ό ꡬ할 수 μžˆμ—ˆλ‹€.
  • λ‚˜λ¨Έμ§€ λ‘œμ§μ€ 첫 번째 풀이와 μœ μ‚¬ν•˜λ‹€.

 


 

문제

https://programmers.co.kr/learn/courses/30/lessons/12905

λŒ“κΈ€