【力扣周赛】第 364 场周赛⭐(前后缀分解+单调栈DFS技巧)

news2024/11/26 11:55:04

文章目录

  • 竞赛链接
  • Q1:2864. 最大二进制奇数(贪心)
    • 写法1——手动模拟(代码长,运行快)
    • 写法2——API(代码短,运行慢)
  • Q2:2865. 美丽塔 I
    • 竞赛时代码——枚举山顶
  • Q3:2866. 美丽塔 II⭐(前后缀分解+单调栈)
    • 学习到的技巧
    • 相关题目列表📕
  • Q4:2867. 统计树中的合法路径数目(⭐)
    • 解法——枚举质数为根+DFS非质数连通块
      • 学习到的技巧
    • 相似题目——2242. 节点序列的最大得分
      • 解法——枚举中间的边
  • 成绩记录

竞赛链接

https://leetcode.cn/contest/weekly-contest-364/

Q1:2864. 最大二进制奇数(贪心)

https://leetcode.cn/problems/maximum-odd-binary-number/description/

贪心:最后一位保留一个 1,其余的 1 都放置在最开始的位置。

写法1——手动模拟(代码长,运行快)

class Solution {
    public String maximumOddBinaryNumber(String s) {
        int n = s.length(), cnt = 0;
        char[] chs = s.toCharArray();
        for (int i = 0; i < n; ++i) {
            if (chs[i] == '1') ++cnt;
        }
        for (int i = 0; i < n; ++i) {
            if (i < cnt - 1) chs[i] = '1';
            else chs[i] = '0';
        }
        chs[n - 1] = '1';
        return new String(chs);
    }
}

写法2——API(代码短,运行慢)

public class Solution {
    public String maximumOddBinaryNumber(String s) {
        int cnt1 = (int) s.chars().filter(c -> c == '1').count();
        return "1".repeat(cnt1 - 1) + "0".repeat(s.length() - cnt1) + "1";
    }
}

Q2:2865. 美丽塔 I

https://leetcode.cn/problems/beautiful-towers-i/description/

竞赛时代码——枚举山顶

计算每一个位置作为最高点时的最大结果,对所有结果取最大。

class Solution {
    public long maximumSumOfHeights(List<Integer> maxHeights) {
        long ans = 0;
        int n = maxHeights.size();
        for (int i = 0; i < n; ++i) {
            ans = Math.max(ans, op(i, maxHeights));
        }
        return ans;
    }
    
    public long op(int k, List<Integer> maxHeights) {
        long ans = maxHeights.get(k);
        long l = maxHeights.get(k), r = maxHeights.get(k);
        for (int i = k - 1; i >= 0; --i) {
            l = Math.min(maxHeights.get(i), l);
            ans += l;
        }
        for (int i = k + 1; i < maxHeights.size(); ++i) {
            r = Math.min(maxHeights.get(i), r);
            ans += r;
        }       
        if (l <= 0 || r <= 0) return 0;
        return ans;
    }
}

Q3:2866. 美丽塔 II⭐(前后缀分解+单调栈)

https://leetcode.cn/problems/beautiful-towers-ii/description/

在这里插入图片描述

class Solution {
    public long maximumSumOfHeights(List<Integer> maxHeights) {
        int[] a = maxHeights.stream().mapToInt(i -> i).toArray();   // 列表转数组
        int n = a.length;
        long[] suf = new long[n + 1];
        Deque<Integer> stk = new ArrayDeque<>();    // 单调递增的单调栈
        stk.push(n);                                // 加入 n 作为哨兵
        long sum = 0;
        // 从后往前
        for (int i = n - 1; i >= 0; --i) {
            int x = a[i];
            while (stk.size() > 1 && x <= a[stk.peek()]) {
                int j = stk.pop();
                sum -= (long) a[j] * (stk.peek() - j);  // 删除之前加到sum中的
            }
            sum += (long) x * (stk.peek() - i);         // 从i到stk.peek()-1都是x
            suf[i] = sum;
            stk.push(i);
        }

        long ans = sum;
        stk.clear();
        stk.push(-1);
        // 从前往后
        long pre = 0;
        for (int i = 0; i < n; ++i) {
            int x = a[i];
            while (stk.size() > 1 && x <= a[stk.peek()]) {
                int j = stk.pop();
                pre -= (long) a[j] * (j - stk.peek());
            }
            pre += (long) x * (i - stk.peek());
            ans = Math.max(ans, pre + suf[i + 1]);
            stk.push(i);
        }
        return ans;
    }
}

