Leetcode - 周赛418

news2024/10/9 23:30:16

目录

一,3309. 连接二进制表示可形成的最大数值

二,3310. 移除可疑的方法

三,3311. 构造符合图结构的二维矩阵

四,3312. 查询排序后的最大公约数


一,3309. 连接二进制表示可形成的最大数值

本题数据范围较小,可以使用递归枚举每一种排列方式,计算出最大值,代码如下:

class Solution {
    int ans = 0;
    public int maxGoodNumber(int[] nums) {
        dfs(0, "", nums);
        return ans;
    }
    void dfs(int i, String res, int[] nums){
        if(i == (1<<3)-1){
            ans = Math.max(ans, Integer.parseInt(res, 2));
            return;
        }
        for(int j=0; j<3; j++){
            if((i>>j&1)==1) continue;
            dfs(i|1<<j, res + Integer.toBinaryString(nums[j]), nums);
        }
        return ;
    }
}

但是该方式只适用于数据范围较小的题,下面介绍一种 O(nlogn) 的做法,我们先用十进制的方式来思考一下,给你一个数组 [9,10] ,如何使得这个数组用十进制并接得到的值更大?我们当然是比较一下:是9在前大,还是10在前大,然后决定这两个拼接的顺序。那么拓展到大小为 n 的数组如何决定它们的顺序?和上述做法一样,相邻的数依次比较,类似于冒泡排序。那么对于本题使用二进制拼接也是同理,代码如下:

class Solution {
    public int maxGoodNumber(int[] t) {
        Integer[] nums = new Integer[t.length];
        for(int i=0; i<t.length; i++)
            nums[i] = t[i];
        //注意要想按照自己的想法排序,必须使用Integer数组
        Arrays.sort(nums, (x, y)->{
            int len_x = Integer.toBinaryString(x).length();
            int len_y = Integer.toBinaryString(y).length();
            int xy = x << len_y | y;
            int yx = y << len_x | x;
            return yx - xy;
        });
        int ans = 0;
        for(int x : nums){
            int len = Integer.toBinaryString(x).length();
            ans = ans << len | x;
        }
        return ans;
    }
}

二,3310. 移除可疑的方法

本题题意给你一个可疑方法 k,如果被 k 直接调用/间接调用,那么这些方法也被视为可疑方法(注意:调用可疑方法的方法不是可疑方法),如果没有其他方法调用可疑方法,返回非可疑方法;否则,返回所用方法。

我们可以建立一个图,使用 dfs/bfs 找到所有的可疑方法,然后枚举 invocations 数组,比如每个元素为 [x,y],如果 x 不是可疑方法 && y 是可疑方法,说明有非可疑方法调用可疑方法,返回所有方法;否则只返回非可疑方法。

代码如下:

class Solution {
    public List<Integer> remainingMethods(int n, int k, int[][] invocations) {
        List<Integer> ans = new ArrayList<>();
        List<Integer>[] g = new ArrayList[n];
        Arrays.setAll(g, e->new ArrayList<>());
        for(int[] e : invocations){
            g[e[0]].add(e[1]);
        }
        Queue<Integer> que = new LinkedList<>();
        que.add(k);
        Set<Integer> set = new HashSet<>();
        set.add(k);
        while(!que.isEmpty()){
            int x = que.poll();
            for(int y : g[x]){
                if(!set.contains(y)){
                    que.add(y);
                    set.add(y);
                }
            }
        }
        for(int[] e : invocations){
            if(!set.contains(e[0]) && set.contains(e[1])){
                for(int i=0; i<n; i++)
                    ans.add(i);
                return ans;
            }
        }
        for(int i=0; i<n; i++){
            if(!set.contains(i))
                ans.add(i);
        }
        return ans;
    }
}

三,3311. 构造符合图结构的二维矩阵

本题可以想象成拼拼图,我们可以先找到四个角落的点(如果行列>=3,那么它只有两个相邻的点),然后不断的往里拼,但是本题不知道四个角的对应位置,所以我们可以先找到一个角洛的点,然后往一边拼,注意一个边上点(除了角落的点),它们相邻的点有三个,不断的填充,直到找到一个这条边的另一个角落(即只有两个相邻点的点),这样我们就拼出一个边了,然后通过这个边不断的往下拼就行了。

