每日算法刷题Day33 6.16:leetcode枚举技巧5道题,用时1h10min

9. 2815. 数组中的最大数对和(简单)

2815. 数组中的最大数对和 - 力扣(LeetCode)

思想

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

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

2.根据条件"这两个数数位上最大的数字相等"即可枚举右,维护左,键为数数位上最大的数字,再根据"和 最大 的一对数",所以值为之前最大数的下标

代码

c++:

复制代码
class Solution {
public:
    int getMax(int a) {
        int res = 0;
        while (a) {
            res = max(res, a % 10);
            a /= 10;
        }
        return res;
    }
    int maxSum(vector<int>& nums) {
        int n = nums.size(), res = -1;
        map<int, int> mp; // 数位最大数字-最大数字下标
        for (int j = 0; j < n; ++j) {
            int t = getMax(nums[j]);
            auto it = mp.find(t);
            if (it != mp.end()) {
                res = max(res, nums[j] + nums[it->second]);
                if (nums[j] > nums[it->second])
                    mp[t] = j;
            } else
                mp[t] = j;
        }
        return res;
    }
};
10. 2342.数位和相等数对的最大和(中等)

2342. 数位和相等数对的最大和 - 力扣(LeetCode)

思想

1.给你一个下标从 0 开始的数组 nums ,数组中的元素都是 整数。请你选出两个下标 iji != j),且 nums[i] 的数位和 与 nums[j] 的数位和相等。

请你找出所有满足条件的下标 ij ,找出并返回 nums[i] + nums[j] 可以得到的 最大值 。如果不存在这样的下标对,返回 -1。

2.跟2815. 数组中的最大数对和类似,只不过把条件"这两个数数位上最大的数字相等"改成"且 nums[i] 的数位和 与 nums[j] 的数位和相等"

代码

c++:

复制代码
class Solution {
public:
    int getSum(int a) {
        int sum = 0;
        while (a) {
            sum += a % 10;
            a /= 10;
        }
        return sum;
    }
    int maximumSum(vector<int>& nums) {
        int n = nums.size(), res = -1;
        map<int, int> mp;
        for (int j = 0; j < n; ++j) {
            int t = getSum(nums[j]);
            auto it = mp.find(t);
            if (it != mp.end()) {
                res = max(res, nums[j] + nums[it->second]);
                if (nums[j] > nums[it->second])
                    mp[t] = j;
            } else
                mp[t] = j;
        }
        return res;
    }
};
11. 1679.K和数对的最大数目(中等,学习)

1679. K 和数对的最大数目 - 力扣(LeetCode)

思想

1.给你一个整数数组 nums 和一个整数 k

每一步操作中,你需要从数组中选出和为 k 的两个整数,并将它们移出数组。

返回你可以对数组执行的最大操作数。

2.条件"和为 k 的两个整数"说明可以枚举右,维护左,而"将它们移出数组"则说明要记录当前有几个值为k-nums[j]的下标,所以值为下标个数,无需记录下标到底是多少

3.而我原来想存储下标集也是可行的,用vector<int>,判断不为空,然后pop_back删除最后一个元素(一开始忘记了这个)

代码

c++:

复制代码
class Solution {
public:
    int maxOperations(vector<int>& nums, int k) {
        int n = nums.size(), res = 0;
        map<int, int> mp; // 和-下标个数
        for (int j = 0; j < n; ++j) {
            auto it = mp.find(k - nums[j]);
            if (it != mp.end() && it->second) {
                ++res;
                --it->second;
            } else
                ++mp[nums[j]]; // 不能写++it->second,因为可能it->second无效
        }
        return res;
    }
};

存储下标集:

复制代码
class Solution {
public:
    int maxOperations(vector<int>& nums, int k) {
        int n = nums.size(), res = 0;
        map<int, vector<int>> mp; // 和-下标集
        for (int j = 0; j < n; ++j) {
            auto it = mp.find(k - nums[j]);
            if (it != mp.end() && !it->second.empty()) {
                ++res;
                it->second.pop_back(); // 用pop_back()
            } else
                mp[nums[j]].emplace_back(
                    j); // 不能写it->second.emplace_back(j),因为可能it->second无效
        }
        return res;
    }
};
12. 面试题 16.24. 数对和(中等)

