Leetcode - 147双周赛

embedded/2025/1/15 1:03:11/

目录

  • 一、3407. 子字符串匹配模式
  • 二、3408. 设计任务管理器
  • 三、3409. 最长相邻绝对差递减子序列
  • 四、3410. 删除所有值为某个元素后的最大子数组和

一、3407. 子字符串匹配模式

题目链接
在这里插入图片描述
字符串匹配问题,把字符串 p 分成两段 、,i 是 ’ * ’ 的下标,判断 s 是否包含这两段,且这两段处于不相交 && 有前后关系

代码如下:

class Solution {public boolean hasMatch(String s, String p) {int idx = p.indexOf('*');int i = s.indexOf(p.substring(0, idx));return i>=0 && s.substring(i+idx).contains(p.substring(idx+1));}
}

二、3408. 设计任务管理器

题目链接
在这里插入图片描述
使用哈希存当前每个 taskId,对应的 userId 和 priority,再使用堆存储 taskId 和 priority,按照 priority 排序,如果优先级相同,按照 taskId 排序。

  • TaskManager(),将数据存入哈希表和堆
  • add(),将数据存入哈希表和堆
  • edit(),更新哈希表,将更新后的数据存入堆
  • rmv(),更新哈希表 execTop(),不断的将数据排出堆,使用懒删除,如果当前数据存储在哈希表中,返回当前的 userId

代码如下:

class TaskManager {Map<Integer, int[]> map = new HashMap<>();PriorityQueue<int[]> que = new PriorityQueue<>((x,y)->x[1]==y[1]?y[0]-x[0]:y[1]-x[1]);public TaskManager(List<List<Integer>> tasks) {for(List<Integer> x : tasks){int userId = x.get(0), taskId = x.get(1), priority = x.get(2);map.put(taskId, new int[]{userId, priority});que.offer(new int[]{taskId, priority});}    }public void add(int userId, int taskId, int priority) {map.put(taskId, new int[]{userId, priority});que.offer(new int[]{taskId, priority});}public void edit(int taskId, int newP) {int[] t = map.get(taskId);t[1] = newP;map.put(taskId, t);que.offer(new int[]{taskId, t[1]});}public void rmv(int taskId) {map.remove(taskId);}public int execTop() {while(!que.isEmpty()){int[] t = que.poll();if(map.containsKey(t[0]) && map.get(t[0])[1] == t[1]){int user = map.get(t[0])[0];map.remove(t[0]);return user;}}return -1;}
}

三、3409. 最长相邻绝对差递减子序列

题目链接
在这里插入图片描述
定义 f [ i ] [ j ] f[i][j] f[i][j]: 以 x = n u m s [ i ] x = nums[i] x=nums[i] 为结尾的且与倒数第二个数的绝对值的差至少 j j j(即倒数第二个数为 x − j / x + j x-j/x+j xj/x+j)的子序列的最长长度。

对于 x = n u m s [ i ] x = nums[i] x=nums[i],题目要求两数差的绝对值是非递增的(即倒数第三个数和倒数第二个数的绝对差值 > = j >=j >=j ),分类讨论:

  • n u m s [ i ] nums[i] nums[i] 单独形成一个子序列 , f [ i ] [ j ] = 1 f[i][j] = 1 f[i][j]=1
  • 倒数第一个数和倒数第二个数的绝对差值 > j >j >j,也就是绝对差值 > = j + 1 >=j+1 >=j+1 f [ i ] [ j ] = f [ i ] [ j + 1 ] f[i][j] = f[i][j+1] f[i][j]=f[i][j+1]
  • 倒数第一个数和倒数第二个数的绝对差值 = j =j =j,也就是倒数第二个数的值为 x + j / x − j x+j/x-j x+j/xj f [ i ] [ j ] = m a x ( f [ l a s t [ x − j ] ] [ j ] , f [ l a s t [ x + j ] ] [ j ] ) f[i][j] = max(f[last[x-j]][j],f[last[x+j]][j]) f[i][j]=max(f[last[xj]][j]f[last[x+j]][j])
  • l a s t [ x ] last[x] last[x]:值为 x x x 的数在 n u m s nums nums 数组中的下标

