Leetcode - 127双周赛

目录

一,3095. 或值至少 K 的最短子数组 I

二,3096. 得到更多分数的最少关卡数目

三,3097. 或值至少为 K 的最短子数组 II

四,3098. 求出所有子序列的能量和


一,3095. 或值至少 K 的最短子数组 I

本题需要知道一个知识点,0|0 = 0,0|1 = 1,1|1 = 1,根据上述性质可以得出,每按位或一个数,这个数要么变大,要么不变,也就是说它有一个非递减的性质。在者,这道题的数据范围不大,可以直接暴力,代码如下: 

class Solution {public int minimumSubarrayLength(int[] nums, int k) {int n = nums.length;int ans = Integer.MAX_VALUE;for(int i=0; i<n; i++){int or = 0;for(int j=i; j<n; j++){or |= nums[j];if(or >= k){ans = Math.min(ans, j-i+1);break;}}}return ans==Integer.MAX_VALUE?-1:ans;}
}

二,3096. 得到更多分数的最少关卡数目

本题实际上就是求前缀和大于后缀和的所需要的最小数量,需要先统计整个数组的和sum,再遍历数组possible,用一个额外变量pre统计它的前缀和,那么sum - pre就是它的后缀和,如果 pre > sum - pre,返回结果,代码如下:

class Solution {public int minimumLevels(int[] possible) {int sum = 0;for(int x : possible) sum += x==0?-1:1;int n = possible.length;int pre = 0;for(int i=0; i<n; i++){if(i>0 && pre > sum - pre)return i;pre += possible[i]==0?-1:1;}return -1;}
}

三,3097. 或值至少为 K 的最短子数组 II

本题和第一题相同,但是数据范围更大,无法使用暴力,但是结论可以使用:一个数按位或的越多,那么就会变大或不变

方法一:滑动窗口

使用一个大小为32的数组来统计32个比特位各出现了几次

  • 每遍历到一个数,遍历它的32个bit位,如果cnt[i]==0 && (x>>i)&1==1时,说明当前数字按位或后,这个bit位会从0变成1,所以 k -= 1<<i
  • 当 k <= 0 时,说明当前按位与的数已经大于k了,就可以更新ans,同时可以缩减[l,r]的范围,看看当l变大时,是否满足k<=0,注意删除nums[l]时,遍历它的32个bit位,如果cnt[i]==1 && ((nums[l]>>i)&1)==1,说明删除这个数后,按位或的这个数会减小,所以 k += 1<<i
  • 注意当 k == 0 时,直接返回 1
class Solution {public int minimumSubarrayLength(int[] nums, int k) {int[] cnt = new int[32];//统计bit位出现了几次int n = nums.length;int ans = Integer.MAX_VALUE;if(k == 0) return 1;for(int l=0,r=0; r<n; r++){int x = nums[r];for(int i=0; i<32; i++){if(cnt[i]==0 && ((x>>i)&1)==1)//按位或之后,这个bit位会从0变成1k -= 1<<i;cnt[i] += (x>>i)&1;}while(k <= 0){ans = Math.min(ans, r-l+1);//跟新答案int y = nums[l];for(int i=0; i<32; i++){if(cnt[i]==1 && ((y>>i)&1)==1)//丢掉y之后,这个bit位是否会从1变成0k += 1<<i;cnt[i] -= (y>>i)&1;}l++;}}return ans==Integer.MAX_VALUE?-1:ans;}
}

方法二:通用模板

遍历数组nums,使用二维数组不停的更新以 i 为右端点的按位或值,及其最大左端点,同时计算符合条件的最短子数组

class Solution {public int minimumSubarrayLength(int[] nums, int k) {int ans = Integer.MAX_VALUE;int[][] or = new int[32][2];int m = 0;int n = nums.length;for(int i=0; i<n; i++){or[m][0] = 0;or[m++][1] = i;//更新操作int j = 0;for(int idx=0; idx < m; idx++){or[idx][0] |= nums[i];if(or[idx][0] >= k){ans = Math.min(ans, i-or[idx][1]+1);}if(or[idx][0] != or[j][0])//去重or[++j][0] = or[idx][0];or[j][1] = or[idx][1];}m = j+1;}return ans == Integer.MAX_VALUE ? -1 : ans;}
}

四,3098. 求出所有子序列的能量和

本题是一道单纯的dfs+记忆化题,有两种做法:

  • 枚举选哪个
  • 选或不选

枚举选哪个:

class Solution {static final int MOD = (int)1e9+7;int[] nums;int n;Map<Long, Long> map = new HashMap<>();public int sumOfPowers(int[] nums, int k) {this.nums = nums;Arrays.sort(nums);this.n = nums.length;long ans = dfs(0,k,Integer.MAX_VALUE, -1);return (int)ans%MOD;}long dfs(int idx, int k, int min, int j){if(k == 0){return min;}long res = 0;long key = ((long)min<<18|idx<<12|k<<6|(j+1));if(map.containsKey(key)) return map.get(key);for(int i=idx; i<=n-k; i++){res = (res + dfs(i+1, k-1, Math.min(min, (j==-1?Integer.MAX_VALUE:Math.abs(nums[i]-nums[j]))), i))%MOD;}map.put(key, res);return res;}
}

