Leetcode---352周赛

周赛题目

2760. 最长奇偶子数组

2761. 和等于目标值的质数对

2762. 不间断子数组

2763. 所有子数组中不平衡数字之和

一、最长奇偶子数组

 这题的数据范围允许用暴力来做,只要我们分别枚举左端点left和右端点right,然后看区间[left,right]是否符合题目条件,然后找到最大值了返回就行,这里就不多做解释了,下面讲解一种更快的算法---滑动窗口

思路:我们先找到符合条件的左端点,再不断向右扩展右端点,并不断更新最长子数组的长度,直到遇到不符合条件的数出现,我们再移动左端点,使得区间再次符合条件,然后继续移动右端点,如此循环,最后返回得到的最长子数组的长度

代码如下

int longestAlternatingSubarray(int* nums, int numsSize, int threshold){
    int right=0;
    int ans=0;
    while(right<numsSize){
        //找到符合条件的左端点
        if(nums[right]>threshold||nums[right]%2){
            right++;
            continue;
        }
        int left=right;
        right++;
        while(right<numsSize&&nums[right]<=threshold&&(nums[right-1]%2)!=(nums[right]%2)){ 
            right++;
        }
        ans=fmax(ans,right-left);
    }
    return ans;
}

二、和等于目标值的质数对

 这题其实也不难,主要是质数的判断比较费时间,如果我们一个个去比较,那么时间很可能会超时,这里需要用埃氏筛或者线性筛,来提前预处理出那些素数

这里简单说明一下埃氏筛的思路:默认所有的数都是素数(即标记为true),从2开始枚举,将2放入素数集合中,再将范围内所有2的倍数标记为false,然后下一个枚举的数是如果是true,就加入素数集合,并将其在范围内的所有倍数标记为false,如果是false,就将其在范围内的所有倍数标记为false,如此循环,就得到了范围内所有的素数

代码如下

int** findPrimePairs(int n, int* returnSize, int** returnColumnSizes){
    bool prime[n+1];
    for(int i=0;i<=n;i++)
        prime[i]=true;
    for(int i=2;i<n;i++){
        for(int j=i;j<n/i+1;j++){//这里的写法可以防止越界
            prime[j*i]=false;
        }
    }
    int**ans=(int**)malloc(sizeof(int*)*100000);
    *returnSize=0;
    for(int i=2;i<n;i++){
        if(!prime[i])continue;
        if(n-i<i)break;
        if(prime[n-i]){
            int*tmp=(int*)malloc(sizeof(int)*2);
            tmp[0]=i,tmp[1]=n-i;
            ans[(*returnSize)++]=tmp;
        }
    }
    *returnColumnSizes=(int*)malloc(sizeof(int)*(*returnSize));
    for(int i=0;i<*returnSize;i++){
        (*returnColumnSizes)[i]=2;
    }
    return ans;
}

进阶:由于埃氏筛会导致有些数字被重复赋值为false,浪费了时间(如12=2*6=3*4),这里补充讲一下线性筛,也就是防止重复赋值的情况,我们该怎么办?我们只要将枚举到的数字和已经得到的质数相乘,且如果该质数是所枚举数字的因子,直接跳出循环即可,这个算法的证明有兴趣的同学可以自行去百度,这里就不做详细证明了,写一下代码

int** findPrimePairs(int n, int* returnSize, int** returnColumnSizes){
    bool is_prime[n+1];
    int primes[n];
    int k=0;
    for(int i=0;i<=n;i++)
        is_prime[i]=true;
    for(int i=2;i<n;i++){
        if(is_prime[i])
            primes[k++]=i;
        for(int j=0;j<k&&primes[j]*i<n;j++){
            is_prime[primes[j]*i]=false;
            if(i%primes[j]==0)
                break;
        }
    }
    int**ans=(int**)malloc(sizeof(int*)*100000);
    *returnSize=0;
    for(int i=2;i<n;i++){
        if(!is_prime[i])continue;
        if(n-i<i)break;
        if(is_prime[n-i]){
            int*tmp=(int*)malloc(sizeof(int)*2);
            tmp[0]=i,tmp[1]=n-i;
            ans[(*returnSize)++]=tmp;
        }
    }
    *returnColumnSizes=(int*)malloc(sizeof(int)*(*returnSize));
    for(int i=0;i<*returnSize;i++){
        (*returnColumnSizes)[i]=2;
    }
    return ans;
}

