Leetcode - 周赛432

目录

  • 一、3417. 跳过交替单元格的之字形遍历
  • 二、3418. 机器人可以获得的最大金币数
  • 三、3419. 图的最大边权的最小值
  • 四、3420. 统计 K 次操作以内得到非递减子数组的数目

一、3417. 跳过交替单元格的之字形遍历

题目链接
在这里插入图片描述
本题是一道模拟题,第一行走0,2,4,…偶数下标的格子,第二行走1,3,5,…奇数下标的格子(要倒着遍历),可以发现规律:

  • 偶数行从前往后遍历偶数下标的格子
  • 奇数行从后往前遍历奇数下标的格子

代码如下:

class Solution {
    public List<Integer> zigzagTraversal(int[][] g) {
        List<Integer> ans = new ArrayList<>();
        boolean flg = false;
        int n = g.length, m = g[0].length;
        for(int i=0; i<g.length; i++){
            if(!flg){
                for(int j=0; j<m; j+=2){
                    ans.add(g[i][j]);
                }
            }else{
                for(int j=m-1-m%2; j>=0; j-=2){
                    ans.add(g[i][j]);
                }
            }
            flg = !flg;
        }
        return ans;
    }
}

二、3418. 机器人可以获得的最大金币数

题目链接
在这里插入图片描述
定义 f [ i ] [ j ] [ k ] f[i][j][k] f[i][j][k] : 从 ( 0 , 0 ) (0,0) (0,0) ( i , j ) (i,j) (i,j) 且感化最多 k k k 个强盗可获得的最大金币数量。
选或不选 x = c o i n s [ i ] [ j ] x = coins[i][j] x=coins[i][j]

  • 不选 x x x,它只能从 ( i − 1 , j ) (i-1,j) (i1,j) ( i , j − 1 ) (i,j-1) (i,j1) 转移过来,此时它的 k k k 也不会发生变化,即 f [ i ] [ j ] [ k ] = m a x ( f [ i − 1 ] [ j ] [ k ] , f [ i ] [ j − 1 ] [ k ] ) f[i][j][k]=max(f[i-1][j][k],f[i][j-1][k]) f[i][j][k]=max(f[i1][j][k],f[i][j1][k])
  • 选择 x x x,它只能从 ( i − 1 , j ) (i-1,j) (i1,j) ( i , j − 1 ) (i,j-1) (i,j1) 转移过来,此时它的 k k k 需要分情况讨论:
    • i f ( k > 0 if(k > 0 if(k>0 && x < 0 ) x<0) x<0),此时可以感化当前单元格的强盗,即当前不获得也不损失金币,即 f [ i ] [ j ] [ k ] = m a x ( f [ i ] [ j ] [ k ] , f [ i − 1 ] [ j ] [ k − 1 ] , f [ i ] [ j − 1 ] [ k − 1 ] ) f[i][j][k]=max(f[i][j][k],f[i-1][j][k-1],f[i][j-1][k-1]) f[i][j][k]=max(f[i][j][k],f[i1][j][k1],f[i][j1][k1])
    • 不使用感化能力次数 k k k,直接选 x x x,即 f [ i ] [ j ] [ k ] = m a x ( f [ i ] [ j ] [ k ] , f [ i − 1 ] [ j ] [ k − 1 ] + x , f [ i ] [ j − 1 ] [ k − 1 ] + x ) f[i][j][k]=max(f[i][j][k],f[i-1][j][k-1]+x,f[i][j-1][k-1]+x) f[i][j][k]=max(f[i][j][k],f[i1][j][k1]+x,f[i][j1][k1]+x)

