【LeetCode每日一题合集】2023.11.27-2023.12.3 (⭐)

文章目录

  • 907. 子数组的最小值之和(单调栈+贡献法)
  • 1670. 设计前中后队列⭐(设计数据结构)
    • 解法1——双向链表
    • 解法2——两个双端队列
  • 2336. 无限集中的最小数字
    • 解法1——维护最小变量mn 和 哈希表维护已经去掉的数字
    • 解法2——维护原本可用的最小值 和 有序集合维护后期添加的数值👌
  • 1657. 确定两个字符串是否接近(理解操作本质)⭐
  • 2661. 找出叠涂元素(哈希表、计数统计)
  • 1094. 拼车(差分)
  • 1423. 可获得的最大点数(滑动窗口)

907. 子数组的最小值之和(单调栈+贡献法)

https://leetcode.cn/problems/sum-of-subarray-minimums/description/?envType=daily-question&envId=2023-11-27

在这里插入图片描述

提示:

1 <= arr.length <= 3 * 10^4
1 <= arr[i] <= 3 * 10^4

class Solution {
    private static final int MOD = (int)1e9 + 7;

    public int sumSubarrayMins(int[] arr) {
        long ans = 0;           // 使用long总归是有利于避免溢出
        int n = arr.length;
        // 计算每个数字作为最小值的贡献,即找到左右两侧第一个小于它的(一边严格小于,另一边小于等于)
        Deque<Integer> stk = new ArrayDeque();
        int[] right = new int[n], left = new int[n];
        Arrays.fill(left, -1);
        Arrays.fill(right, n);
        for (int i = 0; i < n; ++i) {
            while (!stk.isEmpty() && arr[i] <= arr[stk.peek()]) {
                right[stk.pop()] = i;
            }
            if (!stk.isEmpty()) left[i] = stk.peek();
            stk.push(i);
        }
        for (int i = 0; i < n; ++i) {
            ans = (ans + (long)arr[i] * (right[i] - i) * (i - left[i])) % MOD;
        }
        return (int)ans;
    }
}

1670. 设计前中后队列⭐(设计数据结构)

https://leetcode.cn/problems/design-front-middle-back-queue/description/?envType=daily-question&envId=2023-11-28

在这里插入图片描述

提示:

1 <= val <= 10^9
最多调用 1000 次 pushFront, pushMiddle, pushBack, popFront, popMiddle 和 popBack 。

解法1——双向链表

自己写的代码如下:

class FrontMiddleBackQueue {
    Node head = new Node(), tail = new Node();
    int sz = 0;

    public FrontMiddleBackQueue() {
        head.next = tail;
        tail.prev = head;
    }
    
    public void pushFront(int val) {
        Node node = new Node(val, head, head.next);
        head.next.prev = node;
        head.next = node;
        sz++;
    }
    
    public void pushMiddle(int val) {
        Node cur = head;
        for (int i = 0; i < sz / 2; ++i) {
            cur = cur.next;
        }
        Node node = new Node(val, cur, cur.next);
        cur.next.prev = node;
        cur.next = node;
        sz++;
    }
    
    public void pushBack(int val) {
        Node node = new Node(val, tail.prev, tail);
        tail.prev.next = node;
        tail.prev = node;
        sz++;
    }
    
    public int popFront() {
        if (sz == 0) return -1;
        int res = head.next.val;
        head.next.next.prev = head;
        head.next = head.next.next;
        --sz;
        return res;
    }
    
    public int popMiddle() {
        if (sz == 0) return -1;
        Node cur = head;
        for (int i = 0; i < (sz - 1) / 2; ++i) cur = cur.next;
        int res = cur.next.val;
        cur.next.next.prev = cur;
        cur.next = cur.next.next;
        --sz;
        return res;
    }
    
    public int popBack() {
        if (sz == 0) return -1;
        int res = tail.prev.val;
        tail.prev.prev.next = tail;
        tail.prev = tail.prev.prev;
        --sz;

        return res;
    }
}


class Node {
    int val = -1;
    Node prev = null, next = null;
    Node() {};
    Node(int _val, Node _prev, Node _next) {
        this.val = _val;
        this.prev = _prev;
        this.next = _next;
    }
}

