Leetcode - 361周赛

news2025/1/19 17:02:21

一,2843. 统计对称整数的数目

 这道题直接暴力,要注意的一点是这个数字必须是由 2 * N 位数字组成。

代码如下:

class Solution {
    public int countSymmetricIntegers(int low, int high) {
        int ans = 0;
        for(int i=low; i<=high; i++){
            if(i>10 && isVaild(i)){
                ans++;
            }
        }
        return ans;
    }
    boolean isVaild(int i){
        int sum1 = 0, sum2 = 0;
        String s = String.valueOf(i);
        int n = s.length();
        if(n%2 == 1) return false;//必须是2*N位数组成的整数
        for(int j=0; j<n/2; j++){
            sum1 += (int)(s.charAt(j)-'0');
            sum2 += (int)(s.charAt(n-j-1)-'0');
        }
        return sum1==sum2;
    }
}

二,2844. 生成特殊数字的最少操作

 这道题要我们找到将 num 字符串操作最少次数得到 %25 == 0 的数,那我们首先要找到%25==0的数有什么特点?我们发现 %25==0 的数的后两位必然是 00,25,50,75。那么我们可以分情况讨论,比如:将 num 字符串的后两位变成 00 需要操作多少次?将 num 字符串的后两位变成 25 需要操作多少次?将 num 字符串的后两位变成 50 需要操作多少次?将 num 字符串的后两位变成 75 需要操作多少次?最后取其中的最小值。

还需要注意的一点是,有可能该字符串不管怎么操作都不能使得后两位的值变成上述四种情况中的一种,比如:"2230467",这个时候,我们就需要将该字符串变成 0 (毕竟 0%25 = 0),这种情况我们需要统计字符串中 0 的个数,然后得到答案 num.length() - cnt(0)。

代码如下:

class Solution {
    public int minimumOperations(String num) {
        int cnt = 0;
        int index0 = num.lastIndexOf('0');
        int index2 = num.lastIndexOf('2');
        int index5 = num.lastIndexOf('5');
        int index7 = num.lastIndexOf('7');
        int ans = 100;
        if(index0 >= 0){
            for(int i=index0-1; i>=0; i--){
                char ch = num.charAt(i);
                System.out.println(ch);
                if(ch=='0'||ch=='5'){//将00,50的情况合并
                    ans = Math.min(ans,num.length()-i-2);
                    break;
                }
            }
        }
        if(index5 >= 0)
            for(int i=index5-1; i>=0; i--){
                char ch = num.charAt(i);
                if(ch=='2'||ch=='7'){//将25,75的情况合并
                    ans = Math.min(ans,num.length()-i-2);
                    break;
                }
            }
        for(int i=0; i<num.length(); i++){
            if(num.charAt(i)=='0')
                cnt++;
        }
        return Math.min(num.length()-cnt,ans);
    }
}

三,2845. 统计趣味子数组的数目

这道题目分成 4 个部分:

1. 转化 

        遍历数组,将满足 nums[ i ] % modulo == k 的 nums[ i ] 直接赋值成 1 ,将不满足条的nums[ i ] 赋值为 0 ,因为我们最后要算的是满足 cnt % modulo == k 的子数组

2. 前缀和

        得到转化后的nums数组后,定义一个数组 prev 来统计nums的前缀和,此时我们设 left 是nums子数组的左边界, right 是nums子数组的右边界 [left,right],此时我们子数组中的 cnt = prev[right+1] - prev[left],这里有一个注意点,我们定义的 prev 数组的长度 = nums.length + 1,prev[0] = 0,画个图理解一下:

3. %运算 (注意:R = right+1)

        cnt%modulo = prev[R]%modulo-prev[L]%modulo = k

        1. prev[R]%modulo > prev[L]%modulo

            prev[R]%modulo-prev[L]%modulo = k

            prev[R]%modulo - k = prev[L]%modulo

        2. prev[R]%modulo < prev[L]%modulo

            prev[R]%modulo-prev[L]%modulo+modulo = k

            prev[R]%modulo - k + modulo = prev[L]%modulo

    结果:prev[L]%modulo = (prev[R]%modulo - k + modulo)%modulo

    现在这道题就变成了一道 "两数之和" 的题目!!

4. 滑动数组

代码如下:

class Solution {
    public long countInterestingSubarrays(List<Integer> nums, int modulo, int k) {
        Map<Integer,Integer> map = new HashMap<>();
        int[] preSum = new int[nums.size()+1];
        for(int i=0; i<nums.size(); i++){
            preSum[i+1] = preSum[i]+(nums.get(i)%modulo==k?1:0);
        }
        long ans = 0;
        for(int i=0; i<=nums.size(); i++){
            ans += map.getOrDefault((preSum[i]%modulo - k + modulo)%modulo,0);
            //R = i,代表子树组的右边为 i,在[0,i]下标处找子数组的左边边界

            map.put(preSum[i]%modulo,map.getOrDefault(preSum[i]%modulo,0)+1);
            //L = i,更新下标为 i 的左边边界的子数组有几个
        }
        return ans;
    }
}

四,2846. 边权重均等查询

这道题还是使用了树上倍增的算法思想,我借鉴了一下大佬的写法,我加了一些注释,直接看代码:

class Solution {
    public int[] minOperationsQueries(int n, int[][] edges, int[][] queries) {
        List<int[]>[] g = new ArrayList[n];
        Arrays.setAll(g,e -> new ArrayList<>());
        for(var e : edges){
            int x = e[0], y = e[1], w = e[2]-1;
            g[x].add(new int[]{y,w});
            g[y].add(new int[]{x,w});
        }//记录每一个节点的相邻节点及权重

        int m = 32 - Integer.numberOfLeadingZeros(n);
        var pa = new int[n][m];
        //n:节点,m:向上走2^m步, pa[i][j]:到达哪个节点
        for(int i=0; i<n; i++){
            Arrays.fill(pa[i],-1);
        }
        var cnt = new int[n][m][26];
        //从n向上走 2^m步 过程中 每个权重的个数
        var depth = new int[n];//每个节点的深度
        dfs(0,-1,g,pa,cnt,depth);

        //树上倍增
        for(int i=0; i<m-1; i++){
            for(int x = 0; x < n; x++){
                int p = pa[x][i];
                if(p != -1){
                    int pp = pa[p][i];
                    pa[x][i+1] = pp;
                    for(int j = 0; j < 26; j++){
                        cnt[x][i+1][j] = cnt[x][i][j] + cnt[p][i][j];
                    }
                }
            }
        }

        //交换
        var ans = new int[queries.length];
        for(int qi = 0; qi < queries.length; qi++){
            int x = queries[qi][0], y = queries[qi][1];
            int pathLen = depth[x] + depth[y];
            var cw = new int[26];//统计不同权重的个数
            if(depth[x] > depth[y]){
                int tmp = x;
                x = y;
                y = tmp;
            }
            //让y向上走,使得x,y节点的深度一样
            for(int k = depth[y]-depth[x]; k > 0; k &= k-1){
                int i = Integer.numberOfTrailingZeros(k);
                int p = pa[y][i];//j向上走2^i步
                for(int j=0; j<26; j++){
                    cw[j] += cnt[y][i][j];//统计y向上走的过程中的权重
                }
                y = p;//y节点走到p节点位置
            }

            if(y != x){//x,y同时向上走,找到相遇点
                for(int i=m-1; i>=0; i--){
                    int px = pa[x][i];//从x节点向上走2^i步
                    int py = pa[y][i];//从y节点向上走2^i步
                    if(px != py){
                        for(int j=0; j<26; j++){
                            cw[j] += cnt[x][i][j]+cnt[y][i][j];//统计x,y向上走的过程中的权重
                        }
                        x = px;//更新x的位置
                        y = py;//更新x的位置
                    }
                }
                for(int j = 0; j < 26; j++){
                    cw[j] += cnt[x][0][j] + cnt[y][0][j];//统计x,y向上走的过程中,不同权重的个数
                }
                x = pa[x][0];//注意要在往上走一步才是相遇点
            }

            int lca = x;
            pathLen -= depth[lca]*2;//真正的路径长度
            int maxCw = 0;//求出现次数最多的权重
            for(int i=0; i<26; i++){
                maxCw = Math.max(maxCw,cw[i]);
            }
            ans[qi] = pathLen - maxCw;//路径长度-权重出现最多次数=操作最少
        }
        return ans;
    }

