第 364 场 LeetCode 周赛题解

news/2024/5/18 22:07:37 标签: leetcode, 算法, C++, 枚举, 单调栈, 计数, dfs

A leetcode.cn/problems/maximum-odd-binary-number/">最大二进制奇数

在这里插入图片描述

降序排序字符串,然后将最后一个 1 与最后一位交换

class Solution {
public:
    string maximumOddBinaryNumber(string s) {
        sort(s.begin(), s.end(), greater<>());
        for (int i = s.size() - 1;; i--)
            if (s[i] == '1') {
                swap(s[i], s.back());
                break;
            }
        return s;
    }
};

B leetcode.cn/problems/beautiful-towers-i/">美丽塔 I

在这里插入图片描述
在这里插入图片描述

枚举枚举山状数组的最大值的下标 i i i,然后遍历两端 [ 0 , i ) [0,i) [0,i) ( i , n − 1 ] (i,n-1] (i,n1] ,求各位置能达到的最大高度

class Solution {
public:
    using ll = long long;

    long long maximumSumOfHeights(vector<int> &maxHeights) {
        int n = maxHeights.size();
        ll res = 0;
        for (int i = 0; i < n; i++) {
            ll cur = maxHeights[i];
            for (int j = i - 1, last = maxHeights[i]; j >= 0; j--) {
                last = min(last, maxHeights[j]);
                cur += last;
            }
            for (int j = i + 1, last = maxHeights[i]; j < n; j++) {
                last = min(last, maxHeights[j]);
                cur += last;
            }
            res = max(res, cur);
        }
        return res;
    }
};

C leetcode.cn/problems/beautiful-towers-ii/">美丽塔 II

在这里插入图片描述
在这里插入图片描述

单调栈+枚举:设 l [ i ] l[i] l[i] 为当 h e i g h t s [ i ] = m a x H e i g h t s [ i ] heights[i]=maxHeights[i] heights[i]=maxHeights[i] ∑ k = 0 i h e i g h t s [ k ] \sum_{k=0}^i heights[k] k=0iheights[k] 的最大值,类似地设 r [ i ] r[i] r[i] 为当 h e i g h t s [ i ] = m a x H e i g h t s [ i ] heights[i]=maxHeights[i] heights[i]=maxHeights[i] ∑ k = i h e i g h t s . s i z e ( ) − 1 h e i g h t s [ k ] \sum_{k=i}^{heights.size()-1} heights[k] k=iheights.size()1heights[k] 的最大值,用单调栈预先求出 l l l r r r 数组,答案即为: m a x { l [ i ] + r [ i ] − m a x H e i g h t s [ i ]    ∣    0 ≤ i < n } max\{ l[i]+r[i]-maxHeights[i] \; | \; 0\le i< n \} max{l[i]+r[i]maxHeights[i]0i<n}

class Solution {
public:
    using ll = long long;

    long long maximumSumOfHeights(vector<int> &maxHeights) {
        int n = maxHeights.size();
        vector<ll> l(n), r(n);
        stack<int> st;
        for (int i = 0; i < n; i++) {
            while (!st.empty() && maxHeights[st.top()] > maxHeights[i])//栈顶位置最大高度大于当前位置最大高度则需要出栈
                st.pop();
            l[i] = st.empty() ? 1LL * (i + 1) * maxHeights[i] : l[st.top()] + 1LL * (i - st.top()) * maxHeights[i];
            st.push(i);
        }
        st = stack<int>();
        for (int i = n - 1; i >= 0; i--) {
            while (!st.empty() && maxHeights[st.top()] > maxHeights[i])//栈顶位置最大高度大于当前位置最大高度则需要出栈
                st.pop();
            r[i] = st.empty() ? 1LL * (n - i) * maxHeights[i] : r[st.top()] + 1LL * (st.top() - i) * maxHeights[i];
            st.push(i);
        }
        ll res = 0;
        for (int i = 0; i < n; i++)
            res = max(res, l[i] + r[i] - maxHeights[i]);
        return res;
    }
};

D leetcode.cn/problems/count-valid-paths-in-a-tree/">统计树中的合法路径数目

在这里插入图片描述
在这里插入图片描述
计数+ d f s dfs dfs:设一个质数点 r o o t root root v v v 集合为: { 从 u 出发只通过非质数点能到达的非质数点的数目 ∣ u 是 r o o t 的邻接点 } \{ 从u出发只通过非质数点能到达的非质数点的数目 | u是root的邻接点 \} {u出发只通过非质数点能到达的非质数点的数目uroot的邻接点},例如下图中 r o o t root root v v v 集合为 { 1 , 2 , 3 } \{1,2,3 \} {1,2,3}
在这里插入图片描述
知道 r o o t root root v v v 集合后,则树中含 r o o t root root 的合法路径可分为两类:

  1. 一个端点为 r o o t root root 的路径,这类路径数为: ∑ v i ∈ v v i \sum_{v_i\in v} v_i vivvi
  2. 两个端点都不为 r o o t root root 的路径,这类路径数为: 1 2 ∑ v i ∈ v ∑ j ≠ i v i v j = 1 2 ( ( ∑ v i ∈ v v i ) 2 − ∑ v i ∈ v v i 2 ) \frac 1 2 \sum_{v_i\in v} \sum_{j\ne i} v_iv_j=\frac 1 2 \left ( ( \sum_{v_i\in v} v_i )^2 -\sum_{v_i\in v} v_i^2 \right ) 21vivj=ivivj=21((vivvi)2vivvi2)

