D354周赛复盘:特殊元素平方和+数组最大美丽值(滑动窗口)+合法分割最小下标

文章目录

    • 6889.特殊元素平方和
      • 思路
      • 完整版
        • 取模注意:不能对0取余/取模
        • 解答错误:本题的数组最后一个下标是nums[nums.size()]
    • 6929.数组的最大美丽值(排序+滑动窗口)
      • 思路1:排序+滑动窗口
        • 注意点
    • 6927. 合法分割的最小下标(倒推的思路)
      • 思路
      • 思路1:哈希表统计元素频率
      • 思路2:投票法找出出现频率最高的元素
        • 投票法介绍
      • 补充:投票法

6889.特殊元素平方和

  • 主要注意点是本题的i并不是数组下标的i,是按照数字顺序来的

给你一个下标从 1 开始、长度为 n 的整数数组 nums 。

对 nums 中的元素 nums[i] 而言,如果 n 能够被 i 整除,即 n % i == 0 ,则认为 num[i] 是一个 特殊元素 。

返回 nums 中所有 特殊元素 的 平方和 。

示例 1:

输入:nums = [1,2,3,4]
输出:21
解释:nums 中共有 3 个特殊元素:nums[1] ,因为 41 整除;nums[2] ,因为 42 整除;以及 nums[4] ,因为 44 整除。 
因此,nums 中所有元素的平方和等于 nums[1] * nums[1] + nums[2] * nums[2] + nums[4] * nums[4] = 1 * 1 + 2 * 2 + 4 * 4 = 21

示例 2:

输入:nums = [2,7,1,19,18,3]
输出:63
解释:nums 中共有 4 个特殊元素:nums[1] ,因为 61 整除;nums[2] ,因为 62 整除;nums[3] ,因为 63 整除;以及 nums[6] ,因为 66 整除。 
因此,nums 中所有元素的平方和等于 nums[1] * nums[1] + nums[2] * nums[2] + nums[3] * nums[3] + nums[6] * nums[6] = 2 * 2 + 7 * 7 + 1 * 1 + 3 * 3 = 63

提示:

  • 1 <= nums.length == n <= 50
  • 1 <= nums[i] <= 50

思路

本题属于比较简单的模拟题,遍历再模拟是否整除即可。

完整版

class Solution {
public:int sumOfSquares(vector<int>& nums) {int sum=0;int n=nums.size();//本题的判断对象是n//for循环遍历里面是本题的自定义数组下标for(int i=1;i<=nums.size();i++){if(n%i==0){//此处是真实的数组下标sum+=nums[i-1]*nums[i-1];}}return sum;}
};

取模注意:不能对0取余/取模

因为数组的下标从0开始,但是所有对0的取余/取模运算都是违法的

最开始写成了:

class Solution {
public:int sumOfSquares(vector<int>& nums) {int sum=0;int n=nums.size();//本题的判断对象是nfor(int i=0;i<nums.size();i++){if(n%i==0){sum+=nums[i]*nums[i];}}return sum;}
};

但是会出现执行错误,不能对0取模

在这里插入图片描述

解答错误:本题的数组最后一个下标是nums[nums.size()]

当我们直接改成初始值i=1,又会出现结果错误

在这里插入图片描述

原因是从示例中我们看出,nums[4]是最后一个元素,也就是说本题的下标并不是按照普通数组的形式,而是与数字顺序一致,题目里的数组下标特殊含义也要注意

在这里插入图片描述

因此,本题的for循环应该从i=1开始遍历,一直到i=nums.size()。内部求平方和的逻辑直接用nums[i-1]进行计算。

6929.数组的最大美丽值(排序+滑动窗口)