上述是行列>=3的情况,如果它只有一行/列,那么它所有点中最少的相邻点必须为1,所以只需要判断最少的相邻是否为1,就直到是否是一行/列。

如果它只有两行/列,那么只需要判断所有点中最多的相邻点是否为4,如果不为4且不是一行/列,说明它只用两行/列。

代码如下:

class Solution {
    public int[][] constructGridLayout(int n, int[][] edges) {
        List<Integer>[] g = new ArrayList[n];
        Arrays.setAll(g, e->new ArrayList<>());
        for(int[] e : edges){
            g[e[0]].add(e[1]);
            g[e[1]].add(e[0]);
        }
        int[] node = new int[5];
        Arrays.fill(node, -1);
        for(int x=0; x<n; x++){
            node[g[x].size()] = x;
        }
        List<Integer> row = new ArrayList<>();
        if(node[1] != -1){
            row.add(node[1]);
        }else if(node[4]==-1){
            int x = node[2];
            for(int y : g[x]){
                if(g[y].size() == 2){
                    row.add(x);
                    row.add(y);
                    break;
                }
            }
        }else{
            int x = node[2];
            row.add(x);
            int pre = x;
            x = g[x].get(0);
            while(g[x].size() == 3){
                row.add(x);
                for(int y : g[x]){
                    if(y != pre && g[y].size() < 4){
                        pre = x;
                        x = y;
                        break;
                    }
                }
            }
            row.add(x);
        }
        int k = row.size();
        int[][] ans = new int[n/k][k];
        boolean[] vis = new boolean[n];
        for(int j=0; j<k; j++){//把第一行放进去
            int x = row.get(j);
            ans[0][j] = x;
            vis[x] = true;
        }
        for(int i=1; i<ans.length; i++){
            for(int j=0; j<k; j++){
                for(int y : g[ans[i-1][j]]){
                    if(!vis[y]){
                        vis[y] = true;
                        ans[i][j] = y;
                        break;
                    }
                }
            }
        }
        return ans;
    }
}

四,3312. 查询排序后的最大公约数

本题最重要的部分就是计算出每个 gcd 出现的次数,对于查询,我们可以使用二分前缀和的方式算出答案。

如何计算每个 gcd 出现的次数?假设要计算 gcd 等于 2 出现的次数,比如说有 n 个 2 的倍数,那么我们可以得到 Cn2 个数对(即 (n-1)*n/2 ),但是这么多数对,不一定每一个 gcd 的值都为 2,比如 4 和 8 的 gcd 就为 4,6 和 12 的 gcd 就为 6,所以我们需要从 (n-1)*n/2 个数对中减去数对的 gcd 为 4,6,8,....。这样就能得到 gcd 为 2 的数对个数了。

定义 cntGcd[i] 表示 gcd 为 i 的数对的个数,cntGcd[i] = (n-1)*n/2 - cntGcd[2*i] - cntGcd[3*i] - ...,从上述公式可以看出,要想计算出 cntGcd[i],必须先计算出 cntGcd[2*i]、cntGcd[3*i],所以我们需要从后往前遍历。

代码如下:

class Solution {
    //cnt[2] = C(n,2) - cnt[4] - cnt[6] - ...
    public int[] gcdValues(int[] nums, long[] queries) {
        int[] cntX = new int[50001];
        int mx = 0;
        for(int x : nums){
            cntX[x]++;
            mx = Math.max(mx, x);
        } 
        long[] cnt = new long[mx+1];
        for(int i=mx; i>=1; i--){
            int s = 0;
            for(int j=i; j<mx+1; j+=i){
                s += cntX[j];
                cnt[i] -= cnt[j]; //去除2i,3i,4i...(虽然j从i开始,但是cnt[i]初始值为0,所以实际上没有减去i)
                //为什么不是从2*i开始?因为要计算i的倍数的和s,如果从2i开始会少计算i出现的个数!!
            }
            cnt[i] += (long)(s - 1) * s / 2;
        }
        for(int i=1; i<mx+1; i++){
            cnt[i] += cnt[i-1]; 
        }
        int[] ans = new int[queries.length];
        for(int i=0; i<queries.length; i++){
            int l = 1, r = mx;
            while(l <= r){
                int mid = (l + r) / 2;
                if(cnt[mid] <= queries[i]){
                    //为什么加=?因为query[i]可以取到0(当然也可以写成cnt[mid]-1 < queries[i])
                    l = mid + 1;
                }else{
                    r = mid - 1;
                }
            }
            ans[i] = l;
        }
        return ans;
    }
}

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

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

