[Swift] [44일차] 1630_LEET

·2025년 1월 20일
0

SwiftAlgorithm

목록 보기
47/105
post-thumbnail

1630. Arithmetic Subarrays


문제설명

  1. arithmetic- 등차수열 찾기
  2. 수열이랑 함께 ,l,r배열도 주어지는데, 여기서 l[i] ~ r[i] 에해당하는게 등차수열인지 3. 판단해서 하나씩 배열에 넣어주면 끝

문제 풀이

1. 일단 l,r기준으로 배열을 잘라줄 수 있는가 ?

var test = nums[l[i] ... r[i]].map { Int($0) } // 대상이 되는 순열 먼저 잘라주기

이런식으로 수행을 해줬다 근데 이렇게 배열 슬라이싱을 수행하면 SubSequence으로 변환되다보니, 다시 [Int]로 만들기위해서 map을 한번 돌려줬다.

2. 어떻게 등차수열인지를 판단해줄 것이냐?

이런 로직이 필요한 것은 가독성때문에 함수를 하나 선언해주는 걸 좋아해서, isArithmetic이라는 함수를 만들어줘서 수행했다.
먼저 정렬을 해준다음에 등차를 구하고, 거기서 함께 반복문을 돌아가면서

첫항 + (index * 등차)에 적합한지를 차례대로 판단해주는 것이다.

func isArithmetic(_ arr: [Int]) -> Bool {
    var arr = arr.sorted(by: <)
    let 등차 = arr[1] - arr[0]
    var first = arr[0]
    for (idx, value) in arr.enumerated() {
        if value != first + (idx * 등차) {
            return false
        }
    }
    return true
}

이제 이걸 조립하면...

최종 제출

func isArithmetic(_ arr: [Int]) -> Bool {
    var arr = arr.sorted(by: <)
    let 등차 = arr[1] - arr[0]
    var first = arr[0]
    for (idx, value) in arr.enumerated() {
        if value != first + (idx * 등차) {
            return false
        }
    }
    return true
}

class Solution {
    func checkArithmeticSubarrays(_ nums: [Int], _ l: [Int], _ r: [Int]) -> [Bool] {
        var answer = [Bool]()
        for i in 0 ..< l.count { // l도 되고 r도 상관없음
            var test = nums[l[i] ... r[i]].map { Int($0) } // 대상이 되는 순열 먼저 잘라주기
            answer.append(isArithmetic(test))
        }
        return answer
    }
}

결과


타인의 코드

class Solution {
    func checkArithmeticSubarrays(_ nums: [Int], _ l: [Int], _ r: [Int]) -> [Bool] {
        var res = [Bool]()
        for i in 0..<l.count {
            res.append(isArithmetic(nums, l[i], r[i]))
        }
        return res
    }

    func isArithmetic(_ nums: [Int], _ from: Int, _ to: Int) -> Bool {
        var maxi = Int.min
        var mini = Int.max
        for i in from...to {
            maxi = max(nums[i], maxi)
            mini = min(nums[i], mini)
        }

        if maxi == mini {
            return true
        }
        
        if (maxi - mini) % (to - from) != 0 {
            return false
        }

        let distance = (maxi - mini) / (to - from)
        let len = to - from + 1
        var hasBeenFilledAt = Array(repeating: false, count: len)
        for i in from...to {
            
            if (nums[i] - mini) % distance != 0 {
                return false
            }

            let pos = (nums[i] - mini) / distance
    
            if hasBeenFilledAt[pos] {
                return false
            }

            hasBeenFilledAt[pos] = true
        }
        return true
    }
}
  1. MAX,MIN값이 같으면 일정한 등차수열
  2. MAX-MIN이 등차로 깔끔하게 안나눠지면 등차수열이 아닌 것
  3. hasBeenFilledAt으로 이미 들어온 친구가 있다면 중복은 허용이 안되기 때문에 false(이전에 다 같은 순열인것은 미리 판단을 해준 상태라 가능)
  4. 해당 코드는 sorting을 전혀안해준 상태로 그냥 최댓값 최솟값, 등차로 판단을 전부해줬기 때문에 내 코드보다 훨씬 빠르게 수행이 된 것 같다.

이런 수학 관련 문제는 공식이나, 좀 더 성질을 잘 파악해서 풀이하는게 중요한듯 ..

profile
기억보단 기록을

0개의 댓글