  • 本题主要是需要想到,经过排序,相等的元素会相邻在一起,也就是说相等的元素成为了连续序列,求序列最大长度就是滑动窗口类型题目了。
  • 本题关于元素顺序保持不变的要求可以忽略,一是因为求最大长度和元素顺序无关,二是因为所有解法都不能保证不改变元素顺序。(需要排序

给你一个下标从 0 开始的整数数组 nums 和一个 非负 整数 k

在一步操作中,你可以执行下述指令:

  • 在范围 [0, nums.length - 1] 中选择一个 此前没有选过 的下标 i
  • nums[i] 替换为范围 [nums[i] - k, nums[i] + k] 内的任一整数。

数组的 美丽值 定义为数组中由相等元素组成的最长子序列的长度。

对数组 nums 执行上述操作任意次后,返回数组可能取得的 最大 美丽值。

**注意:**你 能对每个下标执行 一次 此操作。

数组的 子序列 定义是:经由原数组删除一些元素(也可能不删除)得到的一个新数组,且在此过程中剩余元素的顺序不发生改变。

示例 1:

输入:nums = [4,6,1,2], k = 2
输出:3
解释:在这个示例中,我们执行下述操作:
- 选择下标 1 ,将其替换为 4(从范围 [4,8] 中选出),此时 nums = [4,4,1,2]- 选择下标 3 ,将其替换为 4(从范围 [0,4] 中选出),此时 nums = [4,4,1,4] 。
执行上述操作后,数组的美丽值是 3(子序列由下标 013 对应的元素组成)。
可以证明 3 是我们可以得到的由相等元素组成的最长子序列长度。

示例 2:

输入:nums = [1,1,1,1], k = 10
输出:4
解释:在这个示例中,我们无需执行任何操作。
数组 nums 的美丽值是 4(整个数组)。

提示:

  • 1 <= nums.length <= 105
  • 0 <= nums[i], k <= 105

思路1:排序+滑动窗口

因为美丽值的定义是数组中由相等元素组成的最长子序列的长度,因此我们想要获得全部都是相等元素的序列,并求最大长度

虽然本题要求 子序列 定义是剩余元素的顺序不发生改变,但是求的是相等元素组成的最长子序列长度,因此元素的顺序并不影响结果

(实际上本题所有解法都不考虑元素顺序,所以这个条件有点问题)

因此我们可以先进行排序,让相等的元素排在一起,此时只需要判断窗口左端点(最小值)和右端点(最大值)是不是相等,也就是只有nums[r]-k<=nums[l]+k的时候,才作为有效窗口

此时,本题就转变成了,求满足nums[r]-k<=nums[l]+k条件的最长子序列,也就是找最长的连续子数组,其最大值-最小值不超过2k。

也属于找最长子序列问题。最长子序列需要枚举右端点,只有不满足条件的时候,才更新左端点。

算法专题整理:滑动窗口_大磕学家ZYX的博客-CSDN博客

class Solution {
public:int maximumBeauty(vector<int>& nums, int k) {sort(nums.begin(), nums.end());int res=0;for (int l = 0, r = 0; r < nums.size(); ++r) {while (nums[r]-k > nums[l] + k) {l++;}res = max(res, r - l + 1);}return res;}
};

注意点

由于选的是子序列,且子序列的元素都相等,所以元素顺序对答案没有影响,可以先对数组排序

且仔细看用例1可以看出,并不要求最后的子数组在原数组也是连续的只是找替换后相等的数字组成的总长度,并不是找原数组中就连续的子数组

参考题解:
灵茶山艾府
力扣周赛总结

6927. 合法分割的最小下标(倒推的思路)

  • 本题重点是想明白,如果想要相等,最后那个结果肯定是原数组的支配元素
  • 因此可以根据支配元素的结果倒推,已知支配元素一定是这个数值,去求那两个子数组支配元素是不是这个。这种倒推的思路要注意。

如果元素 x 在长度为 m 的整数数组 arr 中满足 freq(x) * 2 > m ,那么我们称 x支配元素 。其中 freq(x)x 在数组 arr 中出现的次数。注意,根据这个定义,数组 arr 最多 只会有 一个 支配元素。

给你一个下标从 0 开始长度为 n 的整数数组 nums ,数据保证它含有一个支配元素。

你需要在下标 i 处将 nums 分割成两个数组 nums[0, ..., i]nums[i + 1, ..., n - 1] ,如果一个分割满足以下条件,我们称它是 合法 的:

  • 0 <= i < n - 1
  • nums[0, ..., i]nums[i + 1, ..., n - 1] 的支配元素相同。

这里, nums[i, ..., j] 表示 nums 的一个子数组,它开始于下标 i ,结束于下标 j ,两个端点都包含在子数组内。特别地,如果 j < i ,那么 nums[i, ..., j] 表示一个空数组。

请你返回一个 合法分割最小 下标。如果合法分割不存在,返回 -1

示例 1:

输入:nums = [1,2,2,2]
输出:2
解释:我们将数组在下标 2 处分割,得到 [1,2,2][2] 。
数组 [1,2,2] 中,元素 2 是支配元素,因为它在数组中出现了 2 次,且 2 * 2 > 3 。
数组 [2] 中,元素 2 是支配元素,因为它在数组中出现了 1 次,且 1 * 2 > 1 。
两个数组 [1,2,2][2] 都有与 nums 一样的支配元素,所以这是一个合法分割。
下标 2 是合法分割中的最小下标。

示例 2:

输入:nums = [2,1,3,1,1,1,7,1,2,1]
输出:4
解释:我们将数组在下标 4 处分割,得到 [2,1,3,1,1][1,7,1,2,1] 。
数组 [2,1,3,1,1] 中,元素 1 是支配元素,因为它在数组中出现了 3 次,且 3 * 2 > 5 。
数组 [1,7,1,2,1] 中,元素 1 是支配元素,因为它在数组中出现了 3 次,且 3 * 2 > 5 。
两个数组 [2,1,3,1,1][1,7,1,2,1] 都有与 nums 一样的支配元素,所以这是一个合法分割。
下标 4 是所有合法分割中的最小下标。

示例 3:

输入:nums = [3,3,3,3,7,2,2]
输出:-1
解释:没有合法分割。

提示:

  • 1 <= nums.length <= 105
  • 1 <=nums[i] <= 109
  • nums 有且只有一个支配元素。

思路

这道题的重要注意点在于,如果想要两个子数组的支配元素相等,那么这个支配元素,肯定也是原数组的支配元素

所以就可以倒过来推导,先求原数组支配元素,然后再看这个支配元素,是否在两个子数组里也是支配的

想明白这一点之后,剩下的就是模拟了,模拟的部分也可以练习一下。

思路1:哈希表统计元素频率

首先,要找到这个数组的支配元素。我们可以使用哈希表(unordered_map)来存储每个元素的频率。在这个过程中,我们同时找出频率最高的元素,即为我们的支配元素。

在找到支配元素后,再次遍历数组。这一次遍历要找出合法的分割点。一个合法的分割点需要满足以下条件:

  • [0, …, i] 的支配元素与整个数组的支配元素相同,即 nums[i] == dominator;
  • 在当前分割点之前(包括分割点),支配元素的出现次数超过了数组的一半,即 count > (i + 1) / 2;
  • 在当前分割点之后,剩余的支配元素出现次数仍超过后半部分数组的一半,即 (maxFreq - count) > (n - i - 1) / 2。
  • 如果当前分割点满足以上所有条件,我们就找到了一个合法的分割点。我们需要找的是最小的分割点,所以一旦找到,我们就直接返回这个分割点的索引 i。
class Solution {
public:int minimumIndex(vector<int>& nums) {//先建立哈希表统计原数组的支配元素unordered_map<int,int>umap;//遍历所有元素统计频率int maxFreq = 0;int x=0;for(int i=0;i<nums.size();i++){umap[nums[i]]++;//最大频率if(umap[nums[i]]>maxFreq){maxFreq = umap[nums[i]];x=nums[i];//同时存储频率最高数值}}//遍历i,对于i分割的两个子数组判断支配元素是不是xint count=0;for(int i=0;i<nums.size();i++){if(nums[i]==x){  //统计支配元素的频率count++;}//统计完了可以直接判断i之前元素的count是不是>长度/2,之后的频率是不是>长度/2//注意边界条件的长度,i+1已经算了i本身了,后面的nums.size()-i就不能算i了!if(count>(i+1)/2&&(maxFreq-count)>(nums.size()-i-1)/2){return i;}}return -1;}
};

思路2:投票法找出出现频率最高的元素

也可以用投票法,求出占比最高的元素及其频率。

投票法介绍

投票法是一种用于找出数组中多数元素的算法,这个算法的基本原理是:

如果一个元素是数组的多数元素(出现次数超过数组长度的一半),那么即使我们把它和其他每个不同的元素一一抵消(每次都从数组中删除两个不同的元素),最后剩下的一定是这个多数元素

由于题目保证了数组中最多只存在一个支配元素,投票法最后找到的元素必然是这个支配元素

class Solution {
public:int minimumIndex(vector<int>& nums) {int n = nums.size();int cnt = 0, x = 0;// 投票法求元素 xfor (int num: nums) {  // 遍历数组if (num == x) {  // 如果当前元素等于候选元素cnt++;  // 候选元素的票数加一} else {  // 如果当前元素不等于候选元素cnt--;  // 候选元素的票数减一,相当于抵消掉了if (cnt < 0) {  // 如果票数小于0x = num;  // 将当前元素作为新的候选元素cnt = 1;  // 将新的候选元素的票数设为1}}}// 求 x 出现的总数int sum = 0;for (int num: nums) {  // 再次遍历数组if (x == num) sum++;  // 如果当前元素等于支配元素,将支配元素的总数加一}// 枚举求解 icnt = 0;for (int i = 0; i < n; ++i) {  // 再次遍历数组,寻找分割点if (x == nums[i]) cnt++;  // 如果当前元素等于支配元素,将支配元素的出现次数加一if (cnt * 2 > (i + 1) && (sum - cnt) * 2 > (n - i - 1)) return i;  // 检查是否满足分割条件,如果满足,返回当前索引}return -1;  // 如果遍历完数组都没有找到合法的分割点,返回-1}
};

补充:投票法

  • 投票法是找**数组中出现频率超过半数(必须是超过不能是等于)**的元素。
  • 数组中出现频率超过半数的元素,一定只有一个

投票法(Boyer-Moore Voting Algorithm)是一种用于在数组中查找主要元素的算法,主要元素定义为一个元素出现次数超过数组长度的一半。它并不一定能找到频率最高的元素,例如在数组 [1, 2, 2, 3, 3, 3] 中,频率最高的元素是 3,但没有元素出现次数超过数组长度的一半,因此投票法不会返回任何元素。如果数组 [1, 1, 2, 2, 3, 3, 3, 3] 中,频率最高的元素也是主要元素,这时投票法会返回元素 3

示例:

class Solution {
public:int majorityElement(vector<int>& nums) {int count = 0;int candidate = 0;for(int num : nums){if (count == 0) {candidate = num;  // 当前候选主要元素}count += (num == candidate) ? 1 : -1;  // 如果当前元素等于候选主要元素,票数加1,否则减1}return candidate;  // 返回最后的候选主要元素}
};

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

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

相关文章

SpringBoot+actuator和admin-UI实现监控中心

使用SpringBoot很久了&#xff0c;但是很少使用到SpringBoot的查看和监控&#xff0c;将来八成也不会用到&#xff0c;万一有机会用到呢&#xff1f;所以记录一下以前学习SpringBootactuator和adminUI实现监控中心的方式 Springboot的版本2.0.x <parent><groupId>…

Spring学习记录---回顾反射机制

目录 10.回顾反射机制 10.1 分析方法四要素 //不使用反射机制调用这些方法 使用反射机制调用方法 代码&#xff1a; 运行结果&#xff1a; 10.4 假设你知道属性名 测试代码 运行结果 10.回顾反射机制 10.1 分析方法四要素 package com.dong.reflect;public class Som…

【java爬虫】将优惠券数据存入数据库排序查询

本文是在之前两篇文章的基础上进行写作的 (1条消息) 【java爬虫】使用selenium爬取优惠券_haohulala的博客-CSDN博客 (1条消息) 【java爬虫】使用selenium获取某宝联盟淘口令_haohulala的博客-CSDN博客 前两篇文章介绍了如何获取优惠券的基础信息&#xff0c;本文将获取到的…

PyTorch 1.13简介

# 1.  PyTorch 1.13 据官方介绍&#xff0c;PyTorch 1.13 中包括了 BetterTransformer 的稳定版&#xff0c;且不再支持 CUDA 10.2 及 11.3&#xff0c;并完成了向 CUDA 11.6 及 11.7 的迁移。此外 Beta 版还增加了对 Apple M1 芯片及 functorch 的支持。 1.1 主要更新 Be…

C++第四讲

思维导图 仿照string类&#xff0c;实现myString类 /* ---------------------------------author&#xff1a;YoungZorncreated on 2023/7/19 19:20.--------------------------------- */ #include<iostream> #include<cstring>using namespace std;class myStri…

【数据结构】时间复杂度---OJ练习题

目录 &#x1f334;时间复杂度练习 &#x1f4cc;面试题--->消失的数字 题目描述 题目链接&#xff1a;面试题 17.04. 消失的数字 &#x1f334;解题思路 &#x1f4cc;思路1&#xff1a; malloc函数用法 &#x1f4cc;思路2&#xff1a; &#x1f4cc;思路3&…

如何使用DiskPart命令行格式化分区?

想要格式化磁盘分区&#xff0c;您可以使用磁盘管理工具&#xff0c;或在Windows文件资源管理器中右键单击驱动器并选择“格式化”。如果您更想使用命令行来格式化磁盘&#xff0c;那么Windows自带的DiskPart将是首选。 DiskPart有很多优点&#xff0c;例如&#xff0c;如果您想…

活动页服务端渲染探索

目标 通过采用在服务端渲染激励页的方式&#xff0c;降低页面加载白屏时间&#xff0c;从而提升激励 H5 渲染体验。 架构设计 前端服务框架调研选型 只对比分析以下两种方案&#xff1a; Vue3 Nuxt3 WebpackNext.js React Node.js ’Nuxt3Next.js介绍Nuxt是一个基于Vu…

Clickhouse基础和基本优化

CK基础和基本优化 一、ClickHouse的特点列式存储高吞吐写入能力数据分区与线程级并行表引擎的使用MergeTreeReplacingMergeTreeSummingMergeTree 二、SQL操作1.Insert2.Update 和 Delete3.查询操作4.alter操作5.导出数据 三、基于表的分布式集群集群写入流程&#xff08; 3分片…

旅游卡加盟代理合伙人模式软件开发

旅游卡加盟代理合伙人模式是近年来逐渐兴起的一种旅游产业发展模式&#xff0c;它通过将旅游卡加盟商与代理商紧密结合&#xff0c;实现资源共享、风险共担、合作共赢的目标。而软件开发作为旅游卡加盟代理合伙人模式的重要技术支持&#xff0c;对于该模式的实施和发展起着至关…

深入理解Java虚拟机(二)Java内存区域与内存溢出异常

一、前言 对于Java程序员来说&#xff0c;在虚拟机自动内存管理机制的帮助下&#xff0c;不再需要为每一个new操作去写配对的delete/free代码&#xff0c;不容易出现内存泄漏和内存溢出问题&#xff0c;看起来由虚拟机管理内存一切都很美好。不过&#xff0c;也正是因为Java程序…

iOS APP外包开发的语言比较

iOS APP是Apple公司运行在iPhone手机上的APP&#xff0c;开发这样的APP有两种开发语言可以选择&#xff0c;都是由Apple公司提供的语言。其中Objective-C使用时间相对较长&#xff0c;有历史兼容考虑&#xff0c;而Swift是新的开发语言&#xff0c;更符合近些年开发语言的发展理…

05 Docker 安装常用软件 (mongoDB)

目录 1. mongoDB简介 1.1 mongodb的优势 2. mongodb的安装 2.1 创建数据文件夹 2.2 备份日志 2.3 配置文件夹 2.4 创建两个文件 ---> 2.4.1 配置如下: 2.5 拉取mongodb 2.6 运行容器 2.7 进入mongodb容器 ---> 2.7.0 高版本(6.0)以上是这样的 , 旧版的没研究 …

服务保护 Sentinel

服务保护 Sentinel Sentinel 介绍Sentinel 的下载使用Sentinel 流控规则流控规则介绍流控规则演示 Sentinel 热点规则Sentinel 隔离和熔断降级Feign 整合 Sentinel线程隔离熔断降级 Sentinel 授权规则Sentinel 系统规则Sentinel 自定义异常Sentinel 资源定义url 默认资源抛出异…

【力扣周赛】第 354 场周赛

文章目录 Q1&#xff1a;6889. 特殊元素平方和思路——简单模拟题竞赛时代码 Q2&#xff1a;6929. 数组的最大美丽值思路——差分数组&#xff0c;计算每个数字可能出现的次数竞赛时代码解法2——排序 双指针⭐解法3——排序 二分查找 Q3&#xff1a;6927. 合法分割的最小下标…

Linux 漏洞扫描

Linux 漏洞扫描程序会仔细检查基于 Linux 的系统&#xff0c;以减轻潜在的风险和漏洞。 什么是 Linux 漏洞扫描程序 Linux 漏洞扫描程序是一种专门的漏洞扫描工具&#xff0c;旨在识别基于 Linux 的系统中的安全漏洞和弱点,它会扫描配置错误、过时的软件版本和已知漏洞。 为…

pytorch学习--第一个模型(线性模型)

目标 我们想通过随机初始化的参数 ω , b \omega ,b ω,b能在迭代过程中使预测值和目标值能无限接近 y ω x b y\omega xb yωxb 定义数据 x torch.rand([60, 1])*10 y x*2 torch.randn(60,1)构建模型 利用pytorch中的nn.Module 想要构建模型时&#xff0c;继承这个类…

(四)「消息队列」之 RabbitMQ 路由(使用 .NET 客户端)

0、引言 先决条件 本教程假设 RabbitMQ 已安装并且正在 本地主机 的标准端口&#xff08;5672&#xff09;上运行。如果您使用了不同的主机、端口或凭证&#xff0c;则要求调整连接设置。 获取帮助 如果您在阅读本教程时遇到问题&#xff0c;可以通过邮件列表或者 RabbitMQ 社区…

Meta发布升级大模型LLaMA 2:开源可商用

论文地址&#xff1a;https://ai.meta.com/research/publications/llama-2-open-foundation-and-fine-tuned-chat-models/ Github地址&#xff1a;https://github.com/facebookresearch/llama LLaMA 2介绍 Meta之前发布自了半开源的大模型LLaMA&#xff0c;自从LLaMA发布以来…

C# WPF实现动画渐入暗黑明亮主题切换效果

C# WPF实现动画渐入暗黑明亮主题切换效果 效果图如下最近在Bilibili的桌面端看到一个黑白主题切换的效果感觉&#xff0c;挺有意思。于是我使用WPF尝试实现该效果。 主要的切换效果&#xff0c;基本实现不过还存在一些小瑕疵&#xff0c;比如字体等笔刷不能跟随动画进入进行切…