相关文章

sklearn机器学习实战——随机森林回归与特征重要性分析全过程(附完整代码和结果图)

sklearn机器学习实战——随机森林回归与特征重要性分析全过程&#xff08;附完整代码和结果图&#xff09; 关于作者 作者&#xff1a;小白熊 作者简介&#xff1a;精通python、matlab、c#语言&#xff0c;擅长机器学习&#xff0c;深度学习&#xff0c;机器视觉&#xff0c;目…

南京大学《软件分析》李越, 谭添——1. 导论

导论 主要概念: soundcompletePL领域概述 动手学习 本节无 文章目录 导论1. PL(Programming Language) 程序设计语言1.1 程序设计语言的三大研究方向1.2 与静态分析相关方向的介绍与对比静态程序分析动态软件测试形式化(formal)语义验证(verification) 2. 静态分析:2.1莱斯…

爆红网络的膨胀飞天视频,背后竟是Pika1.5 AI视频模型!

最近&#xff0c;社交网络上疯传着各种动物、建筑等物体膨胀飞上天的搞笑视频。无论是真实的还是虚构的物体&#xff0c;都在视频中被压扁、融化、膨胀&#xff0c;引发了广泛的病毒式传播。而这些有趣的效果&#xff0c;都是由Pika最新推出的1.5版本AI视频模型所制作的。 Ai …

STM32输入捕获模式详解(下篇):PWM输入捕获与PWI模式

1. 前言 在上篇文章中&#xff0c;我们详细介绍了STM32输入捕获模式的基本原理和应用方法&#xff0c;包括测频法和测周法。本文将重点探讨如何通过STM32的PWI&#xff08;PWM Input&#xff09;模式实现对PWM信号的频率和占空比测量。我们将结合具体的硬件电路&#xff0c;解…

[万字解析]从零开始使用transformers微调huggingface格式的中文Bert模型的过程以及可能出现的问题

系列文章目录 使用transformers中的pipeline调用huggingface中模型过程中可能遇到的问题和修改建议 [万字解析]从零开始使用transformers微调huggingface格式的中文Bert模型的过程以及可能出现的问题 文章目录 系列文章目录前言模型与数据集下载模型下载数据集下载 数据加载、…

单细胞转录组 —— simpleaf 原始数据处理

单细胞转录组 —— 原始数据处理实战&#xff08;simpleaf&#xff09; 前言 Alevin-fry 是一个快速、准确且内存节约的单细胞和单核数据处理工具。 Simpleaf 是用 Rust 编写的程序&#xff0c;它提供了一个统一且简化的界面&#xff0c;用于通过 alevin-fry 流程处理一些最…

软件设计师——系统基础开发

&#x1f4d4;个人主页&#x1f4da;&#xff1a;秋邱-CSDN博客☀️专属专栏✨&#xff1a;软考——软件设计师&#x1f3c5;往期回顾&#x1f3c6;&#xff1a;软件设计师——信息安全&#x1f31f;其他专栏&#x1f31f;&#xff1a;C语言_秋邱 ​ 一、软件工程概述 1.1、考…

【Linux】man手册安装使用

目录 man(manual,手册) 手册安装: 章节区分&#xff1a; 指令参数: 使用场景&#xff1a; 手册内容列表: 手册查看快捷键: 实例: 仍致谢:Linux常用命令大全(手册) – 真正好用的Linux命令在线查询网站 提供的命令查询 在开头先提醒一下:在 man 手册中退出的方法很简单…

数字IC/FPGA AMBA总线 (内容参考B站UP主数字逻辑君)

1、 串行总线 SPI IIC UART Fsmc &#xff08;串行总线本文不再赘述&#xff0c;可以参考作者其他文章&#xff09; 总线简介&#xff1a; AMBA常用的系统总线&#xff1a;AHB&#xff0c;ASB&#xff0c;APB&#xff0c;AXI总线&#xff0c;一个Soc和外部的外设不可能每…

zigbee学习

24.10.7学习目录 一.简介1.分层2.zstack通信 一.简介 其是一种新兴的短距离无线通信技术&#xff0c;用于传感控制应用&#xff1b; 特性&#xff1a; 低功耗&#xff0c;比wifi蓝牙功耗更低&#xff1b;低成本&#xff1b;低速率&#xff1b;近距离&#xff1b;短时延&…

