624. 数组列表中的最大距离

624. 数组列表中的最大距离

给定 m 个数组,每个数组都已经按照升序排好序了。现在你需要从两个不同的数组中选择两个整数(每个数组选一个)并且计算它们的距离。两个整数 a 和 b 之间的距离定义为它们差的绝对值 ∣ a − b ∣ |a-b| ab 。你的任务就是去找到最大距离。

示例 1:

输入: 
[[1,2,3],
 [4,5],
 [1,2,3]]
输出: 4
解释:
一种得到答案 4 的方法是从第一个数组或者第三个数组中选择 1,同时从第二个数组中选择 5 。

解法一:暴力(TLE)

思路

很容易想到。在第 i 行选最大元素,在除 i 行外的一行选最小元素;或在第 i 行选最小元素,在除 i 行外的一行选最大元素,两者相减就是最大距离。

又因为每个数组都是升序排列,所以最大距离与每个数组的第一个元素和最后一个元素有关。于是就有两层循环暴力的求最大值。

复杂度

时间复杂度: O ( N 2 ) O(N^2) O(N2) N N N 二维数组中数组的个数。

空间复杂度: O ( 1 ) O(1) O(1)

代码

class Solution {
public:
    int maxDistance(vector<vector<int>>& a) {
        int res = 0;
        for (int i = 0; i < a.size(); i++) {
            for (int j = i; j < a[i].size(); j++) {
                int x = abs(a[i][0] - a[j][a[j].size() - 1]);
                int y = abs(a[i][a[i].size() - 1] - a[j][0]);
                res = max(res, max(x, y));
            }
        }
        return res;
    }
};`

解法二:线性扫描

思路

由方法一得知,最大距离由每一行最大值和最小值决定。如果 a 在第 i 行中选,则 b 只能在前 i - 1 行中选,若把前 i - 1 个行合并起来看为一个大行,那么只有这个大行中的最大值和最小值有效(必须拉自不同的行)和第 i 行中的最大值和最小值有效。

因为每一行升序排列,第 i 行最小值和最大值很容易得到。关键在于如何取得大行的最大值和最小值。

大行由前面的小行所构成,所以在循环到第 ii - 1 的最大和最小值元素已经确定。

复杂度

时间复杂度: O ( N ) O(N) O(N)

空间复杂度: O ( 1 ) O(1) O(1)

代码

class Solution {
public:
    int maxDistance(vector<vector<int>>& a) {
        int n = a.size(), res = 0;
        int pre_max = a[0][a[0].size() - 1], pre_min = a[0][0];
        for (int i = 1; i < n; i++) { 
            int j = a[i].size() - 1;
            int x = abs(pre_max - a[i][0]), y = abs(pre_min - a[i][j]);
            res = max(res, max(x, y));
            pre_max = max(pre_max, a[i][j]), pre_min = min(pre_min, a[i][0]);
        }
        return res;
    }
};

给个 java 版本,get 我头疼。。。

class Solution {
    public int maxDistance(List<List<Integer>> a) {
        int n = a.size(), res = 0;
        int pre_max = a.get(0).get(a.get(0).size() - 1), pre_min = a.get(0).get(0);
        for (int i = 1; i < n; i++) { 
            int j = a.get(i).size() - 1;
            int x = Math.abs(pre_max - a.get(i).get(0));
            int y = Math.abs(pre_min - a.get(i).get(j));
            res = Math.max(res, Math.max(x, y));
            pre_max = Math.max(pre_max, a.get(i).get(j));
            pre_min = Math.min(pre_min, a.get(i).get(0));
        }
        return res;
    }
}

  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值