学习到的技巧

  1. 撤销累加
  2. 加入哨兵

相关题目列表📕

【算法】前后缀分解题单
【算法】单调栈题单(矩阵系列、字典序最小、贡献法)

Q4:2867. 统计树中的合法路径数目(⭐)

https://leetcode.cn/problems/count-valid-paths-in-a-tree/description/

解法——枚举质数为根+DFS非质数连通块

class Solution {
    final static int MX = (int)1e5;
    final static boolean[] np = new boolean[MX + 1];    // 质数false,非质数true

    static {
        np[1] = true;
        for (int i = 2; i <= MX / i; ++i) {
            if (!np[i]) {
                for (int j = i * i; j <= MX; j += i) {
                    np[j] = true;
                }
            }
        }
    }

    public long countPaths(int n, int[][] edges) {
        // 建树
        List<Integer>[] g = new ArrayList[n + 1];
        Arrays.setAll(g, e -> new ArrayList<>());
        for (int[] e: edges) {
            int x = e[0], y = e[1];
            g[x].add(y);
            g[y].add(x);
        }

        long ans = 0;
        int[] size = new int[n + 1];
        List<Integer> nodes = new ArrayList<>();    // 记录一个连通块中的所有节点
        for (int x = 1; x <= n; ++x) {
            if (np[x]) continue;        // 如果不是质数,就跳过。
            int sum = 0;
            for (int y: g[x]) {         // 质数x将这棵树分成了若干个连通块
                if (!np[y]) continue;
                if (size[y] == 0) {     // y还没有被计算过
                    nodes.clear();
                    dfs(y, -1, g, nodes);
                    for (int z: nodes) size[z] = nodes.size();
                }
                ans += (long)size[y] * sum; // 与之前的连通块做乘法原理
                sum += size[y];
            }
            ans += sum;                 // 从x出发的路径
        }
        return ans;
    }

    // dfs过程是将这个连通块中的节点都放入nodes列表中
    void dfs(int x, int fa, List<Integer>[] g, List<Integer> nodes) {
        nodes.add(x);
        for (int y: g[x]) {
            if (y != fa && np[y]) {
                dfs(y, x, g, nodes);
            }
        }
    }
}

学习到的技巧

  1. dfs的过程将所有经过的节点放入一个列表中,这样就可以记录连通块的大小。
  2. 为了防止重复计算某个节点,创建一个数组存储其是否被经历过即可,这里可以直接存储它所在连通块的大小。

相似题目——2242. 节点序列的最大得分

https://leetcode.cn/problems/maximum-score-of-a-node-sequence/description/

周赛题目本质上是求一种类似于「非质数-质数-非质数」的路径个数。
这两题的共同点在于「枚举中间」,请读者细细品味。

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

解法——枚举中间的边

建树的过程中,对于每个节点只保留与它相连的最大的那三条边即可。
建树之后,枚举每条边作为中间边的情况,更新最大值。

class Solution {
    public int maximumScore(int[] scores, int[][] edges) {
        int n = scores.length;
        List<int[]>[] g = new ArrayList[n];
        Arrays.setAll(g, e -> new ArrayList());
        for (int[] edge: edges) {
            int x = edge[0], y = edge[1];
            g[x].add(new int[]{scores[y], y});
            g[y].add(new int[]{scores[x], x});
        }
        for (int i = 0; i < n; ++i) {
            // 如果和i相连的点的数量>3,就可以删掉只剩3个最大的
            // 这样删可以确保和它组成一个序列的另外3个值都不会被删掉
            // 即对于序列a-x-y-b,枚举到x的时候要保证a,y,b都不会被删掉
            // 删去其它的边是为了后面遍历的时候快一些
            if (g[i].size() > 3) {
                g[i].sort((a, b) -> (b[0] - a[0]));     // 按照score从大到小排序
                g[i] = new ArrayList<>(g[i].subList(0, 3));
            }
        }

        int ans = -1;
        // 枚举每个边作为中间的边
        for (int[] edge: edges) {
            int x = edge[0], y = edge[1];
            for (int[] p: g[x]) {
                int a = p[1];       // x旁边的节点号a
                for (int[] q: g[y]) {
                    int b = q[1];   // y旁边的节点号b
                    if (a != y && b != x && a != b) {
                        ans = Math.max(ans, p[0] + q[0] + scores[x] + scores[y]);
                    }
                }
            }
        }
        return ans;
    }   
}