最终 f [ i ] [ j ] = m a x ( 1 , f [ i ] [ j + 1 ] , f [ l a s t [ x + j ] ] [ j ] , f [ l a s t [ x − j ] ] [ j ] ) f[i][j] = max(1,f[i][j+1],f[last[x+j]][j],f[last[x-j]][j]) f[i][j]=max(1,f[i][j+1],f[last[x+j]][j],f[last[xj]][j])

代码如下:

class Solution {public int longestSubsequence(int[] nums) {int n = nums.length;int mx = nums[0], mn = nums[0];for(int x : nums){mx = Math.max(mx, x);mn = Math.min(mn, x);}int maxD = mx - mn;int ans = 0;int[][] f = new int[n][maxD+2];int[] last = new int[mx + 1];Arrays.fill(last, -1);for(int i=0; i<n; i++){int x = nums[i];for(int j=maxD; j>=0; j--){f[i][j] = Math.max(f[i][j+1], 1);if(x - j >= 0 && last[x - j] >= 0){f[i][j] = Math.max(f[i][j], f[last[x-j]][j] + 1);}if(x + j <= mx && last[x+j] >= 0){f[i][j] = Math.max(f[i][j], f[last[x+j]][j] + 1);}ans = Math.max(ans, f[i][j]);}last[x] = i;}return ans;}
}//定义f[x][j]:以值 x 结尾的且与倒数第二个数的绝对差值至少为 j 的子序列的最长长度
class Solution {public int longestSubsequence(int[] nums) {int n = nums.length;int mx = nums[0], mn = nums[0];for(int x : nums){mx = Math.max(mx, x);mn = Math.min(mn, x);}int maxD = mx - mn;int ans = 0;int[][] f = new int[mx+1][maxD+1];for(int x : nums){int fx = 1;for(int j=maxD; j>=0; j--){if(x-j >= 0){fx = Math.max(fx, f[x-j][j] + 1);}if(x+j <= mx){fx = Math.max(fx, f[x+j][j] + 1);}f[x][j] = fx;ans = Math.max(ans, fx);}}return ans;}
}

四、3410. 删除所有值为某个元素后的最大子数组和

题目链接
在这里插入图片描述
本题直接使用线段数来维护四个值——区间和,最大前缀和,最大后缀和,区间最大子数组和,代码如下:

class SegmentTree{private record Info(long sum, long pre, long suf, long ans){}Info[] tree;public SegmentTree(int[] nums){int n = nums.length;tree = new Info[n<<2];build(1, 0, n-1, nums);}void build(int i, int l, int r, int[] nums){if(l == r){int val = nums[l];tree[i] = new Info(val, val, val, val);return;}int m = (l + r) / 2;build(i<<1, l, m, nums);build(i<<1|1,m+1,r,nums);tree[i] = merge(tree[i<<1],tree[i<<1|1]);}Info merge(Info a, Info b){return new Info(a.sum + b.sum,Math.max(a.pre, a.sum+b.pre),Math.max(b.suf, a.suf+b.sum),Math.max(Math.max(a.ans, b.ans), a.suf+b.pre));}void update(int o, int l, int r, int i, int val){if(l == r){tree[o] = new Info(val, val, val, val);return;}int m = (l + r) / 2;if(i <= m){update(o<<1, l, m, i, val);}else{update(o<<1|1, m+1, r, i, val);}tree[o] = merge(tree[o<<1], tree[o<<1|1]);}long queryAll(){return tree[1].ans;}
}
class Solution {public long maxSubarraySum(int[] nums) {SegmentTree t = new SegmentTree(nums);long ans = t.queryAll();if(ans <= 0) return ans;int n = nums.length;Map<Integer, List<Integer>> map = new HashMap<>();for(int i=0; i<n; i++){if(nums[i] < 0)map.computeIfAbsent(nums[i], e->new ArrayList<>()).add(i);}for(List<Integer> x : map.values()){for(int i : x){t.update(1, 0, n-1, i, 0);}ans = Math.max(ans, t.queryAll());for(int i : x){t.update(1, 0, n-1, i, nums[i]);}}return ans;}
}

