Welcome to Subscribe On Youtube

2611. Mice and Cheese

Description

There are two mice and n different types of cheese, each type of cheese should be eaten by exactly one mouse.

A point of the cheese with index i (0-indexed) is:

  • reward1[i] if the first mouse eats it.
  • reward2[i] if the second mouse eats it.

You are given a positive integer array reward1, a positive integer array reward2, and a non-negative integer k.

Return the maximum points the mice can achieve if the first mouse eats exactly k types of cheese.

 

Example 1:

Input: reward1 = [1,1,3,4], reward2 = [4,4,1,1], k = 2
Output: 15
Explanation: In this example, the first mouse eats the 2nd (0-indexed) and the 3rd types of cheese, and the second mouse eats the 0th and the 1st types of cheese.
The total points are 4 + 4 + 3 + 4 = 15.
It can be proven that 15 is the maximum total points that the mice can achieve.

Example 2:

Input: reward1 = [1,1], reward2 = [1,1], k = 2
Output: 2
Explanation: In this example, the first mouse eats the 0th (0-indexed) and 1st types of cheese, and the second mouse does not eat any cheese.
The total points are 1 + 1 = 2.
It can be proven that 2 is the maximum total points that the mice can achieve.

 

Constraints:

  • 1 <= n == reward1.length == reward2.length <= 105
  • 1 <= reward1[i], reward2[i] <= 1000
  • 0 <= k <= n

Solutions

Solution 1: Greedy + Sort

We can first give all the cheese to the second mouse. Next, consider giving $k$ pieces of cheese to the first mouse. How should we choose these $k$ pieces of cheese? Obviously, if we give the $i$-th piece of cheese from the second mouse to the first mouse, the change in the score is $reward1[i] - reward2[i]$. We hope that this change is as large as possible, so that the total score is maximized.

Therefore, we sort the cheese in decreasing order of reward1[i] - reward2[i]. The first $k$ pieces of cheese are eaten by the first mouse, and the remaining cheese is eaten by the second mouse to obtain the maximum score.

Time complexity $O(n \times \log n)$, space complexity $O(n)$. Where $n$ is the number of cheeses.

Solution 2