成绩记录

在这里插入图片描述

很差劲,脑子是糊掉的。

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1053317.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

C++ 基础_Day01

准备工具Vscode或者Clion或者Dev C或者Vs studio 和 MSYS2 是C跨平台的重要工具链. 文章目录 准备工作安装MSYS2软件 创建文件 一、基本介绍1.1C源文件1.2 代码注释1.3变量与常量1.3.1变量1.3.2 常量1.3.3 二者的区别&#xff1a; 1.4 关键字和标识符 二、数据类型2.1 基本数据…

嵌入式Linux应用开发-第十四章查询方式的按键驱动程序

嵌入式Linux应用开发-第十四章查询方式的按键驱动程序 第十四章 查询方式的按键驱动程序_编写框架14.1 LED驱动回顾14.2 按键驱动编写思路14.3 编程&#xff1a;先写框架14.3.1 把按键的操作抽象出一个button_operations结构体14.3.2 驱动程序的上层&#xff1a;file_operation…

自动驾驶中的感知模型:实现安全与智能驾驶的关键

自动驾驶中的感知模型&#xff1a;实现安全与智能驾驶的关键 文章目录 引言感知模型的作用感知模型的技术安全与挑战结论 2023星火培训【专项营】Apollo开发者社区布道师倾力打造&#xff0c;包含PnC、新感知等的全新专项课程上线了。理论与实践相结合&#xff0c;全新的PnC培训…

【洛谷】P3378 【模板】堆

原题链接&#xff1a;https://www.luogu.com.cn/problem/P3378 目录 1. 题目描述 2. 思路分析 3. 代码实现 1. 题目描述 2. 思路分析 一道模板题&#xff0c;主要是熟悉STL中优先队列&#xff08;priority_queue&#xff09;的使用。 堆的STL实现: priority_queue<in…

国庆周《LInux学习第四课》

国庆周《LInux学习第四课》 软件的安装与卸载 图解

无人注意,新安装的 Ubuntu 23.04 不支持安装 32 位应用

导读新安装的 Ubuntu 23.04 不支持安装 32 位应用。 无人注意&#xff0c;新安装的 Ubuntu 23.04 不支持安装 32 位应用 有用户报告&#xff0c;在新安装的 Ubuntu 23.04 上从 Ubuntu 仓库安装的 Steam 客户端是不工作的。在 Ubuntu 23.04 中使用了基于 Flutter 的新安装程序…

故障:无线鼠标键盘有时候出现短暂失灵的情况

无线鼠标连台式机用的&#xff0c;之前一直没问题&#xff0c;最近开始出现短暂失灵的情况。 并不是有延时&#xff0c;因为在失灵期间的那些操作在恢复后不会执行。 有的时候&#xff0c;电脑是在打开或者关闭某些应用&#xff0c;即调用cpu的情况&#xff0c;这个时候出问题…

k8s搭建EFK日志系统

搭建 EFK 日志系统 前面大家介绍了 Kubernetes 集群中的几种日志收集方案&#xff0c;Kubernetes 中比较流行的日志收集解决方案是 Elasticsearch、Fluentd 和 Kibana&#xff08;EFK&#xff09;技术栈&#xff0c;也是官方现在比较推荐的一种方案。 Elasticsearch 是一个实…

Cannot download sources:IDEA源码无法下载

问题 Swagger的相关包&#xff0c;无法看到注释&#xff1b; 在class文件的页面&#xff0c;点击下载源码&#xff0c;源码下载不了&#xff0c;IDEA报下面的错误。 报错 Cannot download sources Sources not found for: io.swagger.core.v3:swagger-annotations:2.2.9 解决…

差分放大器的精髓:放大差模信号 抑制共模信号

参考如图基本的差分放大电路&#xff0c;在R1R2 R3R4的条件下&#xff0c;其输出与输入的关系为 &#xff1a; 具体推导过程参考&#xff1a;差分运算放大器的放大倍数的计算及结论_正在黑化的KS的博客-CSDN博客 由这个式子我们可以发现&#xff0c;差分放大器放大的是同相端与…