三、不间断子数组

我们先用个例子来找找思路

接下来,我们只需要维护一段区间上的最大值和最小值来保证区间合法就行,那么这题很显然要用到特殊的队列(优先队列)来维护变化区间上的最大值和最小值代码如下

long long continuousSubarrays(int* nums, int numsSize){
    long long ans=0;
    int n=numsSize;
    int q_Max[n],q_Min[n];
    int h1=0,t1=0,h2=0,t2=0;
    for(int left=0,right=0;right<numsSize;right++){
        while(h1<t1&&nums[q_Max[t1-1]]<nums[right]){
            t1--;
        }
        while(h2<t2&&nums[q_Min[t2-1]]>nums[right]){
            t2--;
        }
        q_Max[t1++]=right;
        q_Min[t2++]=right;
        while(h1<t1&&h2<t2&&nums[q_Max[h1]]-nums[q_Min[h2]]>2){
            if(q_Max[h1]<q_Min[h2]){
                h1++;
            }else{
                h2++;
            }
            //这里不用担心h1或者h2越界的问题,因为它们就算h1或者h2到达n-1,那么++的必然是另一个
            //而一旦h1=h2=n-1,就不符合最大值和最小值相差大于2的条件,不用进入循环
            left=fmin(q_Max[h1],q_Min[h2]);
        }
        ans+=right-left+1;
    }
    return ans;
}

四、2763. 所有子数组中不平衡数字之和

 

 这题的数据范围允许我们使用暴力做法,即直接枚举左右端点,依次计算每个区间的不平衡数字之和,将它们相加后返回,这里的问题就在于我们如何计算区间内的不平衡数字之和,很多人就会想到题目中要求排序,那我们也排序,但是一旦排序就会改变数组中数字的顺序,所以我们就需要额外空间来存放需要排序的数字,既增加空间复杂度,又增加了时间复杂度,这里其实不用这么复杂,我们继续来举个例子帮助大家打开思路

代码如下

int sumImbalanceNumbers(int* nums, int numsSize){
    int n=numsSize,ans=0;
    for(int i=0;i<n;i++){
        bool visited[n+2];
        memset(visited,false,sizeof(visited));
        visited[nums[i]]=true;
        int cnt=0;
        for(int j=i+1;j<n;j++){
            int x=nums[j];
            if(!visited[x]){
                cnt+=1-visited[x-1]-visited[x+1];
                visited[x]=1;
            }
            ans+=cnt;
        }
        
    }
    return ans;
}

//介绍另一种写法
int sumImbalanceNumbers(int* nums, int numsSize){
    int visited[numsSize+2];
    memset(visited,-1,sizeof(visited));
    int ans=0;
    for(int i=0;i<numsSize-1;i++){
        int cnt=0;
        visited[nums[i]]=i;
        for(int j=i+1;j<numsSize;j++){
            int x=nums[j];
            if(visited[x]!=i){
                cnt+=1-(visited[x-1]==i)-(visited[x+1]==i);
                visited[x]=i;
            }
            ans+=cnt;
        }
    }
    return ans;
}

那么有没有O(n)的方法呢?

其实这题还可以用贡献法来求解,即我们来单独讨论每个元素对不平衡数字之和的贡献。

算法的思想:假设我们要计算x这个数对数组不平衡数字的贡献,那么我们向左边寻找离x最近的x-1或x,在向右边寻找离x最近的x-1(之所以不找x+1,是因为当我们计算x+1这个数的贡献时,就会向左找x,所以没必要找,而右边不找x的理由同上)这样我们就能知道x存在的子数组的个数(用乘法原理),由此来推断x对不平衡数字的贡献,但是这有一个问题:当x是所在子数组的最小值时,它的贡献就是0,我们需要减去这部分多算的贡献,而每一个元素x充当最小值的子数组的数量就是原数组的子数组的数量,也就是n(n+1)/2---注意子数组要求连续

代码如下

