οΉ₯

Leetcode 1497. Check If Array Pairs Are Divisible by k (Python3)

@λ‚¨μ œμ΄ Β· 2024λ…„ 07μ›” 04일 Β· 2λΆ„
problem_solvingleetcodepython

문제 링크

https://leetcode.com/problems/check-if-array-pairs-are-divisible-by-k/

문제 μš”μ•½

μ›μžκ°€ 숫자인 λ°°μ—΄ arr 이 있고 λ°°μ—΄μ˜ 길이인 n 은 짝수이고 k κ°€ 주어진닀.
μ΄λ•Œ, 배열을 μ •ν™•ν•˜κ²Œ n/2 의 pair κ°€ λ˜μ–΄μ•Ό ν•˜κ³  pair κ°€ 된 숫자의 ν•© 이 k 둜 λ‚˜λˆ„μ–΄μ Έμ•Ό ν•œλ‹€.

λ”°λΌμ„œ, λ°°μ—΄μ—μ„œ 두 개의 숫자λ₯Ό 골라 κ·Έ 합이 k 둜 λ‚˜λˆ„μ–΄μ§€λ©΄ pair κ°€ 되고
λ°°μ—΄μ˜ λͺ¨λ“  μ›μ†Œκ°€ pair κ°€ 되면 True, μ•„λ‹ˆλ©΄ False λ₯Ό 좜λ ₯ν•˜λ©΄ λœλ‹€.


( arr[a] + arr[b] ) // k == True
( arr[a] + arr[b] ) // k != False

문제 풀이

μ²˜μŒμ—λŠ” ν•˜λ‚˜μ˜ μ›μ†Œλ₯Ό 가져와 λ‹€λ₯Έ μ›μ†Œμ™€ 비ꡐ해가며 두 수의 합이 k 둜 λ‚˜λˆ„μ–΄μ§„λ‹€λ©΄ True, 그렇지 μ•Šλ‹€λ©΄ False 둜 ν’€λ €κ³  ν–ˆμ—ˆλ‹€.
ν•˜μ§€λ§Œ μ΄λ ‡κ²Œ ν’€κ²Œ 되면 μ‹œκ°„ λ³΅μž‘λ„κ°€ O(n^2) 이 λ˜μ–΄ μ‹œκ°„ μ œν•œ 초과둜 μ‹€νŒ¨ν•˜κ²Œ λ˜μ—ˆλ‹€.


  • 잘λͺ»λœ 제좜 μ½”λ“œ

    class Solution:
        def canArrange(self, arr: List[int], k: int) -> bool:
            for i in range(len(arr)):
                check = False
    
                for j in range(len(arr)):
                    sum_args = arr[i] + arr[j]
    
                    if sum_args % k == 0:
                        arr[i] = 0
                        arr[j] = 0
    
                        check = True
    
                if check is False:
                    return False
    
            return True

  • 제좜 κ²°κ³Ό

    image



κ·Έλž˜μ„œ μ²˜μŒλΆ€ν„° λ‹€μ‹œ μ ‘κ·Όν•˜κ²Œ λ˜μ—ˆλ‹€.

두 수의 합이 k 둜 λ‚˜λˆ„μ–΄μ Έμ•Ό ν•œλ‹€.

μœ„μ˜ 말을 쑰금 더 ν’€μ–΄μ„œ μ„€λͺ…ν•˜μžλ©΄ 각 숫자의 λ‚˜λ¨Έμ§€μ˜ 합이 0 λ˜λŠ” k κ°€ λœλ‹€λ©΄ k 둜 λ‚˜λˆ„μ–΄μ§„λ‹€κ³  말할 수 있게 λœλ‹€.

κ·Έλž˜μ„œ 2κ°€μ§€μ˜ μΌ€μ΄μŠ€λ‘œ ꡬ뢄해볼 수 μžˆμ—ˆλ‹€.

  1. λ‚˜λ¨Έμ§€μ˜ 합이 0 인 경우
    λ‚˜λ¨Έμ§€μ˜ 합이 0 μ΄λΌλŠ” 말은 두 수의 합이 k 둜 λ‚˜λˆ„μ–΄μ§„λ‹€λŠ” 말이 λ˜μ–΄ pair κ°€ λœλ‹€.
  2. λ‚˜λ¨Έμ§€μ˜ 합이 k 인 경우
    λ‚˜λ¨Έμ§€μ˜ 합을 λ‹€μ‹œ k 둜 λ‚˜λˆ„κ²Œ λ˜μ–΄ 0 이 λœλ‹€λ©΄ k 둜 λ‚˜λˆ„μ–΄μ§ˆ 수 μžˆλ‹€λ©΄ pair κ°€ λœλ‹€.

이 말을 μ‹μœΌλ‘œ λ‚˜νƒ€λ‚΄λ³΄μžλ©΄ λ‹€μŒκ³Ό κ°™λ‹€.

(a % k) + ( b % k ) % k == 0

예λ₯Ό λ“€μ–΄ μ„€λͺ…해보면 더 이해가 μ‰¬μšΈ 것 κ°™μ•„μ„œ 예λ₯Ό λ“€μ–΄λ³΄μ•˜λ‹€.
λ§Œμ•½ k 의 값이 5 이고 λ°°μ—΄ [1, 3, 5, 7, 9] κ°€ μžˆλ‹€κ³  ν•  λ•Œ 두 개의 숫자 3 κ³Ό 7 을 κ°€μ Έμ™€μ„œ pair κ°€ λ˜λŠ”μ§€ 확인해본닀고 κ°€μ •ν•˜μž.