/**
 * Your FrontMiddleBackQueue object will be instantiated and called as such:
 * FrontMiddleBackQueue obj = new FrontMiddleBackQueue();
 * obj.pushFront(val);
 * obj.pushMiddle(val);
 * obj.pushBack(val);
 * int param_4 = obj.popFront();
 * int param_5 = obj.popMiddle();
 * int param_6 = obj.popBack();
 */

一种优化方法是额外一个指针指向中间节点,参见:https://leetcode.cn/problems/design-front-middle-back-queue/solutions/502014/she-ji-qian-zhong-hou-dui-lie-by-zerotrac2/?envType=daily-question&envId=2023-11-28 的方法二。

解法2——两个双端队列

参考官方题解的思想 和 0x3f的代码写的。

class FrontMiddleBackQueue {
    // 左边的双端队列和右边的双端队列等长 或恰好大1。可以保证中间节点是左队列的结尾节点
    Deque<Integer> left = new ArrayDeque<>(), right = new ArrayDeque<>();

    public FrontMiddleBackQueue() {

    }
    
    public void pushFront(int val) {
        left.addFirst(val);
        balance();
    }
    
    public void pushMiddle(int val) {
        if (left.size() > right.size()) right.offerFirst(left.pollLast());
        left.offerLast(val);
    }
    
    public void pushBack(int val) {
        right.offerLast(val);
        balance();
    }
    
    public int popFront() {
        if (left.isEmpty()) return -1;
        int res = left.pollFirst();
        balance();
        return res;
    }
    
    public int popMiddle() {
        if (left.isEmpty()) return -1;
        int res = left.pollLast();
        balance();
        return res;
    }
    
    public int popBack() {
        if (left.isEmpty()) return -1;
        int res = right.isEmpty()? left.pollLast(): right.pollLast();
        balance();
        return res;
    }

    // 保持两个队列的相对大小
    public void balance() {
        if (left.size() > right.size() + 1) {
            right.offerFirst(left.pollLast());
        } else if (left.size() < right.size()) {
            left.offerLast(right.pollFirst());
        }
    }
}

/**
 * Your FrontMiddleBackQueue object will be instantiated and called as such:
 * FrontMiddleBackQueue obj = new FrontMiddleBackQueue();
 * obj.pushFront(val);
 * obj.pushMiddle(val);
 * obj.pushBack(val);
 * int param_4 = obj.popFront();
 * int param_5 = obj.popMiddle();
 * int param_6 = obj.popBack();
 */

2336. 无限集中的最小数字

https://leetcode.cn/problems/smallest-number-in-infinite-set/description/?envType=daily-question&envId=2023-11-29

在这里插入图片描述

解法1——维护最小变量mn 和 哈希表维护已经去掉的数字

维护最小变量mn,哈希表记录已经去除的数字。
当新添加数字时,如果更小,则更新 mn 变量。

class SmallestInfiniteSet {
    int mn = 1;
    Set<Integer> mv = new HashSet<>();

    public SmallestInfiniteSet() {

    }
    
    public int popSmallest() {
        int res = mn;
        mv.add(mn);
        while (mv.contains(mn)) mn++;
        return res;
    }
    
    public void addBack(int num) {
        if (mv.contains(num)) {
            mv.remove(num);
            if (num < mn) mn = num;
        }
    }
}

/**
 * Your SmallestInfiniteSet object will be instantiated and called as such:
 * SmallestInfiniteSet obj = new SmallestInfiniteSet();
 * int param_1 = obj.popSmallest();
 * obj.addBack(num);
 */

解法2——维护原本可用的最小值 和 有序集合维护后期添加的数值👌

去除时 是 去除最小的。
添加时 也只能添加 当前没有的,也是小的。

用一个变量维护上界,用一个有序集合维护新加的可用小数据。

class SmallestInfiniteSet {
    private int thres;
    private TreeSet<Integer> set;

    public SmallestInfiniteSet() {
        thres = 1;
        set = new TreeSet<Integer>();
    }

    public int popSmallest() {
        if (set.isEmpty()) {
            int ans = thres;
            ++thres;
            return ans;
        }
        int ans = set.pollFirst();
        return ans;
    }