int sumImbalanceNumbers(int* nums, int numsSize){
    int n=numsSize,ans=0;
    int left[n];
    int idx[n+1];
    memset(idx,-1,sizeof(idx));
    for(int i=0;i<n;i++){
        int x=nums[i];
        left[i]=fmax(idx[x-1],idx[x]);
        idx[x]=i;
    }
    for(int i=0;i<n+1;i++){
        idx[i]=n;
    }
    for(int i=n-1;i>=0;i--){
        int right=idx[nums[i]-1];
        ans+=(i-left[i])*(right-i);
        idx[nums[i]]=i;
    }
    return ans-n*(n+1)/2;
}

最后不要忘记点赞,评论加收藏哦!!!

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

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

相关文章

vue3 报错解决:找不到模块‘xxx.vue’或其相应的类型声明。(Vue 3 can not find module)

src下面建立一个xx.d.ts的文件 declare module *.vue {import { ComponentOptions } from vueconst componentOptions: ComponentOptionsexport default componentOptions }

数据结构错题集 第七章 查找

7.2 124 等比 1(1-2^h)/(1-2) 2^h - 1 查找失败的最小次数相等吗&#xff1f; 13.A D 推一下公式 &#xff08;M1&#xff09;/2 平均查找长度 17.有序 就可二分查找 记住向下取整就是往右 13题就是个例子 向上取整就是往左 7.3 A错 不会分裂 不是平衡树 12。 C 黑高…

Tomcat、Maven以及Servlet的基本使用

Tomcat什么是TomcatTomcat的目录结构启动Tomcat MavenMaven依赖管理流程配置镜像源 Servlet主要工作实现Servlet添加依赖实现打包分析 配置插件 Tomcat 什么是Tomcat Tomcat 是一个 HTTP 服务器。前面我们已经学习了 HTTP 协议, 知道了 HTTP 协议就是 HTTP 客户端和 HTTP 服务…

Android性能优化(bin启动优化)

我们平时会在android里面写个bin程序来干点活&#xff0c;但是有时候我们会发现很奇怪的现象&#xff0c;我明明很早就启动这个bin了&#xff0c;但是过了很久bin程序的main函数才被调用~。这个是为啥呢&#xff1f;主要有2个原因&#xff1a; 一.bin程序依赖的so库太多&#…

Python:使用prometheus-client提交数据到实现prometheus+ grafana数据监控

相关资料 prometheus文档&#xff1a;https://prometheus.io/grafana文档&#xff1a;https://grafana.com/grafana github: https://github.com/grafana/grafanaPyhton客户端https://pypi.org/project/prometheus-client/ 目录 1、使用Python提供数据源2、启动 prometheus3、…

zabbix 监控 windows 系统、java应用、SNMP

Zabbix 监控 Windows 系统 1、下载 Windows 客户端 Zabbix agent 2 2、安装客户端&#xff0c;配置 3.在服务端 Web 页面添加主机&#xff0c;关联模板 Zabbix 监控 java 应用 1、客户端开启 java jmxremote 远程监控功能 1.1配置 java jmxremote 远程监控功能 1.2启动…

左神算法之中级提升(2)