PS:

  • 这里 f [ i ] [ j ] f[i][j] f[i][j]是从 f [ i − 1 ] [ j ] f[i-1][j] f[i1][j] f [ i ] [ j − 1 ] f[i][j-1] f[i][j1]转移过来的,还需要注意越界访问,并且需要预处理第一行和第一列的值,所以在开数组的时候可以多开一行一列,此时递推公式就变成了 f [ i + 1 ] [ j + 1 ] = m a x ( f [ i + 1 ] [ j ] , f [ i ] [ j + 1 ] ) f[i+1][j+1] = max(f[i+1][j],f[i][j+1]) f[i+1][j+1]=max(f[i+1][j],f[i][j+1])。就不需要使用 i f if if 判断是否越界了
  • 该题的答案可以为负值,所以需要在初始化的时候将所有位置置为 − i n f -inf inf,除了 f [ 0 ] [ 1 ] [ k ] f[0][1][k] f[0][1][k] f [ 1 ] [ 0 ] [ k ] f[1][0][k] f[1][0][k] ( k ∈ [ 0 , 2 ] ) (k\in [0,2]) (k[0,2]),因为 f [ 1 ] [ 1 ] [ k ] f[1][1][k] f[1][1][k] ( 0 , 0 ) (0,0) (0,0)需要从上述两个状态转移过来,如果置为 − i n f -inf inf,它在 ( 0 , 0 ) (0,0) (0,0)位置的值就变成了 − i n f -inf inf,这显然不符合题意。

代码如下:

class Solution {
    public int maximumAmount(int[][] coins) {
        int n = coins.length, m = coins[0].length;
        int[][][] f = new int[n+1][m+1][3];
        //不选
        //f[i][j][k] = max(f[i-1][j][k], f[i][j-1][k]);
        //选
        //f[i][j][k] = max(f[i-1][j][k], f[i][j-1][k]) + x
        //if(k > 0 && x < 0)
        //f[i][j][k] = max(f[i-1][j][k-1], f[i][j-1][k-1])
        for(int[][] x : f){
            for(int[] y : x){
                Arrays.fill(y, Integer.MIN_VALUE/2);
            }
        }
        Arrays.fill(f[0][1], 0);
        //此时f[1][1][k]一定会从f[0][1][k]处转移过来,
        //不会出现-inf这种情况,所以两个选一个赋值为0就行
     	//f[1][j>=1][k] 和 f[i>=1][1][k] 也是同理
        //Arrays.fill(f[1][0], 0);
        for(int i=0; i<n; i++){
            for(int j=0; j<m; j++){
                int x = coins[i][j];
                for(int k=0; k<3; k++){
                	//不选的情况和选的第一种情况合起来
                    f[i+1][j+1][k] = Math.max(f[i+1][j][k], f[i][j+1][k]) + x;
                    if(k > 0 && x < 0)
                        f[i+1][j+1][k] = Math.max(f[i+1][j+1][k], Math.max(f[i+1][j][k-1], f[i][j+1][k-1]));
                }
            }
        }
        return f[n][m][2];
    }
}

三、3419. 图的最大边权的最小值

题目链接
在这里插入图片描述
本题满足三个条件:

  • 所有节点都能到达节点 0,反过来说,从节点 0 可以到所有节点,所以可以反向建图,通过 d f s ( 0 ) dfs(0) dfs(0) 计算可以到达的节点个数。
  • 图中剩余边的最大边权值尽可能小,就是最大化最小值问题,可以使用二分来做。
  • 每个节点至多有 t h r e s h o l d threshold threshold 条出去的边(即出度 ⩽ t h r e s h o l d \leqslant threshold threshold),这是个干扰条件,由于我们建立的是反图,这里的出度实际上是入度,而在 d f s ( 0 ) dfs(0) dfs(0) 遍历的时候,已经保证了所有点的入度为 1,题目也保证了 t h r e s h o l d ⩾ 1 threshold\geqslant1 threshold1,所以只要能 d f s ( 0 ) dfs(0) dfs(0) 遍历到所有节点,这个条件就一定会满足!!!

代码如下:

class Solution {
    public int minMaxWeight(int n, int[][] edges, int t) {
        List<int[]>[] g = new ArrayList[n];
        int mx = 0;
        Arrays.setAll(g, e->new ArrayList<>());
        for(int[] e : edges){
            int x = e[0], y = e[1], w = e[2];
            mx = Math.max(w, mx);
            g[y].add(new int[]{x, w});
        }
        cnt = new int[n];
        int l = 1, r = mx;
        while(l <= r){
            m = (l + r) / 2;
            if(check(g)){
                r = m - 1;
            }else{
                l = m + 1;
            }
        }
        return r + 1 <= mx ? r + 1 : -1;
    }
    //由于每次二分的数字肯定不一样
    //所以可以使用cnt[x] == m 来判断该点是否已经遍历过
    int[] cnt;
    int m;//当前二分的数字
    boolean check(List<int[]>[] g){
        int cnt = dfs(0, g);
        return cnt == g.length;
    }
    int dfs(int x, List<int[]>[] g){
        cnt[x] = m;
        int res = 1;
        for(int[] t : g[x]){
            int y = t[0], w = t[1];
            if(w <= m && cnt[y] != m){
                res += dfs(y, g);
            }
        }
        return res;
    }
}

