https://leetcode.com/problems/add-digits/

 

Add Digits - LeetCode

Level up your coding skills and quickly land a job. This is the best place to expand your knowledge and get prepared for your next interview.

leetcode.com

풀이를 시작해보자!!

나는 아래와 같이 풀이를 했었다.

일단, num 이 0이거나 음수면 return 0을 하기로 했다. 문제의 조건대로.

 

그런다음에, 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
        
    }
}

 

 

..... 정말 잘 짜셨다.AsahiOcean!! 

너무 깔끔하다...!!

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
    }
}

'Algorithm > Leetcode' 카테고리의 다른 글

Leetcode_Robot-return-to-origin  (0) 2022.06.30
Leetcode_fizz-buzz  (0) 2022.06.30
Leetcode_Add Strings  (0) 2022.06.30
Leetcode_convert-1d-array-into-2d-array  (0) 2022.06.29
Leetcode_Add Bianary  (0) 2022.06.29

https://leetcode.com/problems/add-strings/

 

Add Strings - LeetCode

Level up your coding skills and quickly land a job. This is the best place to expand your knowledge and get prepared for your next interview.

leetcode.com

 

풀이를 하면 이렇다.

 

음... 일단, 문제 조건 자체가 String -> Int -> String 하지마라!!

이것이기 때문에, 나는 다른 방향으로 진행해야한다.

오케이,  그러면 직접 하는 수 밖에 없다...

 

일단, 받은 String을 Array로 변환 시킨다. 

그리고, reversed()를 하면, 

func reversed() -> ReversedCollection<Self>

ReversedCollenction<Self> 타입을 반환한다.

 

이것을 다시 Array타입으로 변형 시켜준다.

왜냐하면, 아래 부분에서 Int("\(num1[i])")! :  0

여기에서 \() 이것을 사용하려면, Array type이 필요하다.

 

계속 이어가자. 

지금 까지는

"123" -> ["1","2",3"]

 이렇게 만든 것이고

 

이제는 문제대로 두개의 String을 받아서 더해야한다.

한개 한개

문제점 1)

근데, 여기서 "123", "11" 이렇게 두개의 String을 받는 다고 할때에는 

"11"이 한 자리 수가 부족하기 때문에 에러가 발생할 것이다. 

그렇다면, 그것을 아래와 같이 해결하자.

 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에 넣을 수 있게 하는 것.

마지막에, res가 Character를 가지는 배열이기 때문에 reversed가 가능하고

String으로 변환하여 값을 도출함.

 

전체적인 타입 역사는 하기와 같음.

String -> Array -> Reversed Collections -> [Character]

-> String -> Int -> String -> Character

-> Reversed Collections -> String

func addStrings(_ num1: String, _ num2: String) -> String {
        let chs1: [Character] = Array(num1).reversed()
        let chs2: [Character] = Array(num2).reversed()
        var isOne = 0
        var res = [Character]()
        var i = 0
        var j = 0 
     
        while i < chs1.count || j < chs2.count || isOne == 1 {
            let c1 = i < chs1.count ? Int(String(chs1[i]))! : 0
            let c2 = j < chs2.count ? Int(String(chs2[j]))! : 0

            let s = (c1 + c2 + isOne) % 10
            isOne = (c1 + c2 + isOne) / 10
            i += 1
            j += 1
            res.append(Character(String(s)))
        }
        return String(res.reversed())
}

하기 해결책도 비슷하다.

 

일단, 이것은 String을 받자마자 reversed()를 했다. 이것을 [Character]에 담았다.

특이하다. 위에는 String을 Array로 그리고 reversed()를 해주었다.

하지만, 여기에는 String을 바로 reversed()해주었다.

 

Line 3: Char 12: error: value of type 'String' has no member 'reveresed' in solution.swift
print(num1.reveresed())

 

역시... String은 reversed() Method가 없다. 근데, 왜 아래와 같이 코딩을 해도 괜찮았을까?

 

[Character] 이 영향인 것같다. 

Array에 감싸 있으니깐, 가능한 것같다.

 

계속 가보자.

이 솔루션에도 i, j,sum, carry가 존재한다.

그리고 이것들이 while 함수 밖에 있다는 것이 포인트!!

 

그리고 재미있는 거!!

이 사람 재미있게 코드를 짜네!

if i < num1chars.count, num1chars[i].isNumbber{

}

이 부분에서 if 문에 연달아서 저렇게 쓰는 건 이번에 처음 보는데,

저게 이런 뜻이다. i 가 num~~보다 크고 num1~가 숫자가 존재하면 함수를 실행해라.

 

var i = 0

if i < 2, false{
    print(i)
    print("false")
}

if i < 2, true{
    print(i)
    print("true")
}



//이 프로그램을 실행시켜도 아래 하나만 출력이 된다.
0
true

 

여기도, 눈 여겨 봐야할 점은 num1chars[]를 String으로 감싸고 Int로 변환했다.

 

 

 

나머지는 비슷한 맥락이라 넘어가자.

class Solution {
    func addStrings(_ num1: String, _ num2: String) -> String {
        
        let num1chars = [Character](num1.reversed())
        let num2chars = [Character](num2.reversed())
        
        var i = 0, j = 0, sum = 0, carry = 0
        var value: String = ""
        
        while i < num1chars.count || j < num2chars.count || carry != 0 {
            sum = carry
            
            if i < num1chars.count, num1chars[i].isNumber {
                sum += Int(String(num1chars[i]))!
                i += 1
            }
            if j < num2chars.count, num2chars[j].isNumber {
                sum += Int(String(num2chars[j]))!
                j += 1
            }
            
            carry = sum / 10
            sum = sum % 10
            
            value.append(String(sum))
        }
        
        return String(value.reversed())
    }
}

