💬 문제
건물의 내구도를 나타내는 2차원 정수 배열 board
와 적의 공격 혹은 아군의 회복 스킬을 나타내는 2차원 정수 배열 skill
이 매개변수로 주어집니다. 적의 공격 혹은 아군의 회복 스킬이 모두 끝난 뒤 파괴되지 않은 건물의 개수를 return하는 solution함수를 완성해 주세요.
💬 Idea
정확성과 효율성 모두를 맞춰야 한 문제
정확성만 고려한다면 굉장히 쉬운 문제이지만, 효율성을 맞추기 위해서는 ‘누적합 알고리즘’에 대한 지식이 있어야 했다.
💡 누적합을 통해 시간 복잡도를 O(N + M) 까지 줄일 수 있다.
💬 풀이
[1차 풀이] - 정확성 100 / 효율성 0
func solution(_ board:[[Int]], _ skill:[[Int]])->Int{varboard= board
forskillin skill {lettype=skill[0]letr1=skill[1]letc1=skill[2]letr2=skill[3]letc2=skill[4]letdegree=skill[5]forrowin r1...r2 {forcolumnin c1...c2 {if type ==1{board[row][column]-= degree
}else{board[row][column]+= degree
}}}}varcount=0forrowin board {forcolumnin row {if column >=1{
count +=1}}}return count
}solution([[5,5,5,5,5],[5,5,5,5,5],[5,5,5,5,5],[5,5,5,5,5]],[[1,0,0,3,4,4],[1,2,0,2,3,2],[2,1,0,3,1,2],[1,0,1,3,3,1]])소요시간 : 15분
[2차 풀이] - 정확성 100 / 효율성 100
func solution(_ board:[[Int]], _ skill:[[Int]])->Int{letboard= board
// 누적합을 수행하기 위한 행 + 1, 열 + 1만큼의 행과 열을 가지는 2차원 보드 생성
vardegreeBoard=Array(repeating:Array(repeating:0, count:board[0].count +1), count: board.count +1)forskillin skill {updateBoardByDegree(°reeBoard, skill)}addhorizontal(°reeBoard)addVertical(°reeBoard)varcount=0forrowin0..<board.count {forcolumnin0..<board[0].count {degreeBoard[row][column]+=board[row][column]ifdegreeBoard[row][column]>=1{
count +=1}}}return count
}
// MARK: - skill의 degree에 따라 누적합 보드를 업데이트하는 메서드
func updateBoardByDegree(_ board:inout[[Int]], _ skill:[Int]){lettype=skill[0]letr1=skill[1]letc1=skill[2]letr2=skill[3]letc2=skill[4]letdegree= type ==1?-skill[5]:skill[5]board[r1][c1]+= degree
board[r1][c2 +1]-= degree
board[r2 +1][c1]-= degree
board[r2 +1][c2 +1]+= degree
}
// MARK: - 가로 누적합 메서드
func addhorizontal(_ board:inout[[Int]]){foriin0..<board.count {forjin0..<board[i].count {if j +1<board[i].count {board[i][j +1]+=board[i][j]}}}}
// MARK: - 세로 누적합 메서드
func addVertical(_ board:inout[[Int]]){foriin0..<board.count {forjin0..<board[i].count {if j +1< board.count {board[j +1][i]+=board[j][i]}}}}💬 알게된 것
💡 누적합 알고리즘
💡 inout 파라미터
Swift에서 함수의 파라미터는 상수(Constant)이므로 함수 내부에서 파라미터의 값을 변경할 수 없다. 이는 우리가 파라미터를 실수로라도 변경할 수 없다는 뜻이기도 하다. 만약 함수에서 파라미터의 값을 변경하고, 변경된 값이 함수 호출이 종료된 후에도 지속되길 원한다면 inout 파라미터를 사용하면 된다.
in-out 파라미터는 함수 정의시 파라미터의 타입 전에 inout 키워드를 추가하면 된다. in-out 파라미터는 변수(variable)만을 취급하며 함수의 인자로 전달할 때 &를 사용하여 해당 값이 함수내부에서 변경될 것임을 나타내야 한다.
func swapTwoInts(_ a:inoutInt, _ b:inoutInt){lettemp= a
a = b
b = temp
}varsomeInt=3varanotherInt=107swapTwoInts(&someInt,&anotherInt)
// someInt = 107, anotherInt = 3출처: https://hyunsikwon.github.io/swift/Swift-Inout-01/
💬 문제건물의 내구도를 나타내는 2차원 정수 배열
board와 적의 공격 혹은 아군의 회복 스킬을 나타내는 2차원 정수 배열
skill이 매개변수로 주어집니다. 적의 공격 혹은 아군의 회복 스킬이 모두 끝난 뒤 파괴되지 않은 건물의 개수를 return하는 solution함수를 완성해 주세요.
💬 Idea정확성과 효율성 모두를 맞춰야 한 문제
정확성만 고려한다면 굉장히 쉬운 문제이지만, 효율성을 맞추기 위해서는 ‘누적합 알고리즘’에 대한 지식이 있어야 했다.
💡 누적합을 통해 시간 복잡도를 O(N + M) 까지 줄일 수 있다.
💬 풀이[1차 풀이] - 정확성 100 / 효율성 0
소요시간: 15분[2차 풀이] - 정확성 100 / 효율성 100
💬 알게된 것💡 누적합 알고리즘
💡 inout 파라미터
Swift에서 함수의 파라미터는 상수(Constant)이므로 함수 내부에서 파라미터의 값을 변경할 수 없다. 이는 우리가 파라미터를 실수로라도 변경할 수 없다는 뜻이기도 하다. 만약 함수에서 파라미터의 값을 변경하고, 변경된 값이 함수 호출이 종료된 후에도 지속되길 원한다면
inout파라미터를 사용하면 된다.in-out 파라미터는 함수 정의시 파라미터의 타입 전에
inout키워드를 추가하면 된다. in-out 파라미터는 변수(variable)만을 취급하며 함수의 인자로 전달할 때&를 사용하여 해당 값이 함수내부에서 변경될 것임을 나타내야 한다.출처: https://hyunsikwon.github.io/swift/Swift-Inout-01/