第 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;
    }
};
相关推荐
忘梓.1 小时前
解锁动态规划的奥秘:从零到精通的创新思维解析(3)
算法·动态规划
️南城丶北离1 小时前
[数据结构]图——C++描述
数据结构··最小生成树·最短路径·aov网络·aoe网络
✿ ༺ ོIT技术༻1 小时前
C++11:新特性&右值引用&移动语义
linux·数据结构·c++
tinker在coding3 小时前
Coding Caprice - Linked-List 1
算法·leetcode
XH华7 小时前
初识C语言之二维数组(下)
c语言·算法
南宫生8 小时前
力扣-图论-17【算法学习day.67】
java·学习·算法·leetcode·图论
不想当程序猿_8 小时前
【蓝桥杯每日一题】求和——前缀和
算法·前缀和·蓝桥杯
落魄君子8 小时前
GA-BP分类-遗传算法(Genetic Algorithm)和反向传播算法(Backpropagation)
算法·分类·数据挖掘
菜鸡中的奋斗鸡→挣扎鸡8 小时前
滑动窗口 + 算法复习
数据结构·算法
Lenyiin8 小时前
第146场双周赛:统计符合条件长度为3的子数组数目、统计异或值为给定值的路径数目、判断网格图能否被切割成块、唯一中间众数子序列 Ⅰ
c++·算法·leetcode·周赛·lenyiin