第 358 场LeetCode周赛题解

A 数组中的最大数对和

数据范围小,直接暴力枚举数对

cpp 复制代码
class Solution {
public:
    int mx(int x) {//返回10进制表示的数的最大数字
        int res = 0;
        for (; x; x /= 10)
            res = max(res, x % 10);
        return res;
    }

    int maxSum(vector<int> &nums) {
        int n = nums.size();
        int res = -1;
        for (int i = 0; i < n; i++) {
            int cur = mx(nums[i]);
            for (int j = 0; j < i; j++) {
                int temp = mx(nums[j]);
                if (cur == temp)
                    res = max(res, nums[i] + nums[j]);
            }
        }
        return res;
    }
};

B 翻倍以链表形式表示的数字

借助栈反序遍历链表,模拟乘2的过程

cpp 复制代码
class Solution {
public:
    ListNode *doubleIt(ListNode *head) {
        stack<ListNode *> st;
        for (ListNode *cur = head; cur; cur = cur->next)
            st.push(cur);
        int c = 0;//是否进位
        while (!st.empty()) {
            auto t = st.top();
            st.pop();
            int nc = (t->val * 2 + c) / 10;
            t->val = (t->val * 2 + c) % 10;
            c = nc;
        }
        if (c)
            head = new ListNode(1, head);
        return head;
    }
};

C 限制条件下元素之间的最小绝对差


有序集合:设 l < r l<r l<r,枚举 r r r,同时用有序集合维护所有满足 r − l ≥ x r-l\ge x r−l≥x的 n u m s [ l ] nums[l] nums[l],在集合中查找最接近 n u m s [ r ] nums[r] nums[r]的数。

cpp 复制代码
class Solution {
public:
    int minAbsoluteDifference(vector<int> &nums, int x) {
        int res = INT32_MAX;
        set<int> s;
        for (int r = x, l = 0; r < nums.size(); r++, l++) {
            s.insert(nums[l]);
            auto it = s.upper_bound(nums[r]);
            if (it != s.end())
                res = min(res, *it - nums[r]);
            if (it != s.begin())
                res = min(res, nums[r] - *prev(it));
        }
        return res;
    }
};

D 操作使得分最大


质因数分解+单调栈+快速幂:

1)首先通过质因数分解计算数组中每个元素的质数分数。

2)不妨设一个存在多个最大质数分数的子数组中最大质数分数的贡献来自有最大质数分数且下标最小的一个元素,设当前位置为 i i i,设 i i i左边第一个大于等于 n u m s [ i ] nums[i] nums[i]的位置为 l [ i ] l[i] l[i],设 i i i右边第一个大于 n u m s [ i ] nums[i] nums[i]的位置为 r [ i ] r[i] r[i],则子数组的最大质数分数贡献来自于 n u m s [ i ] nums[i] nums[i]的子数组的个数为 ( i − l [ i ] ) × ( r [ i ] − i ) (i-l[i])\times(r[i]-i) (i−l[i])×(r[i]−i),通过单调栈来求 l l l和 r r r数组。

3)将各项为(元素,元素作为最大质数分数产生贡献的子数组数目)的数组按元素大小降序排序,然后遍历数组,用快速幂更新答案同时更新 k k k。

cpp 复制代码
class Solution {
public:
    typedef long long ll;
    ll mod = 1e9 + 7;

    int maximumScore(vector<int> &nums, int k) {
        int n = nums.size();
        vector<int> score(n);//质数分数
        for (int i = 0; i < n; i++)
            score[i] = get_score(nums[i]);
        vector<int> l(n, -1);//初始化边界
        stack<int> st;
        for (int i = 0; i < n; i++) {
            while (!st.empty() && score[st.top()] < score[i])
                st.pop();
            if (!st.empty())
                l[i] = st.top();
            st.push(i);
        }
        st = stack<int>();
        vector<int> r(n, n);//初始化边界
        for (int i = n - 1; i >= 0; i--) {
            while (!st.empty() && score[st.top()] <= score[i])
                st.pop();
            if (!st.empty())
                r[i] = st.top();
            st.push(i);
        }
        vector<pair<int, ll>> li(n);
        for (int i = 0; i < n; i++)
            li[i] = {nums[i], 1LL * (i - l[i]) * (r[i] - i)};//(元素, 元素作为最大质数分数产生贡献的子数组数目)
        sort(li.begin(), li.end(), greater<>());//按元素大小降序排序
        ll res = 1;
        for (int i = 0; k; i++) {
            int t = min((ll) k, li[i].second);
            res = res * fpow(li[i].first, t) % mod;
            k -= t;
        }
        return (res + mod) % mod;
    }

    int get_score(int x) {
        int res = 0;
        for (int i = 2; i * i <= x; i++)//质因数分解
            if (x % i == 0) {
                res++;
                while (x % i == 0)
                    x /= i;
            }
        if (x > 1)
            res++;
        return res;
    }

    ll fpow(ll x, ll n) {//快速幂
        ll res = 1;
        for (ll e = x; n; n >>= 1, e = (e * e) % mod)
            if (n & 1)
                res = res * e % mod;
        return res;
    }
};
相关推荐
羊小猪~~3 分钟前
数据结构C语言描述2(图文结合)--有头单链表,无头单链表(两种方法),链表反转、有序链表构建、排序等操作,考研可看
c语言·数据结构·c++·考研·算法·链表·visual studio
王哈哈^_^28 分钟前
【数据集】【YOLO】【VOC】目标检测数据集,查找数据集,yolo目标检测算法详细实战训练步骤!
人工智能·深度学习·算法·yolo·目标检测·计算机视觉·pyqt
星沁城30 分钟前
240. 搜索二维矩阵 II
java·线性代数·算法·leetcode·矩阵
脉牛杂德1 小时前
多项式加法——C语言
数据结构·c++·算法
legend_jz1 小时前
STL--哈希
c++·算法·哈希算法
kingmax542120081 小时前
初三数学,最优解问题
算法
一直学习永不止步1 小时前
LeetCode题练习与总结:赎金信--383
java·数据结构·算法·leetcode·字符串·哈希表·计数
小刘|2 小时前
《Java 实现希尔排序:原理剖析与代码详解》
java·算法·排序算法
jjyangyou2 小时前
物联网核心安全系列——物联网安全需求
物联网·算法·安全·嵌入式·产品经理·硬件·产品设计
van叶~2 小时前
算法妙妙屋-------1.递归的深邃回响:二叉树的奇妙剪枝
c++·算法