不妨以 1 1 1 为树根,首先通过 d f s dfs dfs 计算 c n t _ n p cnt\_np cnt_np 数组: c n t _ n p [ i ] cnt\_np[i] cnt_np[i] 为以 i i i 为根的子树中从 i i i 出发只通过非质数点能到达的非质数点的数目。然后再次 d f s dfs dfs ,并在遍历过程中记录“从当前节点的父节点出发(且不经过当前节点)只通过非质数点能到达的非质数点的数目”,这样每到达一个质数点,就能求出它的 v v v 集合,从而计算含该点的合法路径数。

class Solution {
public:
    using ll = long long;

    long long countPaths(int n, vector<vector<int>> &edges) {
        vector<int> isp(n + 1, 1);//isp[i]:i是否是质数
        isp[1] = 0;
        for (int i = 2; i <= n; i++) {//预处理判断数是否是质数
            for (int j = 2; j * j <= i; j++)
                if (i % j == 0) {
                    isp[i] = 0;
                    break;
                }
        }
        vector<vector<int>> e(n + 1);
        for (auto &ei: edges) {//建图
            e[ei[0]].push_back(ei[1]);
            e[ei[1]].push_back(ei[0]);
        }
        vector<ll> cnt_np(n + 1);//以i为根的子树中从i出发只通过非质数点到达的非质数点的数目
        function<int(int, int)> comp_path = [&](int root, int p) {//当前点为root,父节点为p
            if (isp[root]) {//当前点为质数点
                cnt_np[root] = 0;
                for (auto j: e[root])
                    if (j != p)
                        comp_path(j, root);
            } else {//当前点非质数点
                cnt_np[root] = 1;
                for (auto j: e[root])
                    if (j != p)
                        cnt_np[root] += comp_path(j, root);
            }
            return cnt_np[root];
        };
        comp_path(1, 0);
        ll res = 0;
        function<void(int, int, int)> dfs = [&](int root, int p, int up) {//当前点为root,父节点为p,up:从p出发(且不经过当前节点)只通过非质数点能到达的非质数点的数目
            if (isp[root]) {//当前点为质数点
                vector<ll> v;// v集合
                if (up != 0)
                    v.push_back(up);
                for (auto j: e[root])
                    if (j != p) {
                        dfs(j, root, 0);
                        if (cnt_np[j])
                            v.push_back(cnt_np[j]);
                    }
                ll s = 0, s2 = 0;
                for (auto it: v) {
                    s += it;
                    s2 += it * it;
                }
                res += s + (s * s - s2) / 2;//+=含当前质数点的合法路径数目

            } else {//当前点非质数点
                ll s = up + 1;
                for (auto j: e[root])
                    if (j != p && cnt_np[j])
                        s += cnt_np[j];
                for (auto j: e[root])
                    if (j != p)
                        dfs(j, root, s - cnt_np[j]);
            }
        };
        dfs(1, 0, 0);
        return res;
    }
};

http://www.niftyadmin.cn/n/5046957.html

相关文章

寻找单身狗

在一个数组中仅出现一次&#xff0c;其他数均出现两次&#xff0c;这个出现一次的数就被称为“单身狗“。 一.一个单身狗 我们知道异或运算操作符 ^ &#xff0c;它的特点是对应二进制位相同为 0&#xff0c;相异为 1。 由此我们容易知道两个相同的数,进行异或运算得到的结果…

Django框架介绍和安装

Django框架介绍和安装 组件&#xff1a; 基本配置文件/路由器 模型层&#xff08;M&#xff09;/模板层&#xff08;T&#xff09;/视图层&#xff08;v&#xff09; Cookie和Seesion 分页及发邮件 Admin管理后台 init.py:Python包的初始化文件 wsgi.py:WEB服务网关的配…

Docker - Docker启动的MySql修改密码

基于上篇文章《Docker - Docker安装MySql并启动》&#xff0c;在Docker中启动了mysql服务&#xff0c;但是密码设置成了123456&#xff0c;想起来学生时代数据库被盗走&#xff0c;然后邮箱收到被勒索BTC的场景还历历在目&#x1f62d;&#xff0c;密码不能再设置这么简单了啊&…

vue中全局修改elementui,message修改时长

有几种不同的写法对应不同的修改方式&#xff0c;都写在main.js里 第一种 // this.$message.success(添加成功)[success, warning, info, error].forEach(type > {ElementUI.Message[type] options > {if (typeof options string) {options {message: options};opti…

AI AIgents时代 - (三.) AutoGPT和AgentGPT

前两篇讲解了Agent的原理和组件&#xff0c;这节我将给大家介绍两个agent项目&#xff0c;给出它们的工作原理和区别&#xff0c;并教大家亲手尝试使用 Agents&#x1f389; &#x1f7e2; AutoGPT&#x1f916;️ 我们的老朋友&#xff0c;之前文章也专门写过。AutoGPT 是一…

stack, queue 模拟与用法

stack 用法 stack stack 模拟 #include <deque> using namespace std; namespace sjy {template <typename T, typename Container deque<T>>class stack{public:void push(const T& x){_con.push_back(x);}void pop(){_con.pop_back();}T& top(…

【Vue-Element-Admin】table排序

背景 对表格排序大概分两种&#xff0c;一种是仅针对于当前界面排序(前端排序)&#xff0c;另一种是对全量数据进行排序(后端排序) 页面排序(前端排序) 通过 Table 的default-sort属性设置默认的排序列和排序顺序; 在列中设置sortable属性即可实现以该列为基准的排序&#x…

go sync.Map包装过的对象nil值的判断

被sync.Map包装过的nil 对象&#xff0c;是不能直接用if xxx nil的方式来判断的 func testnil() *interface{} {return nil }func main() {var ptr *interface{}test : testnil()//p &Person{}fmt.Printf("ptr 的值为 : %v\n", ptr)fmt.Printf("ptr 的值…