面试题 16.24. 数对和 - 力扣(LeetCode)

思想

1.设计一个算法,找出数组中两数之和为指定值的所有整数对。一个数只能属于一个数对。

2.跟11. 1679.K和数对的最大数目一摸一样,只有记录下标次数即可

代码

c++:

复制代码
class Solution {
public:
    vector<vector<int>> pairSums(vector<int>& nums, int target) {
        int n = nums.size();
        vector<vector<int>> res;
        map<int, int> mp; // 值-下标次数
        for (int j = 0; j < n; ++j) {
            auto it = mp.find(target - nums[j]);
            if (it != mp.end() && it->second) {
                res.push_back({target - nums[j], nums[j]});
                --it->second;
            } else
                ++mp[nums[j]];
        }
        return res;
    }
};
13. 3371.识别数组中的最大异常值(中等)

3371. 识别数组中的最大异常值 - 力扣(LeetCode)

思想

1.给你一个整数数组 nums。该数组包含 n 个元素,其中 恰好n - 2 个元素是 特殊数字 。剩下的 两个 元素中,一个是所有 特殊数字 ,另一个是 异常值
异常值 的定义是:既不是原始特殊数字之一,也不是所有特殊数字的和。
注意 ,特殊数字、和 以及 异常值 的下标必须 不同 ,但可以共享 相同 的值。

返回 nums 中可能的 最大 异常值。

2.根据题意可以分析出2*nums[i]+nums[j]=sum,其中nums[i]是特殊数字,而nums[j]是异常值,所以可以枚举一个,但这里不是枚举右,维护左,因为i和j的关系不定,不存在只考虑左边的数,所以一开始让所有数先进map,然后考虑枚举异常值还是特殊数字,发现枚举异常值更简单,"注意,特殊数字、和 以及 异常值 的下标必须 不同,但可以共享 相同的值。"所以找到的异常值有两种情况满足:(1)异常值与特殊值不同(2)值出现次数>1(可以不用写相同)

代码

c++:

复制代码
class Solution {
public:
    int getLargestOutlier(vector<int>& nums) {
        int n = nums.size(), sum = 0, res = INT_MIN;
        map<int, int> mp; // 值-次数
        for (const int& x : nums) {
            sum += x;
            ++mp[x];
        }
        // 2*nums[i]+nums[j]=sum,枚举特殊数字
        for (int i = 0; i < n; ++i) {
            auto it = mp.find(sum - 2 * nums[i]); // 找异常值
            // 异常值存在,且(异常值与特殊值不同)或(异常值与特殊值相同且这个值至少出现两次)
            if (it != mp.end() && (it->first != nums[i] ||
                                    it->second > 1) )
                res = max(res, it->first);
        }
        return res;
    }
};
相关推荐
倔强的小石头_38 分钟前
【C语言指南】函数指针深度解析
java·c语言·算法
Yasin Chen43 分钟前
C# Dictionary源码分析
算法·unity·哈希算法
_Coin_-2 小时前
算法训练营DAY27 第八章 贪心算法 part01
算法·贪心算法
董董灿是个攻城狮6 小时前
5分钟搞懂什么是窗口注意力?
算法
Dann Hiroaki6 小时前
笔记分享: 哈尔滨工业大学CS31002编译原理——02. 语法分析
笔记·算法
qqxhb8 小时前
零基础数据结构与算法——第四章:基础算法-排序(上)
java·数据结构·算法·冒泡·插入·选择
FirstFrost --sy10 小时前
数据结构之二叉树
c语言·数据结构·c++·算法·链表·深度优先·广度优先
森焱森10 小时前
垂起固定翼无人机介绍
c语言·单片机·算法·架构·无人机
搂鱼11451410 小时前
(倍增)洛谷 P1613 跑路/P4155 国旗计划
算法
Yingye Zhu(HPXXZYY)10 小时前
Codeforces 2021 C Those Who Are With Us
数据结构·c++·算法