    public void addBack(int num) {
        if (num < thres) {
            set.add(num);
        }
    }
}

1657. 确定两个字符串是否接近(理解操作本质)⭐

https://leetcode.cn/problems/determine-if-two-strings-are-close/description/?envType=daily-question&envId=2023-11-30

在这里插入图片描述

提示:
1 <= word1.length, word2.length <= 10^5
word1 和 word2 仅包含小写英文字母

https://leetcode.cn/problems/determine-if-two-strings-are-close/solutions/2547579/li-jie-cao-zuo-ben-zhi-jian-ji-xie-fa-py-b18i/?envType=daily-question&envId=2023-11-30
在这里插入图片描述
在这里插入图片描述

class Solution {
    public boolean closeStrings(String word1, String word2) {
        if (word1.length() != word2.length()) return false;
        int sMask = 0, tMask = 0;
        int[] sCnt = new int[26], tCnt = new int[26];
        for (char ch: word1.toCharArray()) {
            sMask |= 1 << (ch - 'a');
            sCnt[ch - 'a']++;
        }
        for (char ch: word2.toCharArray()) {
            tMask |= 1 << (ch - 'a');
            tCnt[ch - 'a']++;
        }
        Arrays.sort(sCnt);
        Arrays.sort(tCnt);
        return sMask == tMask && Arrays.equals(sCnt, tCnt);
    }
}

2661. 找出叠涂元素(哈希表、计数统计)

https://leetcode.cn/problems/first-completely-painted-row-or-column/description/?envType=daily-question&envId=2023-12-01

在这里插入图片描述
提示:

m == mat.length
n = mat[i].length
arr.length == m * n
1 <= m, n <= 10^5
1 <= m * n <= 10^5
1 <= arr[i], mat[r][c] <= m * n
arr 中的所有整数 互不相同
mat 中的所有整数 互不相同

class Solution {
    public int firstCompleteIndex(int[] arr, int[][] mat) {
        int m = mat.length, n = mat[0].length;
        // 记录位置信息
        int[] c = new int[m * n + 1], r = new int[m * n + 1];
        for (int i = 0; i < m; ++i) {
            for (int j = 0; j < n; ++j) {
                r[mat[i][j]] = i;
                c[mat[i][j]] = j;
            }
        }
        // 计数统计
        int[] cc = new int[n], rc = new int[m];
        for (int i = 0; i < m * n; ++i) {
            int v = arr[i], row = r[v], col = c[v];
            cc[col]++;
            rc[row]++;
            if (cc[col] == m || rc[row] == n) return i;
        }
        return -1;
    }
}

1094. 拼车(差分)

https://leetcode.cn/problems/car-pooling/description/?envType=daily-question&envId=2023-12-02

在这里插入图片描述

提示:

1 <= trips.length <= 1000
trips[i].length == 3
1 <= numPassengersi <= 100
0 <= fromi < toi <= 1000
1 <= capacity <= 10^5

用差分 表示 from 到 to 的范围内增加了多少人,然后再还原。

class Solution {
    public boolean carPooling(int[][] trips, int capacity) {
        int[] diff = new int[1001];
        for (int[] t: trips) {
            diff[t[1]] += t[0];
            diff[t[2]] -= t[0];
        }
        int s = 0;
        for (int i = 0; i < 1001; ++i) {
            s += diff[i];
            if (s > capacity) return false;
        }
        return true;
    }
}

1423. 可获得的最大点数(滑动窗口)

https://leetcode.cn/problems/maximum-points-you-can-obtain-from-cards/description/?envType=daily-question&envId=2023-12-03

在这里插入图片描述
提示:
1 <= cardPoints.length <= 10^5
1 <= cardPoints[i] <= 10^4
1 <= k <= cardPoints.length

就是找到长度为 n - k ,和最小的窗口,答案是 sum - mn。