This implementation uses sorting. It traverses the relevant values and updates its state as each value is processed. Ordering the data first makes the subsequent comparisons deterministic. After all required states have been considered, the maintained result is returned.

  • class Solution {
        public int miceAndCheese(int[] reward1, int[] reward2, int k) {
            int n = reward1.length;
            Integer[] idx = new Integer[n];
            for (int i = 0; i < n; ++i) {
                idx[i] = i;
            }
            Arrays.sort(idx, (i, j) -> reward1[j] - reward2[j] - (reward1[i] - reward2[i]));
            int ans = 0;
            for (int i = 0; i < k; ++i) {
                ans += reward1[idx[i]];
            }
            for (int i = k; i < n; ++i) {
                ans += reward2[idx[i]];
            }
            return ans;
        }
    }
    
    
    // Solution 2
    class Solution {
        public int miceAndCheese(int[] reward1, int[] reward2, int k) {
            int ans = 0;
            int n = reward1.length;
            for (int i = 0; i < n; ++i) {
                ans += reward2[i];
                reward1[i] -= reward2[i];
            }
            Arrays.sort(reward1);
            for (int i = 0; i < k; ++i) {
                ans += reward1[n - i - 1];
            }
            return ans;
        }
    }
    
    
  • class Solution {
    public:
        int miceAndCheese(vector<int>& reward1, vector<int>& reward2, int k) {
            int n = reward1.size();
            vector<int> idx(n);
            iota(idx.begin(), idx.end(), 0);
            sort(idx.begin(), idx.end(), [&](int i, int j) { return reward1[j] - reward2[j] < reward1[i] - reward2[i]; });
            int ans = 0;
            for (int i = 0; i < k; ++i) {
                ans += reward1[idx[i]];
            }
            for (int i = k; i < n; ++i) {
                ans += reward2[idx[i]];
            }
            return ans;
        }
    };
    
    
    // Solution 2
    class Solution {
    public:
        int miceAndCheese(vector<int>& reward1, vector<int>& reward2, int k) {
            int n = reward1.size();
            int ans = 0;
            for (int i = 0; i < n; ++i) {
                ans += reward2[i];
                reward1[i] -= reward2[i];
            }
            sort(reward1.rbegin(), reward1.rend());
            ans += accumulate(reward1.begin(), reward1.begin() + k, 0);
            return ans;
        }
    };
    
    
  • class Solution:
        def miceAndCheese(self, reward1: List[int], reward2: List[int], k: int) -> int:
            n = len(reward1)
            idx = sorted(range(n), key=lambda i: reward1[i] - reward2[i], reverse=True)
            return sum(reward1[i] for i in idx[:k]) + sum(reward2[i] for i in idx[k:])
    
    
    # Solution 2
    class Solution:
        def miceAndCheese(self, reward1: List[int], reward2: List[int], k: int) -> int:
            for i, x in enumerate(reward2):
                reward1[i] -= x
            reward1.sort(reverse=True)
            return sum(reward2) + sum(reward1[:k])
    
    
  • func miceAndCheese(reward1 []int, reward2 []int, k int) (ans int) {
    	n := len(reward1)
    	idx := make([]int, n)
    	for i := range idx {
    		idx[i] = i
    	}
    	sort.Slice(idx, func(i, j int) bool {
    		i, j = idx[i], idx[j]
    		return reward1[j]-reward2[j] < reward1[i]-reward2[i]
    	})
    	for i := 0; i < k; i++ {
    		ans += reward1[idx[i]]
    	}
    	for i := k; i < n; i++ {
    		ans += reward2[idx[i]]
    	}
    	return
    }
    
    
    // Solution 2
    func miceAndCheese(reward1 []int, reward2 []int, k int) (ans int) {
    	for i, x := range reward2 {
    		ans += x
    		reward1[i] -= x
    	}
    	sort.Ints(reward1)
    	n := len(reward1)
    	for i := 0; i < k; i++ {
    		ans += reward1[n-i-1]
    	}
    	return
    }
    
    
  • function miceAndCheese(reward1: number[], reward2: number[], k: number): number {
        const n = reward1.length;
        const idx = Array.from({ length: n }, (_, i) => i);
        idx.sort((i, j) => reward1[j] - reward2[j] - (reward1[i] - reward2[i]));
        let ans = 0;
        for (let i = 0; i < k; ++i) {
            ans += reward1[idx[i]];
        }
        for (let i = k; i < n; ++i) {
            ans += reward2[idx[i]];
        }
        return ans;
    }
    
    
    // Solution 2
    function miceAndCheese(reward1: number[], reward2: number[], k: number): number {
        const n = reward1.length;
        let ans = 0;
        for (let i = 0; i < n; ++i) {
            ans += reward2[i];
            reward1[i] -= reward2[i];
        }
        reward1.sort((a, b) => b - a);
        for (let i = 0; i < k; ++i) {
            ans += reward1[i];
        }
        return ans;
    }
    
    
  • class Solution {
        public int miceAndCheese(int[] reward1, int[] reward2, int k) {
            int ans = 0;
            int n = reward1.length;
            for (int i = 0; i < n; ++i) {
                ans += reward2[i];
                reward1[i] -= reward2[i];
            }
            Arrays.sort(reward1);
            for (int i = 0; i < k; ++i) {
                ans += reward1[n - i - 1];
            }
            return ans;
        }
    }
    
  • class Solution {
    public:
        int miceAndCheese(vector<int>& reward1, vector<int>& reward2, int k) {
            int n = reward1.size();
            int ans = 0;
            for (int i = 0; i < n; ++i) {
                ans += reward2[i];
                reward1[i] -= reward2[i];
            }
            sort(reward1.rbegin(), reward1.rend());
            ans += accumulate(reward1.begin(), reward1.begin() + k, 0);
            return ans;
        }
    };
    
  • class Solution:
        def miceAndCheese(self, reward1: List[int], reward2: List[int], k: int) -> int:
            for i, x in enumerate(reward2):
                reward1[i] -= x
            reward1.sort(reverse=True)
            return sum(reward2) + sum(reward1[:k])
    
    
  • func miceAndCheese(reward1 []int, reward2 []int, k int) (ans int) {
    	for i, x := range reward2 {
    		ans += x
    		reward1[i] -= x
    	}
    	sort.Ints(reward1)
    	n := len(reward1)
    	for i := 0; i < k; i++ {
    		ans += reward1[n-i-1]
    	}
    	return
    }
    
  • function miceAndCheese(reward1: number[], reward2: number[], k: number): number {
        const n = reward1.length;
        let ans = 0;
        for (let i = 0; i < n; ++i) {
            ans += reward2[i];
            reward1[i] -= reward2[i];
        }
        reward1.sort((a, b) => b - a);
        for (let i = 0; i < k; ++i) {
            ans += reward1[i];
        }
        return ans;
    }
    
    

All Problems

All Solutions