2815.数组中的最大数对和

1.题目描述

给你一个下标从 0 开始的整数数组 nums 。请你从 nums 中找出和 最大 的一对数,且这两个数数位上最大的数字相等。

返回最大和,如果不存在满足题意的数字对,返回 -1 。

示例 1:

输入:nums = [51,71,17,24,42]
输出:88
解释:
i = 1 和 j = 2 ,nums[i] 和 nums[j] 数位上最大的数字相等,且这一对的总和 71 + 17 = 88 。 
i = 3 和 j = 4 ,nums[i] 和 nums[j] 数位上最大的数字相等,且这一对的总和 24 + 42 = 66 。
可以证明不存在其他数对满足数位上最大的数字相等,所以答案是 88 。

示例 2:

输入:nums = [1,2,3,4]
输出:-1
解释:不存在数对满足数位上最大的数字相等。

提示:

  • 2 <= nums.length <= 100
  • 1 <= nums[i] <= 104

2.解题思路

1.暴力枚举法:O(n^2)的复杂度枚举每两个数的组合,并且对于每一个数,都使用一个while循环求这个数的最大数位。如果两个数的最大数位相同,那么就相加,直到循环结束,ans中记录的即为满足题意的最大值。这个方法的时间复杂度太高

2.学习的做法:以常量级别的空间复杂度,记录每个最大数位的最大值。就是用一个长为10的数组,下标0-9分别代表了以0-9中任何一个数字为最大数位的最大值。那么只需要一次遍历,对于当前遍历到的数字,求出它的最大数位,然后ans的值肯定为当前数字和它最大数位上的最大值的和,然后如果当前数字大于它最大数为上记录的值,需要更新最大值为当前数字。这样就可以将之前的状态记录在maxVal数组中,从而避免了第二重for循环

3.代码实现

python 常规思路

class Solution:
    def getMax(self, num: int) -> int:
        cnt = 0
        while num:
            cnt = max(cnt,num % 10)
            num //= 10
        return cnt

    def maxSum(self, nums: List[int]) -> int:
        n = len(nums)
        max_val = -1
        for i in range(n-1):
            for j in range(i+1,n):
                if self.getMax(nums[i]) == self.getMax(nums[j]):
                    max_val = max(max_val,nums[i] + nums[j])
        return max_val

Python 一次遍历

class Solution:
    def maxSum(self, nums: List[int]) -> int:
        max_val = [-inf] * 10
        ans = -1
        for num in nums:
            #求数位最大值
            max_d = max(map(int,str(num)))
            ans = max(ans,num + max_val[max_d])
            #更新max_val数位最大值
            max_val[max_d] = max(num,max_val[max_d]) 
        return ans

Java 一次遍历

class Solution {
    public int maxSum(int[] nums) {
        int ans = -1;
        int[] maxVal = new int[10];
        Arrays.fill(maxVal, Integer.MIN_VALUE);
        for (int v : nums) {
            int maxD = 0;
            int temp = v;
            while (temp > 0) {
                maxD = Math.max(maxD,temp % 10);
                temp /= 10;
            }
            ans = Math.max(ans,v + maxVal[maxD]);
            maxVal[maxD] = Math.max(maxVal[maxD],v);
        }
        return ans;
    }
}

  • 8
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值