http://www.ppmy.cn/embedded/153980.html

相关文章

React 进阶之路:深入详解事件绑定的多样方式与区别,促使更加容易理解

React 中的事件绑定是处理用户交互的一个重要方面。React 的事件系统与传统的 DOM 事件系统有所不同&#xff0c;它在设计时考虑了性能、可维护性和易用性&#xff0c;因此 React 提供了多种方式来绑定事件处理程序。理解这些绑定方式及其区别&#xff0c;有助于在实际项目中做…

open3d+opencv实现矩形框裁剪点云操作(C++)

&#x1f451;主页&#xff1a;吾名招财 &#x1f453;简介&#xff1a;工科学硕&#xff0c;研究方向机器视觉&#xff0c;爱好较广泛… ​&#x1f4ab;签名&#xff1a;面朝大海&#xff0c;春暖花开&#xff01; open3dopencv实现矩形框裁剪点云操作&#xff08;C&#xff…

第三章、python中的对象、变量及地址的概念(3.1-3.4)------对象、变量、内存地址及可迭代对象

目录 3.1内存地址(或逻辑地址)、id()、is、in 3.2创建对象及对象的划分问题 3.3变量 3.3.1变量被赋值(=) 3.3.2变量无需声明数据类型 3.3.3变量的作用域(scope)及种类 3.4可迭代对象(Iterable) 第三章、python中的对象、变量及地址的概念 本章讲述编程中对象、变量、地址的基本…

JavaScript Chrome 中的运行

我们在 Chrome 浏览器中可以通过按下 F12 按钮或者右击页面&#xff0c;选择"检查"来开启开发者工具。 也可以在右上角菜单栏选择 "更多工具"》"开发者工具" 来开启&#xff1a; 1、Console 窗口调试 JavaScript 代码 清空 Console 窗口到内容可…

【HM-React】08. Layout模块

基本结构和样式reset 结构创建 实现步骤 打开 antd/Layout 布局组件文档&#xff0c;找到示例&#xff1a;顶部-侧边布局-通栏拷贝示例代码到我们的 Layout 页面中分析并调整页面布局 代码实现 pages/Layout/index.js import { Layout, Menu, Popconfirm } from antd impor…

第二章:HTML的常用标签

目录 一、标签 二、常用标签 1.排版标签 2.文本标签 3.图片标签img 4.列表 5.表格 6.表单 7.框架标签iframe 三、总结 一、标签 HTML是一种标记性语言&#xff0c;主要通过各种标签来呈现页面&#xff0c;不同标签有不同的语义和效果。注意&#xff1a;效果并不重要…

nginx负载均衡-基于多域名的负载均衡(二)

注意&#xff1a; (1) 做负载均衡技术至少需要三台服务器&#xff1a;一台独立的负载均衡器&#xff0c;两台web服务器做集群 (2) keeplived&#xff08;高可用&#xff09;nginx&#xff08;负载均衡&#xff09; 可以实现多域名对应一个VIP,并且访问不同域名&#xff0c;显示…

No.1|Godot|俄罗斯方块复刻|棋盘和初始方块的设置

删掉基础图标新建assets、scenes、scripts文件夹 俄罗斯方块的每种方块都是由四个小方块组成的&#xff0c;很适合放在网格地图中 比如网格地图是宽10列&#xff0c;高20行 要实现网格的对齐和下落 Node2D节点 新建一个Node2D 添加2个TileMapLayer 一个命名为Board&…