2342. 数位和相等数对的最大和 : 用「遍历过程」代替「次大维护」

题目描述

这是 LeetCode 上的 2342. 数位和相等数对的最大和 ,难度为 简单

Tag : 「模拟」、「哈希表」

给你一个下标从 0 开始的数组 nums,数组中的元素都是正整数。

请你选出两个下标 iji != j),且 nums[i] 的数位和与 nums[j] 的数位和相等。

请你找出所有满足条件的下标 ij,找出并返回 nums[i] + nums[j] 可以得到的最大值。

示例 1:

ini 复制代码
输入:nums = [18,43,36,13,7]

输出:54

解释:满足条件的数对 (i, j) 为:
- (0, 2) ,两个数字的数位和都是 9 ,相加得到 18 + 36 = 54 。
- (1, 4) ,两个数字的数位和都是 7 ,相加得到 43 + 7 = 50 。
所以可以获得的最大和是 54 。

示例 2:

ini 复制代码
输入:nums = [10,12,19,14]

输出:-1

解释:不存在满足条件的数对,返回 -1 。

提示:

  • <math xmlns="http://www.w3.org/1998/Math/MathML"> 1 < = n u m s . l e n g t h < = 1 0 5 1 <= nums.length <= 10^5 </math>1<=nums.length<=105
  • <math xmlns="http://www.w3.org/1998/Math/MathML"> 1 < = n u m s [ i ] < = 1 0 9 1 <= nums[i] <= 10^9 </math>1<=nums[i]<=109

模拟

既然每个 <math xmlns="http://www.w3.org/1998/Math/MathML"> n u m s [ i ] nums[i] </math>nums[i] 都对应一个具体的数位和,统计每个数位和的最大值和次大值,然后在所有数位和的最大值和次大值求和中取 max 即是答案。

利用 <math xmlns="http://www.w3.org/1998/Math/MathML"> 1 < = n u m s [ i ] < = 1 0 9 1 <= nums[i] <= 10^9 </math>1<=nums[i]<=109,我们知道数位和不会超过 <math xmlns="http://www.w3.org/1998/Math/MathML"> 9 × 9 = 81 9 \times 9 = 81 </math>9×9=81,可直接起一个大小为 <math xmlns="http://www.w3.org/1998/Math/MathML"> 100 × 2 100 \times 2 </math>100×2 的二维数组进行统计, <math xmlns="http://www.w3.org/1998/Math/MathML"> v a l [ x ] [ 0 ] val[x][0] </math>val[x][0] 代表数位和为 <math xmlns="http://www.w3.org/1998/Math/MathML"> x x </math>x 的次大值, <math xmlns="http://www.w3.org/1998/Math/MathML"> v a l [ x ] [ 1 ] val[x][1] </math>val[x][1] 代表数位和为 <math xmlns="http://www.w3.org/1998/Math/MathML"> x x </math>x 的最大值。

Java 代码:

Java 复制代码
class Solution {
    public int maximumSum(int[] nums) {
        int[][] val = new int[100][2];
        for (int x : nums) {
            int t = x, cur = 0;
            while (t != 0) {
                cur += t % 10;
                t /= 10;
            }
            if (x >= val[cur][1]) { // 最大沦为次大, 更新最大
                val[cur][0] = val[cur][1];
                val[cur][1] = x;
            } else if (x > val[cur][0]) { // 更新次大
                val[cur][0] = x;
            }
        }
        int ans = -1;
        for (int i = 0; i < 100; i++) {
            if (val[i][0] != 0 && val[i][1] != 0) ans = Math.max(ans, val[i][0] + val[i][1]);
        }
        return ans;
    }
}

C++ 代码:

C++ 复制代码
class Solution {
public:
    int maximumSum(vector<int>& nums) {
        vector<vector<int>> val(100, vector<int>(2, 0));
        for (int x : nums) {
            int t = x, cur = 0;
            while (t != 0) {
                cur += t % 10;
                t /= 10;
            }
            if (x >= val[cur][1]) {
                val[cur][0] = val[cur][1];
                val[cur][1] = x;
            } else if (x > val[cur][0]) {
                val[cur][0] = x;
            }
        }
        int ans = -1;
        for (int i = 0; i < 100; i++) {
            if (val[i][0] != 0 && val[i][1] != 0) ans = max(ans, val[i][0] + val[i][1]);
        }
        return ans;
    }
};

Python 代码:

Python 复制代码
class Solution:
    def maximumSum(self, nums: List[int]) -> int:
        val = [[0, 0] for _ in range(100)]
        for x in nums:
            t, cur = x, 0
            while t != 0:
                cur += t % 10
                t //= 10
            if x >= val[cur][1]:
                val[cur][0], val[cur][1] = val[cur][1], x
            elif x > val[cur][0]:
                val[cur][0] = x
        ans = -1
        for i in range(100):
            if val[i][0] != 0 and val[i][1] != 0:
                ans = max(ans, val[i][0] + val[i][1])
        return ans

TypeScript 代码:

TypeScript 复制代码
function maximumSum(nums: number[]): number {
    const val = Array.from({ length: 100 }, () => [0, 0]);
    for (const x of nums) {
        let t = x, cur = 0;
        while (t !== 0) {
            cur += t % 10;
            t = Math.floor(t / 10);
        }
        if (x >= val[cur][1]) {
            val[cur][0] = val[cur][1];
            val[cur][1] = x;
        } else if (x > val[cur][0]) {
            val[cur][0] = x;
        }
    }
    let ans = -1;
    for (let i = 0; i < 100; i++) {
        if (val[i][0] !== 0 && val[i][1] !== 0) ans = Math.max(ans, val[i][0] + val[i][1]);
    }
    return ans;
};
  • 时间复杂度: <math xmlns="http://www.w3.org/1998/Math/MathML"> O ( n log ⁡ m ) O(n\log{m}) </math>O(nlogm),其中 <math xmlns="http://www.w3.org/1998/Math/MathML"> n = 1 e 5 n=1e5 </math>n=1e5 为 nums 长度, <math xmlns="http://www.w3.org/1998/Math/MathML"> m = 1 e 9 m=1e9 </math>m=1e9 为 <math xmlns="http://www.w3.org/1998/Math/MathML"> n u m s [ i ] nums[i] </math>nums[i] 值域上界
  • 空间复杂度: <math xmlns="http://www.w3.org/1998/Math/MathML"> O ( C ) O(C) </math>O(C),其中 <math xmlns="http://www.w3.org/1998/Math/MathML"> C = 2 × 9 × log ⁡ m C = 2 \times 9 \times \log{m} </math>C=2×9×logm

模拟

更进一步,我们不需要记录次大值,仅记录某个"数对和"当前的最大值即可。

每次计算出当前 <math xmlns="http://www.w3.org/1998/Math/MathML"> n u m s [ i ] nums[i] </math>nums[i] 对应的数对 cur 后,检查 cur 是否已出现过,若出现过用两者之和更新答案,并用 <math xmlns="http://www.w3.org/1998/Math/MathML"> n u m s [ i ] nums[i] </math>nums[i] 来更新 cur 下的最大值。

该做法本质是用「遍历过程」代替「次大维护」。

Java 代码:

Java 复制代码
class Solution {
    public int maximumSum(int[] nums) {
        int[] val = new int[100];
        int ans = -1;
        for (int x : nums) {
            int t = x, cur = 0;
            while (t != 0) {
                cur += t % 10;
                t /= 10;
            }
            if (val[cur] != 0) ans = Math.max(ans, val[cur] + x);
            val[cur] = Math.max(val[cur], x);
        }
        return ans;       
    }
}

C++ 代码:

C++ 复制代码
class Solution {
public:
    int maximumSum(vector<int>& nums) {
        vector<int> val(100, 0);
        int ans = -1;
        for (int x : nums) {
            int t = x, cur = 0;
            while (t != 0) {
                cur += t % 10;
                t /= 10;
            }
            if (val[cur] != 0) ans = max(ans, val[cur] + x);
            val[cur] = max(val[cur], x);
        }
        return ans;
    }
};

Python 代码:

Python 复制代码
class Solution:
    def maximumSum(self, nums: List[int]) -> int:
        val = [0] * 100
        ans = -1
        for x in nums:
            t, cur = x, 0
            while t != 0:
                cur += t % 10
                t //= 10
            if val[cur] != 0:
                ans = max(ans, val[cur] + x)
            val[cur] = max(val[cur], x)
        return ans

TypeScript 代码:

TypeScript 复制代码
function maximumSum(nums: number[]): number {
    const val = Array(100).fill(0);
    let ans = -1;
    for (const x of nums) {
        let t = x, cur = 0;
        while (t !== 0) {
            cur += t % 10;
            t = Math.floor(t / 10);
        }
        if (val[cur] !== 0) ans = Math.max(ans, val[cur] + x);
        val[cur] = Math.max(val[cur], x);
    }
    return ans;
};
  • 时间复杂度: <math xmlns="http://www.w3.org/1998/Math/MathML"> O ( n log ⁡ m ) O(n\log{m}) </math>O(nlogm),其中 <math xmlns="http://www.w3.org/1998/Math/MathML"> n = 1 e 5 n=1e5 </math>n=1e5 为 nums 长度, <math xmlns="http://www.w3.org/1998/Math/MathML"> m = 1 e 9 m=1e9 </math>m=1e9 为 <math xmlns="http://www.w3.org/1998/Math/MathML"> n u m s [ i ] nums[i] </math>nums[i] 值域上界
  • 空间复杂度: <math xmlns="http://www.w3.org/1998/Math/MathML"> O ( C ) O(C) </math>O(C),其中 <math xmlns="http://www.w3.org/1998/Math/MathML"> C = 9 × log ⁡ m C = 9 \times \log{m} </math>C=9×logm

最后

这是我们「刷穿 LeetCode」系列文章的第 No.2342 篇,系列开始于 2021/01/01,截止于起始日 LeetCode 上共有 1916 道题目,部分是有锁题,我们将先把所有不带锁的题目刷完。

在这个系列文章里面,除了讲解解题思路以外,还会尽可能给出最为简洁的代码。如果涉及通解还会相应的代码模板。

为了方便各位同学能够电脑上进行调试和提交代码,我建立了相关的仓库:github.com/SharingSour...

在仓库地址里,你可以看到系列文章的题解链接、系列文章的相应代码、LeetCode 原题链接和其他优选题解。

更多更全更热门的「笔试/面试」相关资料可访问排版精美的 合集新基地 🎉🎉

相关推荐
sdgsdgdsgc1 小时前
Next.js企业级应用开发:SSR、ISR与性能监控方案
开发语言·前端·javascript
哲此一生9841 小时前
搭建Vue3工程(去除不必要的文件)
前端·javascript·vue.js
摇滚侠3 小时前
Spring Boot 3零基础教程,IOC容器中组件的注册,笔记08
spring boot·笔记·后端
黑云压城After4 小时前
H5使用环信实现视频或语音通话
前端·javascript·vue.js
未来之窗软件服务6 小时前
自己写算法(九)网页数字动画函数——东方仙盟化神期
前端·javascript·算法·仙盟创梦ide·东方仙盟·东方仙盟算法
程序员小凯6 小时前
Spring Boot测试框架详解
java·spring boot·后端
豐儀麟阁贵6 小时前
基本数据类型
java·算法
你的人类朋友6 小时前
什么是断言?
前端·后端·安全
FIN66687 小时前
昂瑞微:实现精准突破,攻坚射频“卡脖子”难题
前端·人工智能·安全·前端框架·信息与通信
椎4957 小时前
苍穹外卖前端nginx错误之一解决
运维·前端·nginx