그런다음에, Int -> String -> Array로 변환을 하였고 while 문안에 두자리수가 넘으면 for문을 계속 돌렸으면 좋겠다.
라고 한다음에 for문 안에는 sum을 누적하는 방식으로 풀이 하였다.
근데, 아쉽게도 시간 초과가 생겼다.
어떻게 하는 것이 좋을까? 다른 고수분들의 답변을 참고했다.
class Solution {
func addDigits(_ num: Int) -> Int {
if num <= 0{
return 0
}
var sum: Int = 0
var numS = String(num)
var numA = Array(numS)
repeat{
for num in numA{
sum += Int(String(num))!
}
}while sum >= 10
return sum
}
}
class Solution {
func addDigits(_ num: Int) -> Int {
return num < 10 ? num : (num % 9 == 0 ? 9 : num % 9)
}
}
sudiptobd님의 해결책도 가져와봤다.
일반적인 코드이다.
getSum이라는 함수를 구현해주었다.
num 값을 받으면, num의 나머지 그리고 10으로 나누어서 누적해서 해를 구하는 방식이다.
예로, 111이 들어오면, 111 > 0 이니깐, while 문이 실행됩니다.
그런 다음, 111을 % 10을 하게 되면 1이 sum으로 누적이 되고 x는 11이 됩니다.
다시 x > 11을 만족하기 때문에 다시 실행이 되고 11 % 10 이 sum으로 누적이 되고 x는 1이 됩니다.
그리고 또 x > 0을 만족하기 때문에 while 문이 실행이 되고 x% 10 이 sum 으로 누적이 되고 x는 0이 됩니다.
sum은 총 3이되고 리턴하게 됩니다.
만약, 엄청 큰수가 들어온다면, 이것을 일의자리 숫자가 될때 까지 반복하면 되겠습니다.
class Solution {
func addDigits(_ num: Int) -> Int {
var value = getSum(num)
while value > 9 {
value = getSum(value)
}
return value
}
func getSum(_ num: Int) -> Int {
var x = num
var sum = 0
while x > 0{
sum += x%10
x=x/10
}
return sum
}
}
추가적으로....
class Solution {
func addDigits(_ num: Int) -> Int {
var res = num
while res > 9 {
var next = 0
while res != 0 {
next += res % 10
res = res / 10
}
res = next
}
return res
}
}
n1을 i loop안에서 돌릴 것인데, 이 i 가 num1.count의 숫자보다 같아질때에는 정수 0으로 n1을 대체하면 된다!!
그렇다면, 숫자가 비어있지 않을 것이다.
오케이!
이제는 실재로 더하면 0부터 19까지 다양한 값이 나온다.
근데, 우리는 9까지는 신경을 안쓰고 result 배열에 넣으면 된다.
하지만, 10부터는 올림수가 발생하기 때문에 우리는 신경 써야한다.
나는 여기까지 했다. 10이상의 수가 발새한다면, 10을 나눈 나머지를 result에 append해버리자.
class Solution {
func addStrings(_ num1: String, _ num2: String) -> String {
var num1 = Array(Array(num1).reversed())
var num2 = Array(Array(num2).reversed())
var carry:Bool = false
var result: [Any] = []
//print(num1,num2)
//["1", "1"] ["3", "2", "1"]
for i in 0..<max(num1.count,num2.count){
// 아래 부분에서 살짝 헷갈렸어, 어떻게 해야 비어있는 값을 표현할까...?
var n1 = i < num1.count ? Int("\(num1[i])")! : 0
var n2 = i < num2.count ? Int("\(num2[i])")! : 0
if n1 + n1 < 10{
result.append(n1 + n2)
}else{
result.append((n1 + n2)%10)
}
}
print(result)
var a = Array(result.reversed())
return a
}
}
다른 분들의 풀이를 가져왔다.
어떻게 내가 못한 부분을 하셨는지 보자!!
다 보니깐, 아이디어는 비슷비슷하다.
String을 Array로 하고 reversed()
오케이
그리고 res가 result일듯 합니다.
그런다음에, isOne???
그런다음에 i와 j 특이한 것은 i,j를 함수내에서 사용이 가능하게 했다는 것!!
while() 문을 사용했네,
이거 은근 많이 사용된다.
조건을 보니깐,
i < chs1.count 오케이
j< chs2.count 오케이
isOne == 1
을 "또는"으로 연결했네.
let c1, c2부분은 내가 했던 거랑 비슷하네.
s라는 부분을 살펴보면, c1 + c2 + isOne을 더하고 % 10 한다...
오케이 다음...
isOne은 c1 + c2 +isOne을 더하고 / 10 한다...
예로 들자면, 3 + 7 + 0 / 10 이면 1이다.
아하, isOne이 올림수 같은 것 같다.
그런다음에, 이것을 append한다.
예를 들어보자.
321 + 119 = 440
첫째 자리
1 + 9 + 0 % 10 = 0
1 + 9 + 0 / 10 = 1
[1]
둘째 자리
2 + 1 + 1 % 10 = 4
2 + 1 + 1 / 10 = 0
[1,4]
셋째 자리
3 + 1 + 0 % 10 = 4
3 + 1 + 0 / 10 = 0
[1,4,4]
[4,1,1]
"411"
여기서는 얻을 것이 많다.
일단, String을 Array하고 reversed()를 한다면, [Chracter]에 타입으로 캐스팅 가능하다는 것.
res 또한 [Character]로 하는 이유가 있다는 것.
하나 하나의 Character에 접근하기 위해, String으로 변환하고 Int로 변환 하는 것.
Int 타입의 합(s)를 String으로 타입 변경한다음에, Character로 res에 넣을 수 있게 하는 것.
한개 한개 어떻게 구현될지 고민한다음에 생각해서 코딩하니깐, 사고력이 좋아지는 느낌이 든다.
일단, 문제를 읽어보면 [1,2,3,4,5,6,7,8] 이라는 배열을 [[1,2,3,4],[5,6,7,8]]으로 만들어야한다.
m은 행의 값이고 n은 열의 값인데, 여기서는 2,4 이라고 하자.
처음으로 든 생각은, 어떻게 나눌까라는 생각이었다.
일단, 행의 값을 보면 2이고 열의 값을 보면 4인데,
1,2,3,4 로 잘린 것을 보면, 열의 값으로 자르면 되겠다라는 생각을 하였다.
그리고 이 짓을 행의 값으로 반보개주면 되겠다라는 생각을 하였다.
그러면, 이제 구체적으로 수식으로 봐보자.
array를 slice한다고 할때에,
array[0..<4]라고 한다면,
[array[o],array[1],array[2],array[3]]
위와 같이 값들이 나오고 타입 캐스팅을 Array로 해줘야한다. 만약, 필요하다면
그러면, 다시 본론으로 와서
array[n*i..<n(i+1)]으로 하면,
만족이 된다.
array[0..<4]
array[4..<8] 을 만족 시키니깐!!
오케이!!
해결했다!! 근데, 여기서 추가적으로 생각해야하는 것은 갯수이다.
original이랑 m*n은 같아야한다.!!!!!!
아니면, 에러 발생시키자.
그리고 m == 1 이거나, n ==1이 경우도 생각을 해바야한다.
예로,
[1,2,3] 이고, m == 1 , n==3 일때에는
result가 [[1],[2],[3]] 가 되니깐, 바로 original을 append 해줘서 [1,2,3]이 되어야 한다.
n 이 1일때에도 생각해보자!
class Solution {
func construct2DArray(_ original: [Int], _ m: Int, _ n: Int) -> [[Int]] {
var original = original
var result: [[Int]] = []
var arr:[Int] = []
if original.count == m*n && m == 1{
result.append(original)
return result
}
if original.count == m*n && n == 1{
for number in original{
result.append([number])
}
return result
}
if original.count == m*n {
for i in 0..<m{
result.append(Array(original[n*i..<n*(i+1)]))
}
}else{
return []
}
return result
}
}
Emoscu 님의 풀이를 가져와 봤다.
너무 이쁘다.
저 guard original.count == m * n else{ return [] }
이 부분이 너무 이뻤다.
나도 이 부분을 자주 사용하자.!!
그리고 저렇게 var를 여려 개하는 것이 아니라, 연달아서 하는 것도 이쁜것같다.
이 풀이도 나랑 비슷하긴 한데,
다른 것이라고 하면 k라는 값을 주었다는 것이다.
그래서, j for loop한번 돌면 k가 누적이 되는 방향으로 하는 것
이러한 것을 m번 반복한다.
깔끔하게 잘하신 것같다. 그리고, 이렇게 하면 예외가 발생해도 대처가 가능하다.
func construct2DArray(_ original: [Int], _ m: Int, _ n: Int) -> [[Int]] {
guard original.count == m * n else { return [] }
var matrix = [[Int]](), k = 0
for i in 0..<m {
var arr = [Int]()
for j in k..<k+n {
arr.append(original[j])
}
k += n
matrix.append(arr)
}
return matrix
}
첫 번째 경우 일때에, 만약 Carry(올림)이 참이라면, 1을 result 배열에 추가하고 하고 Carry를 false로아니면 0 을
두 번째 경우 일때에는, 만약 Carry가 참이라면, 0을 아니면 1을 추가
이런 식으로 무언가 보기 편안하게 코딩을 해주셨다.
class Solution {
func addBinary(_ a: String, _ b: String) -> String {
var result = ""
let arr1 = Array(a.reversed())
let arr2 = Array(b.reversed())
let size = max(arr1.count, arr2.count)
var carry = false
for i in 0..<size {
let v1 = i < arr1.count ? arr1[i] : "0"
let v2 = i < arr2.count ? arr2[i] : "0"
if v1 == "0", v2 == "0" {
if carry {
result.append("1")
carry = false
} else {
result.append("0")
}
}
else if v1 == "1", v2 == "1" {
if carry {
result.append("1")
} else {
result.append("0")
}
carry = true
}
else if v1 == "1" || v2 == "1" {
if carry {
result.append("0")
} else {
result.append("1")
}
}
}
if carry {
result.append("1")
}
return String(result.reversed())
}
}
이 아래 풀이법도 논리적으로 잘 설명하신것 같아서 가져왔다.
class Solution {
func addBinary(_ a: String, _ b: String) -> String {
var sum = ""
var carryOver = 0
var arrA = Array(Array(a).reversed())
var arrB = Array(Array(b).reversed())
for i in 0..<max(arrA.count, arrB.count) {
let a = arrA.count > i ? Int("\(arrA[i])")! : 0
let b = arrB.count > i ? Int("\(arrB[i])")! : 0
let total = a + b + carryOver
sum = "\(total % 2)\(sum)"
carryOver = total / 2
}
if carryOver == 1 {
sum = "1" + sum
}
return sum
}
}
내 풀이는 아래와 같이 했는데, 런타임 에러가 발생한다.
그래서, 나도 위의 풀이처럼 하나하나 구현해서 해결했다.
class Solution {
func addBinary(_ a: String, _ b: String) -> String {
var a = a
var b = b
return String(Int(a,radix:2)! + Int(b,radix:2)!,radix:2)
}
}
여기서 얻어야할 포인트는 언젠가는 끝날 것인데, 이것을 프로그래밍 적으로 어떻게 구현할 것인가를 고민하면 된다.
생각해 보면, 반환해야하는 값이 결국에는 메트릭스의 아이템의 갯수와 같다.
예로, [[1,2],[3,4]] 가 메트릭스라면, [1,2,4,3]을 반환해야한다.
그러면, 이제 언제까지 이 짓을 할 것인지는 결정이 되었다.
그러면, 앞으로 회전을 어떻게 구현할 것인가..?
오른쪽으로 간다는 것은 (i,j)에서 j를 증가시키면 된다.
왼쪽으로 간다는 것은 j를 감소시키면 된다.
위에서 아래로 간다는 것은 i를 증가시키면 된다.
아래에서 위로 간다는 것은 i를 감소시키면 된다.
그렇다면, 준비는 다 되었다.
while이 거짓이 될때 까지 저 짓을 하면 된다.
class Solution {
func spiralOrder(_ matrix: [[Int]]) -> [Int] {
guard !matrix.isEmpty else {
return []
}
var top = 0
var bottom = matrix.count - 1
var left = 0
var right = matrix[0].count - 1
let count = matrix.count * matrix[0].count
var arr = [Int]()
while arr.count < count {
for i in stride(from: left, to: right+1, by: 1) where arr.count < count {
arr.append(matrix[top][i])
}
top += 1
for i in stride(from: top, to: bottom+1, by: 1) where arr.count < count {
arr.append(matrix[i][right])
}
right -= 1
for i in stride(from: right, to: left-1, by: -1) where arr.count < count {
arr.append(matrix[bottom][i])
}
bottom -= 1
for i in stride(from: bottom, to: top-1, by: -1) where arr.count < count {
arr.append(matrix[i][left])
}
left += 1
}
return arr
}
}