LeetCode in Kotlin

3947. Maximum Number of Items From Sale II

Medium

You are given a 2D integer array items, where items[i] = [factori, pricei] represents the ith item. You are also given an integer budget.

There are unlimited copies of each item available for purchase. You may buy any number of copies of any items such that the total cost of the purchased copies is at most budget.

After buying items, you may receive free copies according to the following rules:

Return the maximum total number of item copies you can obtain, including both purchased copies and free copies, while spending at most budget on purchased items.

Example 1:

Input: items = [[1,6],[2,4],[3,5]], budget = 19

Output: 5

Explanation:

Example 2:

Input: items = [[2,8],[1,10],[6,6],[4,12],[5,20],[5,17]], budget = 35

Output: 7

Explanation:

Constraints:

Solution

import kotlin.math.min

class Solution {
    fun maximumSaleItems(items: Array<IntArray>, budget: Int): Int {
        var budget = budget
        val n = items.size
        val count = IntArray(n + 1)
        var min = Long.MAX_VALUE
        for (item in items) {
            count[item[0]]++
            if (item[1] < min) {
                min = item[1].toLong()
            }
        }
        val temp = IntArray(n + 1)
        for (i in 1..n) {
            if (count[i] > 0) {
                var m = -1
                var j = i
                while (j <= n) {
                    m += count[j]
                    j += i
                }
                temp[i] = m
            }
        }
        val deal = LongArray(n)
        var dealcount = 0
        val limit = min * 2
        for (item in items) {
            val first = item[0]
            val second = item[1]
            if (second < limit) {
                val m = temp[first]
                if (m > 0) {
                    deal[dealcount++] = (second.toLong() shl 32) or (m.toLong() and 0xFFFFFFFFL)
                }
            }
        }
        deal.sort(0, dealcount)
        var total: Long = 0
        for (i in 0..<dealcount) {
            val deals = deal[i]
            val m = (deals ushr 32).toInt()
            val counts = (deals and 0xFFFFFFFFL).toInt()
            if (budget >= m) {
                val time = min(counts.toLong(), (budget / m).toLong())
                budget = (budget - (time * m)).toInt()
                total += 2 * time
            }
        }
        total += budget / min
        return total.toInt()
    }
}