四、3420. 统计 K 次操作以内得到非递减子数组的数目

题目链接
在这里插入图片描述
本题求有多少满足条件的子数组( k k k + 1 +1 +1 操作内,使其变成非递减的子数组),可以使用滑动窗口,枚举右端点 r r r,维护左端点 l l l,设 c n t cnt cnt 为当前 [ l , r ] [l,r] [l,r] 的数组变成非递减所需的最少操作次数。如果 c n t > k cnt > k cnt>k,需要移动 l l l,直到 c n t ⩽ k cnt\leqslant k cntk,此时以 r r r 为右端点的满足条件的子数组有 r − l + 1 r - l + 1 rl+1

本题的难点在于如何维护 c n t cnt cnt:

  • 进窗口:将子数组变成非递减需要操作 t = m a x ( 0 , m a x ( n u m s [ l : r ] ) − n u m s [ r ] ) t = max(0,max(nums[l:r])-nums[r]) t=max(0,max(nums[l:r])nums[r]) c n t = c n t + t cnt = cnt + t cnt=cnt+t
    • 如何维护区间 [ l , r ] [l,r] [l,r]最大值,可以使用单调队列 que(维护一个单调递减的序列)来维护。
      • 如果 que.size() > 0 && \text{que.size() > 0 \&\&} que.size() > 0 && n u m s [ q u e . p e e k L a s t ( ) ] ⩽ n u m s [ r + 1 ] nums[que.peekLast()] \leqslant nums[r+1] nums[que.peekLast()]nums[r+1] 时,说明 n u m s [ q u e . p e e k L a s t ( ) ] nums[que.peekLast()] nums[que.peekLast()] 不可能是当前区间的最大值了,直接删除 q u e . p o l l L a s t ( ) que.pollLast() que.pollLast(),把 r + 1 r+1 r+1添加进队列 q u e que que 中。
      • 如果 q u e . p e e k F i r s t ( ) < l que.peekFirst() < l que.peekFirst()<l,说明该下标已经不在 [ l , r ] [l,r] [l,r]区间,直接删除 q u e . p o l l F i r s t ( ) que.pollFirst() que.pollFirst()
      • 区间 [ l , r ] [l,r] [l,r]的最大值为 n u m s [ q u e . p e e k F i r s t ( ) ] nums[que.peekFirst()] nums[que.peekFirst()]
  • 出窗口:
    在这里插入图片描述

代码如下:

class Solution {
    public long countNonDecreasingSubarrays(int[] nums, int k) {
        int n = nums.length;
        List<Integer>[] g = new ArrayList[n];
        Arrays.setAll(g, e->new ArrayList<>());
        Deque<Integer> st = new ArrayDeque<>();
        int[] pos = new int[n];//记录右边第一个大于nums[i]的下标
        Arrays.fill(pos, n);
        for(int i=0; i<n; i++){
            int v = nums[i];
            while(st.size() > 0 && nums[st.peek()] <= v){
                pos[st.pop()] = i;
            }
            if(st.size() > 0){
                g[st.peek()].add(i);//构建上述所说的树
            }
            st.push(i);
        }
        int cnt = 0;
        long ans = 0;
        Deque<Integer> que = new ArrayDeque<>();
        for(int l=0,r=0; r<n; r++){
            int v = nums[r];
            while(que.size() > 0 && nums[que.getLast()] <= v){
                que.removeLast();
            }
            que.addLast(r);
            cnt += Math.max(nums[que.getFirst()] - v, 0);
            while(cnt > k){
                int x = nums[l];
                for(int i : g[l]){
                    if(i > r) break;
                    cnt -= (x - nums[i]) * (Math.min(pos[i], r+1)-i);
                }
                l++;
                if(!que.isEmpty() && que.getFirst() < l)
                    que.removeFirst();
            }
            ans += r - l + 1;
        }
        return ans;
    }
}

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