class Solution {
    public int maxScore(int[] cardPoints, int k) {
        int n = cardPoints.length, sum = 0, s = 0, mn = Integer.MAX_VALUE / 2;
        if (k == n) return Arrays.stream(cardPoints).sum();
        k = n - k;
        for (int l = 0, r = 0; r < n; ++r) {
            s += cardPoints[r];
            sum += cardPoints[r];
            if (r - l + 1 == k) {
                mn = Math.min(mn, s);
                s -= cardPoints[l++];
            }
            
        }
        return sum - mn;
    }
}

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

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

相关文章

【UE5】监控摄像头效果(上)

目录 效果 步骤 一、视角切换 二、摄像头画面后期处理 三、在场景中显示摄像头画面 效果 步骤 一、视角切换 1. 新建一个Basic关卡&#xff0c;添加第三人称游戏资源到项目浏览器 2. 新建一个Actor蓝图&#xff0c;这里命名为“BP_SecurityCamera” 打开“BP_Securit…

90. 子集 II

90. 子集 II 原题链接&#xff1a;完成情况&#xff1a;解题思路&#xff1a;参考代码&#xff1a;错误经验吸取 原题链接&#xff1a; 90. 子集 II https://leetcode.cn/problems/subsets-ii/description/ 完成情况&#xff1a; 解题思路&#xff1a; /** * 包含重复元素…

图的邻接链表储存

喷了一节课 。。。。。。。、。 #include<stdio.h> #include<stdlib.h> #define MAXNUM 20 //每一个顶点的节点结构&#xff08;单链表&#xff09; typedef struct ANode{ int adjvex;//顶点指向的位置 struct ArcNode *next;//指向下一个顶点 …

.Net6.0 Microsoft.AspNetCore.Http.Abstractions 2.20 已弃用

您想要升级 Microsoft.AspNetCore.Http.Abstractions 包&#xff0c;您需要注意以下几点&#xff1a; Microsoft.AspNetCore.Http.Abstractions 包在 ASP.NET Core 2.2 版本后已经被标记为过时&#xff0c;因为它已经被包含在 Microsoft.AspNetCore.App 框架引用中12。因此&am…

树莓派 5 - Raspberry Pi 5 入门教程

系列文章目录 文章目录 ​​​​​​​ 前言 如果您是第一次使用 Raspberry Pi&#xff0c;请参阅我们的入门指南&#xff08;how to get started&#xff09;。 Raspberry Pi 5 Raspberry Pi 5 配备了运行频率为 2.4GHz 的 64 位四核 Arm Cortex-A76 处理器&#xff0c;CPU 性…

ResNeXt(2017)

文章目录 Abstract1. Introductionformer workour work 2. Related Work多分支卷积网络分组卷积压缩卷积网络Ensembling 3. Method3.1. Template3.2. Revisiting Simple Neurons3.3. Aggregated Transformations3.4. Model Capacity 4. Experiment 原文地址 源代码 Abstract 我…

【二分查找】LeetCode:2354.优质数对的数目

作者推荐 贪心算法LeetCode2071:你可以安排的最多任务数目 本文涉及的基础知识点 二分查找算法合集 题目 给你一个下标从 0 开始的正整数数组 nums 和一个正整数 k 。 如果满足下述条件&#xff0c;则数对 (num1, num2) 是 优质数对 &#xff1a; num1 和 num2 都 在数组 …

VisualStudio反汇编功能使用

VisualStudio反汇编功能使用 使用方法 到达断点时&#xff1a;CtrlK&#xff08;松开&#xff09;G&#xff08;后按&#xff09;唤出反汇编界面&#xff0c;就可以看到当前代码对应的汇编语言了 注意&#xff1a;进入反汇编窗口后可以F10单次调试一条汇编指令 其他&#…

【vscode写vue代码是白色怎么办】

【vscode写vue代码是白色怎么办】 在插件列表中搜索Vetur 安装即可

linux虚拟机Virtualbox的下载安装及vagrant镜像下载安装

Virtualbox下载安装以及创建及简单使用一个虚拟机 1.开启电脑cpu虚拟机 以戴尔G3为例 找到电脑设置–>更新与安全–>恢复 这个步骤也可以在电脑开机时一直按键esc(或者F1、或者F2、或者deleete)都可以进入BIOS 进入BIOS 完成以上步骤就可以开启电脑cpu虚拟机了 …

使用Tomcat部署静态项目并处理BUG