    private void dfs(int x, int fa, List<int[]>[] g, int[][] pa, int[][][] cnt, int[] depth) {
        pa[x][0] = fa;//初始化
        for (var e : g[x]) {//遍历x节点可以走向那些节点
            int y = e[0], w = e[1];
            //y:x走向的那些节点,w:从x节点到y节点的权重
            if (y != fa) {//不能重复计算 比如:i->j j->i
                cnt[y][0][w] = 1;//初始化每个节点向周围走一步的权重
                depth[y] = depth[x] + 1;//初始化每个节点的深度
                dfs(y, x, g, pa, cnt, depth);
            }
        }
    }
}

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

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

相关文章

threejs的dat.gui辅助工具的使用

threejs的dat.gui辅助工具的使用 安装使用 安装 npm i dat.gui -S 使用 import dat from dat.gui const controlData {rotationSpeed: 0.01,color: #66ccff,wireframe: false } const gui new dat.GUI() const f gui.addFolder(配置) f.add(controlData, rotationSpeed, …

【Proteus仿真】【STM32单片机】血压心率血氧体温蓝牙

文章目录 一、功能简介二、软件设计三、实验现象联系作者 一、功能简介 系统运行后&#xff0c;LCD1604液晶显示心率、血氧、血压和体温&#xff0c;及其阈值&#xff1b;可通过K3键进入阈值设置模式&#xff0c;K1和K2加减调节&#xff0c;K4确定&#xff1b;当检测心率、血氧…

Java JUC 并发编程(笔记)

文章目录 再谈多线程并发与并行顺序执行并发执行并行执行 再谈锁机制重量级锁轻量级锁偏向锁锁消除和锁粗化 JMM内存模型Java内存模型重排序volatile关键字happens-before原则 多线程编程核心锁框架Lock和Condition接口可重入锁公平锁与非公平锁 读写锁锁降级和锁升级 队列同步…

ARMv7-A 那些事 - 2.通用寄存器与流水线

By: Ailson Jack Date: 2023.09.10 个人博客&#xff1a;http://www.only2fire.com/ 本文在我博客的地址是&#xff1a;http://www.only2fire.com/archives/154.html&#xff0c;排版更好&#xff0c;便于学习&#xff0c;也可以去我博客逛逛&#xff0c;兴许有你想要的内容呢。…

Visual Studio 2019 简单安装教程

思路 官方页面下载 – 安装Visual Studio Installer – 安装Visual Studio 2019 下载 打开页面&#xff1a;Visual Studio 2019 生成号和发布日期 | Microsoft Learn 点击需要的版本&#xff0c;跳转后会开始下载在线安装包&#xff0c;这里选择第一个Community版本 安装 …

SpringBoot【基础篇】

一、快速上手 按照要求&#xff0c;左侧选择web&#xff0c;然后在中间选择Spring Web即可&#xff0c;选完右侧就出现了新的内容项&#xff0c;这就表示勾选成功了 关注&#xff1a;此处选择的SpringBoot的版本使用默认的就可以了&#xff0c;需要说一点&#xff0c;SpringBo…

PatchMatchNet 学习笔记 译文 深度学习三维重建

9 PatchMatchNet CVPR-2021 patchmatchnet源码下载 PatchMatchNet 代码注释版 下载链接(注释非常详细,较源码结构有调整,使用起来更方便) PatchMatchNet-CVPR-2021(源码、原文+注释+译文+批注) 9.0 主要特点 金字塔,基于传统的PatchMatch算法,精度高,速度快 Pa…

Redis带你深入学习数据类型set

目录 1、set 2、set相关命令 2.1、添加元素 sadd 2.2、获取元素 smembers 2.3、判断元素是否存在 sismember 2.4、获取set中元素数量 scard 2.5、删除元素spop、srem 2.6、移动元素smove 2.7、集合中相关命令&#xff1a;sinter、sinterstore、sunion、sunionstore、s…

基于SSM的在线购物系统

末尾获取源码 开发语言&#xff1a;Java Java开发工具&#xff1a;JDK1.8 后端框架&#xff1a;SSM 前端&#xff1a;采用JSP技术开发 数据库&#xff1a;MySQL5.7和Navicat管理工具结合 服务器&#xff1a;Tomcat8.5 开发软件&#xff1a;IDEA / Eclipse 是否Maven项目&#x…

nrf52832 GPIO输入输出设置

LED_GPIO #define LED_START 17 #define LED_0 17 #define LED_1 18 #define LED_2 19 #define LED_3 20 #define LED_STOP 20设置位输出模式&#xff1a; nrf_gpio_cfg_output(LED_0); 输出高电平:nrf_gpio_pin_set(LED_0); 输…

sqli-labs关卡之一(两种做法)

目录 一、布尔盲注(bool注入) 二、时间盲注(sleep注入) 一、布尔盲注(bool注入) 页面没有报错和回显信息&#xff0c;只会返回正常或者不正常的信息&#xff0c;这时候就可以用布尔盲注 布尔盲注原理是先将你查询结果的第一个字符转换为ascii码&#xff0c;再与后面的数字比较…

[EROOR] SpringMVC之500 回调函数报错

首先&#xff0c;检查一下idea里面的报错的原因&#xff0c;我的是jdk的版本的问题。所以更换一下就可以了。

操作系统:四大特征(并发,共享,虚拟,异步)

1.并发 1.并发的定义 并发:指两个或多个事件在同一时间间隔内发生。 这些事件宏观上是同时发生的&#xff0c;但微观上是交替发生的。 值得注意的是&#xff0c;与并行&#xff08;指两个或多个事件在同一时刻同时发生&#xff09;区分开来。 2.操作系统的并发性 指计算机…

【微信读书】数据内容接口逆向调试01

需求爬取微信读书的某一本书的整本书的内容 增强需求&#xff0c;大批量爬取一批书籍内容 众所周知微信读书是一个很好用的app&#xff0c;他上面书籍的格式很好&#xff0c;质量很高。 本人充值了会员但是看完做完笔记每次还得去翻很不方便&#xff0c;于是想把书籍内容弄下…

【Unity基础】3.脚本控制物体运动天空盒

【Unity基础】3.脚本控制物体运动&天空盒 大家好&#xff0c;我是Lampard~~ 欢迎来到Unity基础系列博客&#xff0c;所学知识来自B站阿发老师~感谢 &#xff08;一&#xff09;搭建开发环境 &#xff08;1&#xff09;下载visual studio 在我们下载unity编译器的时候&…

十一)Stable Diffussion使用教程:人物三视图