 选或不选:

class Solution {static final int MOD = (int)1e9+7;int[] nums;int n;Map<Long, Long> map = new HashMap<>();public int sumOfPowers(int[] nums, int k) {this.nums = nums;Arrays.sort(nums);this.n = nums.length;long ans = dfs(-1,k,Integer.MAX_VALUE, -1);return (int)ans%MOD;}//选或不选long dfs(int i, int k, int min, int j){if(k == 0)return min;if(k > n - i - 1)return 0;long res = 0;long key = ((long)min<<18|i<<12|k<<6|(j+1));if(map.containsKey(key)) return map.get(key);//选nums[i+1]res = dfs(i+1, k-1, Math.min(min, (j==-1?Integer.MAX_VALUE:Math.abs(nums[i+1]-nums[j]))), i+1);//不选nums[i+1]res += dfs(i+1, k, min, j);map.put(key, res%MOD);return res%MOD;}
}

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

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

相关文章

「每日跟读」英语常用句型公式 第3篇

「每日跟读」英语常用句型公式 第3篇 1. I don’t know how to ____ 我不知道如何_____ I don’t know how to play soccer (我不知道怎么踢足球) I don’t know how to study&#xff08;我不知道如何学习&#xff09; I don’t know how to play chess (我不知道如何下国…

mysql 安装与连接

关系型数据库 SQL: MySql Oracle 非关系型数据库 NoSql : redis MangoDB 关系型数据库有局限性&#xff0c;它的局限性由非关系型数据库弥补。 手机端常用的数据库是&#xff1a;SqlLite mysql下载 https://www.mysql.com/ 社区版本(免费) -> 推荐第二种方式 安装 …

Java_自定义实体类的列表List<T>调用remove()失败讲解

示例1 前提&#xff1a; 新建一个主类Demo1。 需求&#xff1a; 在一个列表中有三条String的数据&#xff0c;想要使用remove(Object o)删掉其中一条。 结果&#xff1a; remove(Object o)成功把数据删掉。 示例2 前提&#xff1a; 新建一个自定义实体类DataExample和一个主…

使用Vite创建一个vue3项目

一、vite是什么&#xff1f; vite 是一种新型前端构建工具&#xff0c;能够显著提升前端开发体验。它主要由两部分组成&#xff1a; 一个开发服务器&#xff0c;它基于原生 ES 模块提供了丰富的内建功能&#xff0c;如速度快到惊人的模块热更新&#xff08;HMR&#xff09;。 …

页面静态化:Freemarker入门案例和常用指令教程

页面静态化其实就是将原来的动态网页(例如通过ajax请求动态获取数据库中的数据并展示的网页)改为通过静态化技术生成的静态网页&#xff0c;这样用户在访问网页时&#xff0c;服务器直接给用户响应静态html页面&#xff0c;没有了动态查询数据库的过程。 那么这些静态HTML页面…

MySql 实战大数据查询-(表分区实现)

一 mysql分区&#xff1a; 分区是将单个表按照某种规则划分成多个子集&#xff0c;每个子集称为一个分区。常见的分区策略包括按照时间范围、范围值、列表等进行分区。 优点&#xff1a; 查询性能更好&#xff0c;涉及分区键的查询&#xff0c;数据库引擎可以只扫描特定分区&…

【Qt 学习笔记】使用两种方式实现helloworld

博客主页&#xff1a;Duck Bro 博客主页系列专栏&#xff1a;Qt 专栏关注博主&#xff0c;后期持续更新系列文章如果有错误感谢请大家批评指出&#xff0c;及时修改感谢大家点赞&#x1f44d;收藏⭐评论✍ 使用两种方式实现helloworld 文章编号&#xff1a;Qt 学习笔记 / 05 …

14.信号量

一、信号量的简介 信号量是一种解决同步问题的机制&#xff0c;可以实现对共享资源的有序访问。其中&#xff0c;“同步”指的 是任务间的同步&#xff0c;即信号量可以使得一个任务等待另一个任务完成某件事情后&#xff0c;才继续执行&#xff1b; 而“有序访问”指的是对被…

【资源分享】Eclipse最新版本免费安装下载

::: block-1 “时问桫椤”是一个致力于为本科生到研究生教育阶段提供帮助的不太正式的公众号。我们旨在在大家感到困惑、痛苦或面临困难时伸出援手。通过总结广大研究生的经验&#xff0c;帮助大家尽早适应研究生生活&#xff0c;尽快了解科研的本质。祝一切顺利&#xff01;—…

计算机网络——33多点访问协议

多点访问协议 多路访问链路和协议 两种类型的链路&#xff08;一个子网内部链路连接形式&#xff09; 点对点 拨号访问的PPP以太网交换机和主机之间的点对点链路 广播 传统以太网HFC上行链路802.11无线局域网 多路访问协议 单个共享的广播型链路 2个过更多结点同时传送&am…

CMOS漏极开路门

线与 通常CMOS门电路都有反相器作为输出缓冲电路。在实际工程中&#xff0c;为了方便常将两个门的输入端直接并联来实现与逻辑功能&#xff08;称为线与&#xff09;。如下图所示&#xff1a; 线与的弊端&#xff1a;当与电源VDD直接相连的PMOS管导通时&#xff0c;由于MOS管导…

Day31|贪心算法part01:理论基础、455.分发饼干、376. 摆动序列、53. 最大子序和

理论基础 记得贪心没有规律即可&#xff01;解不出来就看题解。 455. 分发饼干 先把学生和饼干都排序&#xff08;Arrays.sort只能升序&#xff09;&#xff0c;然后都从后往前遍历&#xff0c;把最大的饼干给需求最大的孩子&#xff08;贪心&#xff09; class Solution {…