--听讲的习惯 Tomcat介绍 tomcat what_Arenaschi的博客-CSDN博客 Tomcat安装及配置教程&#xff08;超详细&#xff09; 那些年我们用过的tomcat_Arenaschi的博客-CSDN博客 简单使用tomcat查看版本信息等_windows查看tomcat版本命令-CSDN博客 Tomcat部署html静态网站的五种方…

红海云eHR 任意文件上传漏洞复现

0x01 产品简介 红海eHR是大中型企业广泛采用人力资源管理系统。红海云是国内顶尖的HR软件供应商,是新一代eHR系统的领导者。 0x02 漏洞概述 红海云EHR系统PtFjk.mob接口处存在未授权文件上传漏洞,攻击者可上传webshell来命令执行,获取服务器权限。 0x03 复现环境 FOFA:…

Leetcode 17 电话号码的字母组合

理解题意&#xff1a; 给定一个仅包含数字 2-9 的字符串&#xff0c;返回所有它能表示的字母组合 本质上&#xff1a;数字代表着一个字母集合 数字的个数决定了递归的深度&#xff0c;即树的深度 数字代表的字母组合决定了当前树的宽度。 1.暴力回溯 这里没有什么剪枝…

拆解大语言模型 RLHF 中的PPO算法

为什么大多数介绍大语言模型 RLHF 的文章&#xff0c;一讲到 PPO 算法的细节就戛然而止了呢&#xff1f;要么直接略过&#xff0c;要么就只扔出一个 PPO 的链接。然而 LLM x PPO 跟传统的 PPO 还是有些不同的呀。 其实在 ChatGPT 推出后的相当一段时间内&#xff0c;我一直在等…

【数据结构】顺序表的定义和运算

目录 1.初始化 2.插入 3.删除 4.查找 5.修改 6.长度 7.遍历 8.完整代码 &#x1f308;嗨&#xff01;我是Filotimo__&#x1f308;。很高兴与大家相识&#xff0c;希望我的博客能对你有所帮助。 &#x1f4a1;本文由Filotimo__✍️原创&#xff0c;首发于CSDN&#x1f4da;。 &…

SpringBoot+线程池实现高频调用http接口并多线程解析json数据

场景 SpringbootFastJson实现解析第三方http接口json数据为实体类(时间格式化转换、字段包含中文)&#xff1a; SpringbootFastJson实现解析第三方http接口json数据为实体类(时间格式化转换、字段包含中文)-CSDN博客 Java中ExecutorService线程池的使用(Runnable和Callable多…

swiftUi——颜色

在SwiftUI中&#xff0c;您可以使用Color结构来表示颜色。Color可以直接使用预定义的颜色&#xff0c;例如.red、.blue、.green等&#xff0c;也可以使用自定义的RGB值、十六进制颜色代码或者系统提供的颜色。 1. 预定义颜色 Text("预定义颜色").foregroundColor(.…

使用STM32 HAL库进行GPIO控制的实例

✅作者简介&#xff1a;热爱科研的嵌入式开发者&#xff0c;修心和技术同步精进&#xff0c; 代码获取、问题探讨及文章转载可私信。 ☁ 愿你的生命中有够多的云翳,来造就一个美丽的黄昏。 &#x1f34e;获取更多嵌入式资料可点击链接进群领取&#xff0c;谢谢支持&#xff01;…

人工智能学习9(LightGBM)

编译工具&#xff1a;PyCharm 文章目录 编译工具&#xff1a;PyCharm lightGBM原理lightGBM的基础使用案例1&#xff1a;鸢尾花案例2&#xff1a;绝对求生玩家排名预测一、数据处理部分1.数据获取及分析2.缺失数据处理3.数据规范化4.规范化输出部分数据5.异常数据处理5.1删除开…

调用win32 api获取电脑名字和系统目录

学习一下几个函数的功能&#xff0c;和调用方式&#xff1b; void CBasenameView::OnDraw(CDC* pDC) {CBasenameDoc* pDoc GetDocument();ASSERT_VALID(pDoc);// TODO: add draw code for native data hereCString str1;TCHAR myname1[50], myname2[50], mydirname1[50], myd…