老外发微信时说“I‘ll ping you”是什么意思?发微信怎么用英语说柯桥学英语到哪里?

“发信息”还可以怎么说&#xff1f; 其实很简单&#xff0c;message做动词时&#xff0c;可以直接表达&#xff1a;发信息 ▼ &#x1f330;举个例子 I messaged him yesterday but havent had a reply. 昨天我给他发了短信&#xff0c;但没有回音。 我们现在常说的“发信…

使用Python批量修改文件修改日期为随机的6到8月份

使用Python批量修改文件修改日期为随机的6到8月份 每当雪花飘起的时候&#xff0c;总有一股抹不去的情节&#xff0c;会想起儿时雪天的记忆&#xff0c;虽然模糊但也清晰。那时每年的冬季很冷&#xff0c;但依然喜欢飘雪的日子&#xff0c;看着满天迷蒙飘舞的雪花总有想不完的心…

生成树实验

1 生成树关键点&#xff0c; 第一树根&#xff0c;第二在每个非根桥找root端口 第三 在每个物理片段找指定网桥&#xff0c;第四指定网桥对应的端口就是指定端口 bpdu 比较的方式 root 桥&#xff0c;到root 桥的路径开销&#xff0c;指定桥&#xff0c;指定端口&#x…

双登股份再战IPO:数据打架,实控人杨善基千万元股权激励儿子

撰稿|行星 来源|贝多财经 近日&#xff0c;双登集团股份有限公司&#xff08;下称“双登股份”&#xff09;递交招股书&#xff0c;准备在港交所主板上市&#xff0c;中金公司、建银国际、华泰国际为其联席保荐人。 贝多财经了解到&#xff0c;这并非双登股份首次向资本市场…

谷歌AI大模型Gemini API快速入门及LangChain调用视频教程

1. 谷歌Gemini API KEY获取及AI Studio使用 要使用谷歌Gemini API&#xff0c;首先需要获取API密钥。以下是获取API密钥的步骤&#xff1a; 访问Google AI Studio&#xff1a; 打开浏览器&#xff0c;访问Google AI Studio。使用Google账号登录&#xff0c;若没有账号&#xf…

体制内的必须要知道的“人情世故”及职场礼仪

最近&#xff0c;一位新来的小姑娘在参加活动的时候给外来领导带路&#xff0c;结果到跟前时&#xff0c;没有及时退让&#xff0c;夹在了自己领导与外来领导之间&#xff0c;妨碍了两位领导握手&#xff0c;下来后被一顿狠批。这其实是新人不太懂职场礼仪导致的&#xff0c;笔…

OpenCV库模块解析

1.OpenCV库每个模块解析 2.OpenCV的常用函数 它为计算机视觉应用程序提供了一个通用的基础设施&#xff0c;并加速了在商业产品中使用机器感知。作为BSD许可的产品&#xff0c;OpenCV使企业可以很容易地利用和修改代码。该库拥有超过2500个优化算法&#xff0c;其中包括经典和最…

大数据-158 Apache Kylin 安装配置详解 集群模式启动

点一下关注吧&#xff01;&#xff01;&#xff01;非常感谢&#xff01;&#xff01;持续更新&#xff01;&#xff01;&#xff01; 目前已经更新到了&#xff1a; Hadoop&#xff08;已更完&#xff09;HDFS&#xff08;已更完&#xff09;MapReduce&#xff08;已更完&am…

无线麦克风什么牌子的音质效果好?选购中必须警惕劣质产品

在音频设备不断推陈出新、日益丰富多样的今天&#xff0c;无线领夹麦克风以其独有的优点崭露头角。它的设计非常精巧&#xff0c;佩戴起来既舒适又方便&#xff0c;并且在各种不同的环境下都能保证音质稳定以及传输效果良好。 无论是在户外进行拍摄、室内开展直播&#xff0c;…

uniapp学习(003-3 vue3学习 Part.3)

零基础入门uniapp Vue3组合式API版本到咸虾米壁纸项目实战&#xff0c;开发打包微信小程序、抖音小程序、H5、安卓APP客户端等 总时长 23:40:00 共116P 此文章包含第21p-第p25的内容 文章目录 双向绑定的实现原理例子 计算属性例子1双向绑定格式改成计算属性 例子2 watchwatc…