본문 바로가기
LeetCode/Array & Hashing

[LeetCode][Kotlin] 2870. Minimum Number of Operations to Make Array Empty

by jinwo_o 2024. 9. 5.

 

2870. Minimum Number of Operations to Make Array Empty

You are given a 0-indexed array nums consisting of positive integers.

There are two types of operations that you can apply on the array any number of times:

  • Choose two elements with equal values and delete them from the array.
  • Choose three elements with equal values and delete them from the array.

Return the minimum number of operations required to make the array empty, or -1 if it is not possible.

양의 정수로 구성된 0-인덱스 배열 숫자가 제공됩니다. 

배열에 여러 번 적용할 수 있는 작업에는 두 가지 유형이 있습니다. 
- 동일한 값을 가진 두 요소를 선택하고 배열에서 삭제합니다. 
- 동일한 값을 가진 세 개의 요소를 선택하고 배열에서 삭제합니다. 

배열을 비우는 데 필요한 최소 작업 수를 반환하거나, 불가능할 경우 -1을 반환합니다.

 

Example 1:

Input: nums = [2,3,3,2,2,4,2,3,4]

Output: 4

Explanation: We can apply the following operations to make the array empty:

- Apply the first operation on the elements at indices 0 and 3. The resulting array is nums = [3,3,2,4,2,3,4].

- Apply the first operation on the elements at indices 2 and 4. The resulting array is nums = [3,3,4,3,4].

- Apply the second operation on the elements at indices 0, 1, and 3. The resulting array is nums = [4,4].

- Apply the first operation on the elements at indices 0 and 1. The resulting array is nums = [].

It can be shown that we cannot make the array empty in less than 4 operations.

 

Example 2:

Input: nums = [2,1,2,2,3,3]

Output: -1

Explanation: It is impossible to empty the array.

 

Constraints:

  • 2 <= nums.length <= 10^5
  • 1 <= nums[i] <= 10^6

코드 1

  • 배열의 원소 개수 세기
  • 1을 제외한 나머지는 2와 3으로 만들 수 있다.
  • 3으로 나눈 나머지가 없는 경우는 배열을 비우는 데 필요한 최소 작업 수를 나타낸다.
class Solution {
    fun minOperations(nums: IntArray): Int {
        val hm = HashMap<Int, Int>()
        nums.forEach { hm[it] = hm.getOrDefault(it, 0) + 1 }

        var answer = 0
        hm.values.forEach { value ->
            if (value == 1) {
                return -1
            }

            var v = value
            while (true) {
                if (v % 3 == 0) {
                    answer += v / 3
                    break
                }
                v -= 2
                answer += 1
            }
        }

        return answer
    }
}

 

코드 2

  • 최소 작업 수를 구하기 위해 3으로 먼저 나누면, 나머지가 1인 경우가 존재한다. 예시: 4 % 3 = 1
  • 하지만 3으로 나눈 몫과 3으로 나눈 나머지를 개수로 보면, 2로 나눈 몫과 2로 나눈 나머지의 개수와 같다.
class Solution {
    fun minOperations(nums: IntArray): Int {
        val hm = HashMap<Int, Int>()
        nums.forEach { hm[it] = hm.getOrDefault(it, 0) + 1 }

        var answer = 0
        hm.values.forEach { value ->
            if (value == 1) {
                return -1
            }
            answer += Math.ceil(value.toDouble() / 3).toInt()
        }

        return answer
    }
}