凉鞋的 Godot 笔记 103. 检视器 :节点的微观编辑和查看

在上一篇&#xff0c;笔者简单介绍了场景与节点的增删改查&#xff0c;如下所示: 在这一篇&#xff0c;我们接着往下学习。 我们知道在场景窗口&#xff0c;可以对节点进行增删改查。 在 Godot 引擎使用过程中&#xff0c;场景窗口的使用频率是非常高的。 但是场景窗口只能编…

系统集成|第二十一章(笔记)

目录 第二十一章 知识产权与法律法规21.1 知识产权21.2 法律法规 上篇&#xff1a;第二十章、收尾管理 第二十一章 知识产权与法律法规 21.1 知识产权 概述&#xff1a;狭义的知识产权就是传统意义上的知识产权&#xff0c;包括著作权&#xff08;含邻接权&#xff09;&#x…

深度学习——模型选择、欠拟合和过拟合

深度学习——模型选择、欠拟合和过拟合 文章目录 前言一、训练误差和泛化误差1.1. 统计学习理论1.2. 模型复杂性 二、模型选择2.1. 验证集2.2. K折交叉验证 三、欠拟合 or 过拟合3.1. 模型复杂性3.2. 数据集大小 四、多项式回归4.1. 生成数据集4.2. 对模型进行训练和测试4.3. 三…

Egg 封装接口返回信息

中间件封装 代码 const msgArr {"200":成功,"401":token失效 } module.exports (option, app) > {return async function(ctx, next) {try{//成功是返回的信息ctx.emit(code,data,msg)>{console.log(1111,code,data,msg)ctx.body {code,data:dat…

嵌入式Linux应用开发-第十三章APP怎么读取按键值

嵌入式Linux应用开发-第十三章读取按键及按键驱动程序 第十三章 APP怎么读取按键值13.1 妈妈怎么知道孩子醒了13.2 APP读取按键的4种方法13.2.1 查询方式13.2.2 休眠-唤醒方式13.2.3 poll方式13.2.4 异步通知方式13.2.4.1 异步通知的原理&#xff1a;发信号13.2.4.2 应用程序之…

MyBatisPlus(六)字段映射 @TableField

字段注解&#xff08;非主键&#xff09; TableField 用于映射对象的 属性 和表中的 字段 。 当 属性名 和 字段名 差异较大的时候&#xff0c;无法通过默认的映射关系对应起来&#xff0c;就需要指定 属性名 对应 的 字段名。 官网示例 代码实例 package com.example.web.…

clip代码安装实操

CLIP模型及代码地址&#xff1a;GitHub - openai/CLIP: Contrastive Language-Image Pretraining 代码准备环境 先创建一个anaconda虚拟环境&#xff0c;包含python3.7版本&#xff0c;将该环境命名为clip。成功。 &#xff08; pytorch1.7.1 所需 python 版本 >3.6&…

JVM内存线程Dump

Heap Dump文件生成 Heap Dump是指在Java虚拟机中&#xff0c;将当前内存中的对象信息以二进制形式保存到文件中的操作。它可以用于分析内存泄漏、内存溢出等内存相关问题。 生成Heap Dump文件的方式有多种&#xff0c;可以通过命令行工具如jmap、jcmd&#xff0c;也可以通过J…

Golang中的包和模块设计

Go&#xff0c;也被称为Golang&#xff0c;是一种静态类型、编译型语言&#xff0c;因其简洁性和对并发编程的强大支持而受到开发者们的喜爱。Go编程的一个关键方面是其包和模块系统&#xff0c;它允许创建可重用、可维护和高效的代码。本博客文章将深入探讨在Go中设计包和模块…

数据结构 图 并查集 遍历方法 最短路径算法 最小生成树算法 简易代码实现

文章目录 前言并查集图遍历方法广度优先遍历深度优先遍历 最小生成树算法Kruskal算法Prim算法 最短路径算法Dijkstra算法BellmanFord算法FloydWarshall算法 全部代码链接 前言 图是真的难&#xff0c;即使这些我都学过一遍&#xff0c;再看还是要顺一下过程&#xff1b;说明方…