现在我们通过一个个具体的案例,去进阶SD的使用。 本篇案例:绘制Q版人物三视图 1)我们先选择一个偏3D的模型,选择文生图,输入魔法; 2)然后选择触发三视图的Lora:<lora:charturnerbetaLora_charturnbetalora:0.6>,注意这里的名称都是本地重新命名的,非原来C站下…

PLC编码器测速(限幅滤波+中心差分法求导SCL源代码)

M法测速的基本原理,大家可以查看专栏的系列文章,这里不再赘述常用链接如下: PLC通过编码器反馈值计算速度的推荐做法(算法解析+ST代码)_编码器脉冲怎么转换为速度_RXXW_Dor的博客-CSDN博客PLC如何测量采集编码器的位置数据,不清楚的可以参看我的另一篇博文:三菱FX3U PLC…

十五、Webpack打包图片-js-Vue、Label命令、resolve模块解析

一、webpack打包图片 &#xff08;1&#xff09;加载图片案例准备 为了演示我们项目中可以加载图片&#xff0c;我们需要在项目中使用图片&#xff0c;比较常见的使用图片的方式是两种&#xff1a; img元素&#xff0c;设置src属性&#xff1b;其他元素&#xff08;比如div&…

如何做一个合格的微软技术工程师

我是荔园微风&#xff0c;作为一名在IT界整整25年的老兵&#xff0c;今天我们来重新审视一下如何做一个合格的微软技术工程师。 我认为要做一个合格的微软技术工程师&#xff0c;首先是要有兴趣从事这个职业。现在很多人是因为软件行业的薪资高才进入的&#xff0c;但我的看法…

并查集快速合并

对于一组数据&#xff0c;并查集主要支持两个动作&#xff1a; union(p,q) - 将 p 和 q 两个元素连接起来。 find(p) - 查询 p 元素在哪个集合中。 isConnected(p,q) - 查看 p 和 q 两个元素是否相连接在一起。 在上一小节中&#xff0c;我们用 id 数组的形式表示并查集&am…