📌  相关文章
📜  不同索引对 (i, j) 的计数,使得第一个数组的元素总和更大(1)

📅  最后修改于: 2023-12-03 15:35:54.628000             🧑  作者: Mango

题目描述

给定两个长度相同的整数数组 nums1nums2,请你计算满足 nums1[i] + nums2[i] > nums1[j] + nums2[j] 的不同索引对 (i, j) 数量。

其中 0 <= i, j < nums1.lengthi != j

示例
输入: nums1 = [1,2,3,4,5], nums2 = [1,2,3,4,5]
输出: 16
说明: 
所有可能的索引对如下:
(0,1), (0,2), (0,3), (0,4), (1,2), (1,3), (1,4), (2,3), (2,4), (3,4)
对于每一个索引对,我们计算出 nums1[i] + nums2[i] > nums1[j] + nums2[j]
(0,1), (0,2), (0,3), (0,4), -> 事实上所有的 i 的情况下都成立,因为 nums1[i] >= 1, nums2[i] >= 1
(1,2), (1,3), (1,4), (2,3), (2,4), (3,4) -> 也是成立的,因为 nums1[i] + nums2[i] > nums1[j] + nums2[j] 
解题思路
  1. 对于每个索引 $i$,我们要找到它左侧的数和右侧的数中与之组合之后可以得到大于自己的数的个数,然后将它们的个数相乘即可。
  2. 如何找左右两侧的数呢?因为输入的两个数组长度相同,所以我们可以遍历 nums1,对于每个 $i$,其左侧和右侧的数就是 nums1 中索引小于 $i$ 的数和索引大于 $i$ 的数与 nums2 中对应位置的数之和。这个可以通过预处理两个数组对应位置之和的数组得出。
  3. 这个过程中需要注意的一个细节是,左侧的数可以重合,右侧的数也可以重合,所以我们在计算左右两侧数的组合之和之后,需要将重合的数的数量剪去。
复杂度分析
  • 时间复杂度:$O(n)$。其中 $n$ 是输入数组的长度。
  • 空间复杂度:$O(n)$。
代码实现
class Solution:
    def maxCount(self, m: int, n: int, ops: List[List[int]]) -> int:
        if len(ops) == 0:
            return m * n
        min_a = min(op[0] for op in ops)
        min_b = min(op[1]1 for op in ops)
        return min_a * min_b
class Solution {
    public int maxCount(int m, int n, int[][] ops) {
        if (ops == null || ops.length == 0) {
            return m * n;
        }
        int min_a = Integer.MAX_VALUE;
        int min_b = Integer.MAX_VALUE;
        for (int[] op : ops) {
            min_a = Math.min(min_a, op[0]);
            min_b = Math.min(min_b, op[1]);
        }
        return min_a * min_b;
    }
}
func maxCount(m int, n int, ops [][]int) int {
    if len(ops) == 0 {
        return m * n
    }
    minA := math.MaxInt32
    minB := math.MaxInt32
    for _, op := range ops {
        minA = min(minA, op[0])
        minB = min(minB, op[1])
    }
    return minA * minB
}

func min(a, b int) int {
    if a < b {
        return a
    }
    return b
}