아래도, String을 Array로 전환을 해준다.

carry도 선언했고 다른점은

이것은 reversed()를 안했고 removeLast()를 사용했다.

 

removeLast()는 저렇게 아래와 같이 쓴다면,

A = [1,2,3].removeLast()

A = 3이 된다.

그리고 원래 배열은 [1,2]가 된다.

class Solution {
func addStrings(_ num1: String, _ num2: String) -> String {
      var num1 = Array(num1)
      var num2 = Array(num2)
      
      var carry = 0
      var result = ""
      
      while !num1.isEmpty || !num2.isEmpty {
          let val1 = num1.isEmpty ? "0" : num1.removeLast()
          let val2 = num2.isEmpty ? "0" : num2.removeLast()
          
          let sum = Int(String(val1))! + Int(String(val2))! + carry
          
          result.append("\(sum%10)")
          carry = sum / 10
      }
      
      if carry != 0 {
          result.append("\(carry)")
      }
      
      return String(result.reversed())
  }

}

'Algorithm > Leetcode' 카테고리의 다른 글

Leetcode_fizz-buzz  (0) 2022.06.30
Leetcode_Add digits  (0) 2022.06.30
Leetcode_convert-1d-array-into-2d-array  (0) 2022.06.29
Leetcode_Add Bianary  (0) 2022.06.29
Leet Code_Spiral  (0) 2022.06.29

https://leetcode.com/problems/convert-1d-array-into-2d-array/

 

Convert 1D Array Into 2D Array - LeetCode

Level up your coding skills and quickly land a job. This is the best place to expand your knowledge and get prepared for your next interview.

leetcode.com

시뮬레이션 공부하기 좋은 문제라고 생각한다.

 

한개 한개 어떻게 구현될지 고민한다음에 생각해서 코딩하니깐, 사고력이 좋아지는 느낌이 든다.

 

일단, 문제를 읽어보면 [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
}

 

'Algorithm > Leetcode' 카테고리의 다른 글

Leetcode_fizz-buzz  (0) 2022.06.30
Leetcode_Add digits  (0) 2022.06.30
Leetcode_Add Strings  (0) 2022.06.30
Leetcode_Add Bianary  (0) 2022.06.29
Leet Code_Spiral  (0) 2022.06.29

https://leetcode.com/problems/add-binary/

 

Add Binary - LeetCode

Level up your coding skills and quickly land a job. This is the best place to expand your knowledge and get prepared for your next interview.

leetcode.com

 

나는 이 문제를 String(number,radix: n)으로 풀이할 생각을 잠깐 했었다.

 

하지만, 큰 착오였다. Int(number,radix:n)으로 해야한다!!

 

풀이에 대해 조금 설명하면, 

 

나는 처음에 이렇게 생각을 했다. a는 string 타입의 11이다. 이것을 String 타입 캐스팅하고 2진법으로 바꾸게 되면, 1011이다.

 

문제가 원하는 것은 11에서 3이 되는 것이다.  

 

그러니깐, Int()를 사용해야한다. 

 

아무래도, 이전에 풀었던 문제에서 String()을 사용해서 아무래도 앞선 해결책이 생각난 것 같다.

 

a는 string 타입의 11이다. 이것을 Int로 형변환을 하면 3이다. 

 

아래는 Leetcode에서 좋은 풀이라고 생각해서 hafizu님의 풀이를 가져왔다.

아래 코드가 좋다고 생각한 이유는 사람이 보기 편안하게 구현한 것같다.

예로 들자면,  이진법끼리 계산 할 경우는 4가지 밖에 없다.

0,0 

1,0

0,1

1,1

첫 번째 경우 일때에, 만약 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)
}
}

'Algorithm > Leetcode' 카테고리의 다른 글

Leetcode_fizz-buzz  (0) 2022.06.30
Leetcode_Add digits  (0) 2022.06.30
Leetcode_Add Strings  (0) 2022.06.30
Leetcode_convert-1d-array-into-2d-array  (0) 2022.06.29
Leet Code_Spiral  (0) 2022.06.29

https://leetcode.com/problems/spiral-matrix/

 

Spiral Matrix - LeetCode

Level up your coding skills and quickly land a job. This is the best place to expand your knowledge and get prepared for your next interview.

leetcode.com

 

메트릭스가 주어지면,

왼쪽에서 오른쪽까지 위에서 아래까지 계속!!!! 반복

 

여기서 얻어야할 포인트는 언젠가는 끝날 것인데, 이것을 프로그래밍 적으로 어떻게 구현할 것인가를 고민하면 된다.

 

생각해 보면, 반환해야하는 값이 결국에는 메트릭스의 아이템의 갯수와 같다.

 

예로, [[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
}
}

 

 

'Algorithm > Leetcode' 카테고리의 다른 글

Leetcode_fizz-buzz  (0) 2022.06.30
Leetcode_Add digits  (0) 2022.06.30
Leetcode_Add Strings  (0) 2022.06.30
Leetcode_convert-1d-array-into-2d-array  (0) 2022.06.29
Leetcode_Add Bianary  (0) 2022.06.29

+ Recent posts