ASP.NET Core - 配置系统之配置提供程序

ASP.NET Core - 配置系统之配置提供程序 3. 配置提供程序3.1 文件配置提供程序3.1.1 JSON配置提供程序3.1.2 XML配置提供程序3.1.3 INI配置提供程序 3.2 环境变量配置提供程序3.3 命令行配置提供程序3.4 内存配置提供程序3.5 配置加载顺序 3.6 默认配置来源 3. 配置提供程序 前…

探索与创作:2024年CSDN平台上的成长与突破

文章目录 我与CSDN的初次邂逅初学阶段的阅读CSDN&#xff1a;编程新手的避风港初学者的福音&#xff1a;细致入微的知识讲解考试复习神器&#xff1a;技术总结的“救命指南”曾经的自己&#xff1a;为何迟迟不迈出写博客的第一步兴趣萌芽&#xff1a;从“读”到“想写”的初体验…

CSS中样式继承+优先级

继承属性和非继承属性 一、定义及分类 1、继承属性是指在父元素上设置了这些属性后&#xff0c;子元素会自动继承这些属性的值&#xff0c;除非子元素显式地设置了不同的值。 常见的继承属性: 字体 font 系列文本text-align text-ident line-height letter-spacing颜色 col…

macOS 安装JDK17

文章目录 前言介绍新特性下载安装1.下载完成后打开downloads 双击进行安装2.配置环境变量3.测试快速切换JDK 小结 前言 近期找开源软件&#xff0c;发现很多都已经使用JDK17springboot3 了&#xff0c;之前的JDK8已经被替换下场&#xff0c;所以今天就在本机安装了JDK17&#…

ChatGPT大模型极简应用开发-CH1-初识 GPT-4 和 ChatGPT

文章目录 1.1 LLM 概述1.1.1 语言模型和NLP基础1.1.2 Transformer及在LLM中的作用1.1.3 解密 GPT 模型的标记化和预测步骤 1.2 GPT 模型简史&#xff1a;从 GPT-1 到 GPT-41.2.1 GPT11.2.2 GPT21.2.3 GPT-31.2.4 从 GPT-3 到 InstructGPT1.2.5 GPT-3.5、Codex 和 ChatGPT1.2.6 …

vector迭代器的使用以及迭代器失效

一、iterator的使用注意 begin与end 遵循左闭右开的原则&#xff0c;begin 指向vector的第一个元素&#xff0c;end 指向vector的最后一个元素的往下一个位置。 rbegin 与 rend rbegin指向最后一个元素的位置&#xff0c;rend指向第一个元素的往前一个位置。 二、vector的常…

【Linux】15.Linux进程概念(4)

文章目录 程序地址空间前景回顾C语言空间布局图&#xff1a;代码1代码2代码3代码4代码5代码6代码7 程序地址空间前景回顾 历史核心问题&#xff1a; pid_t id fork(); if(id 0) else if(id>0) 为什么一个id可以放两个值呢&#xff1f;之前没有仔细讲。 C语言空间布局图&am…

【无法下载github文件】虚拟机下ubuntu无法拉取github文件

修改hosts来进行解决。 步骤一&#xff1a;打开hosts文件 sudo vim /etc/hosts步骤二&#xff1a;查询 github.com的ip地址 https://sites.ipaddress.com/github.com/#ipinfo将github.com的ip地址添加到hosts文件末尾&#xff0c;如下所示。 140.82.114.3 github.com步骤三…

Android BitmapShader实现狙击瞄具十字交叉线准星,Kotlin

Android BitmapShader实现狙击瞄具十字交叉线准星&#xff0c;Kotlin <?xml version"1.0" encoding"utf-8"?> <RelativeLayout xmlns:android"http://schemas.android.com/apk/res/android"xmlns:tools"http://schemas.android.…

Android系统开发(十):标准协议和通讯的桥梁:探索蓝牙、NFC、WLAN 的工作原理

