class Solution {
public:
int minimumTime(vector<int>& nums1, vector<int>& nums2, int x) {
}
};
6987. 使数组和小于等于 x 的最少时间
给你两个长度相等下标从 0 开始的整数数组 nums1
和 nums2
。每一秒,对于所有下标 0 <= i < nums1.length
,nums1[i]
的值都增加 nums2[i]
。操作 完成后 ,你可以进行如下操作:
0 <= i < nums1.length
的下标 i
,并使 nums1[i] = 0
。同时给你一个整数 x
。
请你返回使 nums1
中所有元素之和 小于等于 x
所需要的 最少 时间,如果无法实现,那么返回 -1
。
示例 1:
输入:nums1 = [1,2,3], nums2 = [1,2,3], x = 4 输出:3 解释: 第 1 秒,我们对 i = 0 进行操作,得到 nums1 = [0,2+2,3+3] = [0,4,6] 。 第 2 秒,我们对 i = 1 进行操作,得到 nums1 = [0+1,0,6+3] = [1,0,9] 。 第 3 秒,我们对 i = 2 进行操作,得到 nums1 = [1+1,0+2,0] = [2,2,0] 。 现在 nums1 的和为 4 。不存在更少次数的操作,所以我们返回 3 。
示例 2:
输入:nums1 = [1,2,3], nums2 = [3,3,3], x = 4 输出:-1 解释:不管如何操作,nums1 的和总是会超过 x 。
提示:
1 <= nums1.length <= 103
1 <= nums1[i] <= 103
0 <= nums2[i] <= 103
nums1.length == nums2.length
0 <= x <= 106
原站题解
rust 解法, 执行用时: 6 ms, 内存消耗: 2.1 MB, 提交时间: 2024-01-19 07:50:31
impl Solution { pub fn minimum_time(nums1: Vec<i32>, nums2: Vec<i32>, x: i32) -> i32 { let mut pairs = nums1.iter().zip(nums2.iter()).collect::<Vec<_>>(); pairs.sort_unstable_by(|&a, &b| a.1.cmp(&b.1)); let n = pairs.len(); let mut f = vec![0; n + 1]; for (i, &(a, b)) in pairs.iter().enumerate() { for j in (1..=i + 1).rev() { f[j] = f[j].max(f[j - 1] + a + b * j as i32); } } let s1 = nums1.iter().sum::<i32>(); let s2 = nums2.iter().sum::<i32>(); for (t, &v) in f.iter().enumerate() { if s1 + s2 * t as i32 - v <= x { return t as i32; } } -1 } }
javascript 解法, 执行用时: 127 ms, 内存消耗: 57 MB, 提交时间: 2024-01-19 07:50:16
/** * @param {number[]} nums1 * @param {number[]} nums2 * @param {number} x * @return {number} */ var minimumTime = function(nums1, nums2, x) { const pairs = _.zip(nums1, nums2).sort((a, b) => a[1] - b[1]); const n = pairs.length; const f = Array(n + 1).fill(0); for (let i = 0; i < n; i++) { const [a, b] = pairs[i]; for (let j = i + 1; j; j--) { f[j] = Math.max(f[j], f[j - 1] + a + b * j); } } const s1 = _.sum(nums1); const s2 = _.sum(nums2); for (let t = 0; t <= n; t++) { if (s1 + s2 * t - f[t] <= x) { return t; } } return -1; };
golang 解法, 执行用时: 40 ms, 内存消耗: 6.5 MB, 提交时间: 2023-08-07 16:00:58
func minimumTime(nums1, nums2 []int, x int) int { s1, s2, n := 0, 0, len(nums1) id := make([]int, n) for i := range id { id[i] = i s1 += nums1[i] s2 += nums2[i] } sort.Slice(id, func(i, j int) bool { return nums2[id[i]] < nums2[id[j]] }) f := make([]int, n+1) for _, i := range id { for j := n; j > 0; j-- { f[j] = max(f[j], f[j-1]+nums1[i]+nums2[i]*j) } } for t, v := range f { if s1+s2*t-v <= x { return t } } return -1 } func max(a, b int) int { if b > a { return b }; return a }
cpp 解法, 执行用时: 212 ms, 内存消耗: 60.9 MB, 提交时间: 2023-08-07 16:00:43
class Solution { public: int minimumTime(vector<int> &nums1, vector<int> &nums2, int x) { int n = nums1.size(); // 对下标数组排序,避免破坏 nums1 和 nums2 的对应关系 vector<int> ids(n); iota(ids.begin(), ids.end(), 0); sort(ids.begin(), ids.end(), [&](const int i, const int j) { return nums2[i] < nums2[j]; }); vector<int> f(n + 1); for (int i: ids) for (int j = n; j; j--) f[j] = max(f[j], f[j - 1] + nums1[i] + nums2[i] * j); int s1 = accumulate(nums1.begin(), nums1.end(), 0); int s2 = accumulate(nums2.begin(), nums2.end(), 0); for (int t = 0; t <= n; t++) if (s1 + s2 * t - f[t] <= x) return t; return -1; } };
java 解法, 执行用时: 103 ms, 内存消耗: 42.7 MB, 提交时间: 2023-08-07 16:00:23
class Solution { public int minimumTime(List<Integer> nums1, List<Integer> nums2, int x) { int n = nums1.size(), s1 = 0, s2 = 0; // 对下标数组排序,避免破坏 nums1 和 nums2 的对应关系 var ids = new Integer[n]; for (int i = 0; i < n; i++) { ids[i] = i; s1 += nums1.get(i); s2 += nums2.get(i); } Arrays.sort(ids, (i, j) -> nums2.get(i) - nums2.get(j)); var f = new int[n + 1]; for (int i : ids) for (int j = n; j > 0; j--) f[j] = Math.max(f[j], f[j - 1] + nums1.get(i) + nums2.get(i) * j); for (int t = 0; t <= n; t++) if (s1 + s2 * t - f[t] <= x) return t; return -1; } }
python3 解法, 执行用时: 2024 ms, 内存消耗: 16.3 MB, 提交时间: 2023-08-07 15:59:39
''' 动态规划 定义 f[i+1][j] 表示从前 i 个数中选出 j 个数,减少量最大是多少。 考虑第 i 个数「选或不选」: 不选:f[i+1][j]=f[i][j]。 选:f[i+1][j]=f[i][j−1]+nums1[i] + nums2[i] * j 第一维优化,0-1背包倒序循环j ''' class Solution: def minimumTime(self, nums1: List[int], nums2: List[int], x: int) -> int: n = len(nums1) f = [0] * (n + 1) for a, b in sorted(zip(nums1, nums2), key=lambda z: z[1]): for j in range(n, 0, -1): f[j] = max(f[j], f[j - 1] + a + b * j) s1 = sum(nums1) s2 = sum(nums2) for t, v in enumerate(f): if s1 + s2 * t - v <= x: return t return -1