目录 [案例1】 【题目描述】 【思路解析1】 【思路解析2】 【代码实现】 【案例2】 【题目描述】 【思路解析】 【代码实现】 【案例3】 【题目描述】 【思路解析】 【代码实现】 【案例4】 【题目描述】今日头条2018面试题 第四题 【输入描述】 【思路解析】 【…

pytorch学习第一篇:conda配置jupyter notebooks pytorch

安装jupyter notebooks 创建一个pytorch的环境 conda create -n pytorch python3.10 conda activate pytorch安装jupyter notebook&#xff0c;运行命令 conda install jupyter notebook启动jupyter 运行命令 jupyter notebook或者 notebook查看pyhton版本 import sys p…

C++ 环境设置

不好意思&#xff0c;最近有点事&#xff0c;没更新。 C 环境设置 本地环境设置 如果您想要设置 C 语言环境&#xff0c;您需要确保电脑上有以下两款可用的软件&#xff0c;文本编辑器和 C 编译器。 文本编辑器 这将用于输入您的程序。文本编辑器包括 Windows Notepad、O…

QT - 20230710

练习&#xff1a;实现一个简易闹钟 widget.h #ifndef WIDGET_H #define WIDGET_H#include <QWidget> #include <QDateTime> #include <QDebug> #include <QTextToSpeech>namespace Ui { class Widget; }class Widget : public QWidget {Q_OBJECTpubl…

【数据挖掘】时间序列教程【十】

5.4 通用卡尔曼滤波 上一节中描述的状态空间模型作为观测方程的更一般的公式 和状态方程 这里是一个p1 向量

win系统电脑在线打开sketch文件的方法

自Sketch诞生以来&#xff0c;只有Mac版本。Windows计算机如何在线打开Sketch文件&#xff1f; 即时设计已经解决了你遇到的大部分问题&#xff0c;不占用内存也是免费的。 您可以使用此软件直接在线打开Sketch文件&#xff0c;完整预览并导出CSS、SVG、PNG等&#xff0c;还具…

pycharm的一些常用设置

pycharm的一些常用设置 1、最新安装pycharm ,怎么设置解释器如图&#xff1a; 2、可通过鼠标放大缩小配置&#xff1a; 进入setting>Editor>File and Code Templates&#xff0c;点击python script&#xff0c;进行设置&#xff1a; """Author : A Tim…

探索图像处理的利器——OpenCV

目录 引言&#xff1a; 一、OpenCV简介&#xff1a; 二、OpenCV的特点&#xff1a; 三、OpenCV的应用领域&#xff1a; 四、实际案例&#xff1a; 结论&#xff1a; 引言&#xff1a; 在当今信息化的时代&#xff0c;图像处理已经成为了日常生活中不可或缺的一部分。从社…

【开源与项目实战:开源实战】84 | 开源实战四(上):剖析Spring框架中蕴含的经典设计思想或原则

在 Java 世界里&#xff0c;Spring 框架已经几乎成为项目开发的必备框架。作为如此优秀和受欢迎的开源项目&#xff0c;它是我们源码阅读的首选材料之一&#xff0c;不管是设计思想&#xff0c;还是代码实现&#xff0c;都有很多值得我们学习的地方。接下来&#xff0c;我们就详…

Matlab使用S函数

什么是S函数&#xff1f; S-函数是系统函数&#xff08;System Function&#xff09;的简称&#xff0c;在 Simulink 中用非图形化的方式来描述一个模块。一个完整的S-函数结构体系包含了描述一个动态系统所需要的全部能力。使用S-函数用户可以向 Simulink 模型中添加自己的模块…

rust 自动化测试、迭代器与闭包、智能指针、无畏并发

编写测试可以让我们的代码在后续迭代过程中不出现功能性缺陷问题&#xff1b;理解迭代器、闭包的函数式编程特性&#xff1b;Box<T>智能指针在堆上存储数据&#xff0c;Rc<T>智能指针开启多所有权模式等&#xff1b;理解并发&#xff0c;如何安全的使用线程&#x…

Mac矢量绘图工具 Sketch

Sketch是一款适用于 UI/UX 设计、网页设计、图标制作等领域的矢量绘图软件&#xff0c; 其主要特点如下&#xff1a; 1. 简单易用的界面设计&#xff1a;Sketch 的用户界面简洁明了&#xff0c;使得用户可以轻松上手操作&#xff0c;不需要复杂的学习过程。 2. 强大的矢量绘图功…

静态路由介绍

目录 静态路由配置方法&#xff08;基本配置&#xff09;&#xff1a; 静态路由的拓展配置 负载均衡 1.环回接口——测试 2.手工汇总——子网汇总 3.路由黑洞&#xff08;黑洞路由) 4.缺省路由 5.空接口——NULL 0 6.浮动静态路由 静态路由配置方法&#xff08;基本配置&#x…

基于matlab使用部分或较低分辨率图像快速处理阻塞图像(附源码)

一、前言 此示例展示了如何使用两种策略快速处理阻塞图像&#xff0c;这两种策略可以对高分辨率图像的较小代表性样本进行计算。 处理被阻止的图像可能非常耗时&#xff0c;这使得算法的迭代开发成本过高。有两种常见的方法可以缩短反馈周期&#xff1a;迭代较低分辨率的图像…