引言&#xff1a; 现代社会已经是信息互联的世界&#xff0c;各种设备之间的互联互通已经成为了生活的一部分。而在这个过程中&#xff0c;Android 设备与其他硬件之间的通信扮演着至关重要的角色。从蓝牙耳机到 WiFi 路由器&#xff0c;甚至与电话功能的互动&#xff0c;所有…

node中文名的js文件有问题

新版Node无法运行含有中文名的JS文件&#xff0c;具体表现在无报错无反应。如下图&#xff1a; 源码如下&#xff1a; 改成英文的JS文件&#xff0c;则正常&#xff0c;如下图&#xff1a;

BERT与CNN结合实现糖尿病相关医学问题多分类模型

完整源码项目包获取→点击文章末尾名片&#xff01; 使用HuggingFace开发的Transformers库&#xff0c;使用BERT模型实现中文文本分类&#xff08;二分类或多分类&#xff09; 首先直接利用transformer.models.bert.BertForSequenceClassification()实现文本分类 然后手动实现B…

openharmony应用开发快速入门

开发准备 本文档适用于OpenHarmony应用开发的初学者。通过构建一个简单的具有页面跳转/返回功能的应用&#xff08;如下图所示&#xff09;&#xff0c;快速了解工程目录的主要文件&#xff0c;熟悉OpenHarmony应用开发流程。 在开始之前&#xff0c;您需要了解有关OpenHarmon…

RabbitMQ---TTL与死信

&#xff08;一&#xff09;TTL 1.TTL概念 TTL又叫过期时间 RabbitMQ可以对队列和消息设置TTL&#xff0c;当消息到达过期时间还没有被消费时就会自动删除 注&#xff1a;这里我们说的对队列设置TTL,是对队列上的消息设置TTL并不是对队列本身&#xff0c;不是说队列过期时间…

51.WPF应用加图标指南 C#例子 WPF例子

完整步骤&#xff1a; 先使用文心一言生成一个图标如左边使用Windows图片编辑器编辑&#xff0c;去除背景使用正方形&#xff0c;放大图片使图标铺满图片使用格式工程转换为ico格式&#xff0c;分辨率为最大 在资源管理器中右键项目添加ico类型图片到项目里图片属性设置为始终…

多语言插件i18n Ally的使用

先展示一下效果 1.第一步首先在vscode下载插件 2.第二步在 setting.json 里面配置 要区分文件是js&#xff0c;ts或json结尾 以zh.ts和en.ts结尾的用这个 { "i18n-ally.localesPaths": ["src/locales"],"i18n-ally.keystyle": "nested"…

蓝桥杯备考:堆和priority queue(优先级队列)

堆的定义 heap堆是一种特殊的完全二叉树&#xff0c;对于树中的每个结点&#xff0c;如果该结点的权值大于等于孩子结点的权值&#xff0c;就称它为大根堆&#xff0c;小于等于就叫小根堆&#xff0c;如果是大根堆&#xff0c;每个子树也是符合大根堆的特征的&#xff0c;如果是…

【人工智能】:搭建本地AI服务——Ollama、LobeChat和Go语言的全方位实践指南

前言 随着自然语言处理&#xff08;NLP&#xff09;技术的快速发展&#xff0c;越来越多的企业和个人开发者寻求在本地环境中运行大型语言模型&#xff08;LLM&#xff09;&#xff0c;以确保数据隐私和提高响应速度。Ollama 作为一个强大的本地运行框架&#xff0c;支持多种先…

Java锁 从乐观锁和悲观锁开始讲 面试复盘

目录 面试复盘 Java 中的锁 大全 悲观锁 专业解释 自我理解 乐观锁 专业解释 自我理解 悲观锁的调用 乐观锁的调用 synchronized和 ReentrantLock的区别 相同点 区别 详细对比 总结 面试复盘 Java 中的锁 大全 悲观锁 专业解释 适合写操作多的场景 先加锁可以…

OpenVela——专为AIoT领域打造的开源操作系统

目录 一、系统背景与开源 1.1. 起源 1.2. 开源 二、系统特点 2.1. 轻量化 2.2. 标准兼容性 2.3. 安全性 2.4. 高度可扩展性 三、技术支持与功能 3.1. 架构支持 3.2. 异构计算支持 3.3. 全面的连接套件 3.4. 开发者工具 四、应用场景与优势 4.1. 应用场景 4.2. …