λ¨Όμ € 두 수의 λ‚˜λ¨Έμ§€λ₯Ό κ΅¬ν•œλ‹€.

3 % 5 = 3
7 % 5 = 2

λ‹€μŒμœΌλ‘œ 두 수의 λ‚˜λ¨Έμ§€ 합을 κ΅¬ν•œλ‹€.

3 + 2 = 5

두 수의 λ‚˜λ¨Έμ§€μ˜ 합이 5 == k μ΄λ―€λ‘œ 3 κ³Ό 7 은 k 인 5 둜 λ‚˜λˆ„μ–΄μ§€λŠ” pair κ°€ 될 수 μžˆλ‹€.

ν•˜λ‚˜μ˜ 예λ₯Ό 더 λ“€μžλ©΄, 5 와 10 이 μ‘΄μž¬ν•œλ‹€κ³  ν•  경우 두 수의 λ‚˜λ¨Έμ§€λŠ” 0, 0 이 되고
λ‚˜λ¨Έμ§€μ˜ 합이 0이기 λ•Œλ¬Έμ— k 둜 λ‚˜λˆ„μ–΄μ§€λŠ” pair 라고 ν•  수 μžˆλ‹€.

κ·Έλž˜μ„œ 결둠은 μ–΄λ–€ 숫자의 λ‚˜λ¨Έμ§€ remain 이 μžˆμ„ λ•Œ k - remain 의 합이 0 λ˜λŠ” k 라면 pair κ°€ λœλ‹€κ³  κ°€μ •ν•  수 μžˆλ‹€.

그리고 μ—¬κΈ°μ„œ ν•œ 가지 더 μ€‘μš”ν•œ 점은 pair λΌλŠ” 말은 짝수이기 λ•Œλ¬Έμ— 짝수 만큼의 μˆ«μžκ°€ μ—†λ‹€λ©΄ pair κ°€ 될 수 μ—†λ‹€λŠ” 점도 μœ μ˜ν•΄μ•Ό ν•œλ‹€.



μ΄λŸ¬ν•œ 과정을 μ½”λ“œλ‘œ ν’€μ–΄μ„œ μ μ–΄λ³΄μ•˜λ‹€.

λ¨Όμ €, λ°°μ—΄ μ•ˆμ— μžˆλŠ” μˆ«μžλ“€μ˜ λ‚˜λ¨Έμ§€μ˜ 갯수λ₯Ό μ„Έμ–΄μ£Όμ—ˆλ‹€.

remain_count = {i:0 for i in range(k)}

for num in arr:
    k_remain = num % k
    remain_count[k_remain] += 1

μ΄λ•Œ, key 의 값은 k 의 λ‚˜λ¨Έμ§€ κ°’μ˜ λ²”μœ„μΈ 0 ~ k-1 이 λœλ‹€.

이제 μœ„μ—μ„œ λ§ν•œ 2가지 κ²½μš°μ— λŒ€ν•΄μ„œ μ½”λ“œλ‘œ μž‘μ„±ν•΄μ£Όλ©΄ λœλ‹€.

for remain in remain_count.keys():
# k 둜 λ‚˜λˆ„μ–΄μ§€λŠ” 수인 경우(λ‚˜λ¨Έμ§€κ°€ 0인 경우)
# pair λ₯Ό λ§Œλ“€κΈ° μœ„ν•΄μ„œ 짝수 κ°œκ°€ ν•„μš”ν•˜λ‹€.
if remain == 0:
    if remain_count[remain] % 2 != 0:
        return False
else:
    # λ‚˜λ¨Έμ§€μ˜ 합이 k κ°€ λ˜μ–΄μ•Ό ν•˜κΈ° λ•Œλ¬Έμ— (λ‚˜λ¨Έμ§€) 의 κ°œμˆ˜μ™€ (k - λ‚˜λ¨Έμ§€) 의 κ°œμˆ˜κ°€ κ°™μ•„μ•Ό pair κ°€ λœλ‹€.
    if remain_count[remain] != remain_count[k - remain]:
        return False

제좜 λ‹΅μ•ˆ

class Solution:
    def canArrange(self, arr: List[int], k: int) -> bool:
        remain_count = {i:0 for i in range(k)}

        for num in arr:
            k_remain = num % k
            remain_count[k_remain] += 1

        for remain in remain_count.keys():
            # k 둜 λ‚˜λˆ„μ–΄μ§€λŠ” 수인 경우(λ‚˜λ¨Έμ§€κ°€ 0인 경우)
            # pair λ₯Ό λ§Œλ“€κΈ° μœ„ν•΄μ„œ 짝수 κ°œκ°€ ν•„μš”ν•˜λ‹€.
            if remain == 0:
                if remain_count[remain] % 2 != 0:
                    return False
            else:
                # λ‚˜λ¨Έμ§€μ˜ 합이 k κ°€ λ˜μ–΄μ•Ό ν•˜κΈ° λ•Œλ¬Έμ— (λ‚˜λ¨Έμ§€) 의 κ°œμˆ˜μ™€ (k - λ‚˜λ¨Έμ§€) 의 κ°œμˆ˜κ°€ κ°™μ•„μ•Ό pair κ°€ λœλ‹€.
                if remain_count[remain] != remain_count[k - remain]:
                    return False

        return True