leetcode刷题记录18(2023-08-29)【最短无序连续子数组(单调栈) | 合并二叉树(dfs) | 任务调度器(桶) | 回文子串(二维dp)】

news2024/9/22 22:38:20

581. 最短无序连续子数组

给你一个整数数组 nums ,你需要找出一个 连续子数组 ,如果对这个子数组进行升序排序,那么整个数组都会变为升序排序。

请你找出符合题意的 最短 子数组,并输出它的长度。

示例 1:

输入:nums = [2,6,4,8,10,9,15]
输出:5
解释:你只需要对 [6, 4, 8, 10, 9] 进行升序排序,那么整个表都会变为升序排序。

示例 2:

输入:nums = [1,2,3,4]
输出:0

示例 3:

输入:nums = [1]
输出:0

提示:

1 < = n u m s . l e n g t h < = 1 0 4 1 <= nums.length <= 10^4 1<=nums.length<=104
− 1 0 5 < = n u m s [ i ] < = 1 0 5 -10^5 <= nums[i] <= 10^5 105<=nums[i]<=105

进阶:你可以设计一个时间复杂度为 O(n) 的解决方案吗?

最简单的方法就是排序后,比较相同元素的数量,但我竟然没想到 = =。

class Solution {
public:
    int findUnsortedSubarray(vector<int>& nums) {
        // 拷贝一份 nums
        vector<int> vec(nums);
        sort(vec.begin(), vec.end());
        int left = 0;
        while (left < nums.size()) {
            if (vec[left] != nums[left]) {
                break;
            }
            left++;
        }

        if (left == nums.size()) {
            return 0;
        }

        int right = nums.size() - 1;
        while (right >= 0) {
            if (vec[right] != nums[right]) {
                break;
            }
            right--;
        }

        return right + 1 - left;
    }
};

时间复杂度:由排序产生,O(nlogn)
空间复杂度:由拷贝的子数组产生,O(n)

参考了官方解析的做法:https://leetcode.cn/problems/shortest-unsorted-continuous-subarray/solutions/911677/zui-duan-wu-xu-lian-xu-zi-shu-zu-by-leet-yhlf/

中间数组的最大值,一定小于等于右边数组的最小值
中间数组的最小值,一定大于等于左边数组的最大值

因此,我们只需要找到,左右两边的守门员,二者相减就可以了。

class Solution {
public:
    int findUnsortedSubarray(vector<int>& nums) {
        int maxVal = -0x3f3f3f3f;
        int right = -1;
        for (int i = 0; i < nums.size(); i++) {
            if (nums[i] < maxVal) {
                right = i;
            }
            else {
                maxVal = nums[i];
            }
        }
        if (right == -1) return 0;

        int minVal = 0x3f3f3f3f;
        int left = -1;
        for (int i = nums.size() - 1; i >= 0; i--) {
            if (nums[i] > minVal) {
                left = i;
            }
            else {
                minVal = nums[i];
            }
        }
        return right + 1 - left;
    }
};

617. 合并二叉树

给你两棵二叉树: root1 和 root2 。

想象一下,当你将其中一棵覆盖到另一棵之上时,两棵树上的一些节点将会重叠(而另一些不会)。你需要将这两棵树合并成一棵新二叉树。合并的规则是:如果两个节点重叠,那么将这两个节点的值相加作为合并后节点的新值;否则,不为 null 的节点将直接作为新二叉树的节点。

返回合并后的二叉树。

注意: 合并过程必须从两个树的根节点开始。

示例 1:

在这里插入图片描述

输入:root1 = [1,3,2,5], root2 = [2,1,3,null,4,null,7]
输出:[3,4,5,5,4,null,7]

示例 2:

输入:root1 = [1], root2 = [1,2]
输出:[2,2]

提示:

两棵树中的节点数目在范围 [0, 2000] 内
− 1 0 4 < = N o d e . v a l < = 1 0 4 -10^4 <= Node.val <= 10^4 104<=Node.val<=104

根据root1和root2是否为nullptr构建当前节点node,然后构建node->left和node->right,最后返回node。

#include<iostream>

using namespace std;
// Definition for a binary tree node.
struct TreeNode {
    int val;
    TreeNode* left;
    TreeNode* right;
    TreeNode() : val(0), left(nullptr), right(nullptr) {}
    TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
    TreeNode(int x, TreeNode* left, TreeNode* right) : val(x), left(left), right(right) {}
};

class Solution {
public:
    TreeNode* mergeTrees(TreeNode* root1, TreeNode* root2) {
        TreeNode* node = new TreeNode;
        if (root1 != nullptr && root2 != nullptr) {
            node->val = root1->val + root2->val;
            node->left = mergeTrees(root1->left, root2->left);
            node->right = mergeTrees(root1->right, root2->right);
        }
        else if (root1 != nullptr) {
            node->val = root1->val;
            node->left = mergeTrees(root1->left, nullptr);
            node->right = mergeTrees(root1->right, nullptr);
        }
        else if (root2 != nullptr) {
            node->val = root2->val;
            node->left = mergeTrees(nullptr, root2->left);
            node->right = mergeTrees(nullptr, root2->right);
        }
        else {
            delete node;
            node = nullptr;
            return node;
        }
        return node;
    }
};

int main() {
    TreeNode* root1 = new TreeNode(1);
    root1->left = new TreeNode(3);
    root1->right = new TreeNode(2);
    root1->left->left = new TreeNode(5);

    TreeNode* root2 = new TreeNode(2);
    root2->left = new TreeNode(1);
    root2->right = new TreeNode(3);
    root2->left->right = new TreeNode(4);
    root2->right->right = new TreeNode(7);

    Solution sol;
    TreeNode* root = sol.mergeTrees(root1, root2);

    return 0;
}

621. 任务调度器

给你一个用字符数组 tasks 表示的 CPU 需要执行的任务列表。其中每个字母表示一种不同种类的任务。任务可以以任意顺序执行,并且每个任务都可以在 1 个单位时间内执行完。在任何一个单位时间,CPU 可以完成一个任务,或者处于待命状态。

然而,两个 相同种类 的任务之间必须有长度为整数 n 的冷却时间,因此至少有连续 n 个单位时间内 CPU 在执行不同的任务,或者在待命状态。

你需要计算完成所有任务所需要的 最短时间 。

示例 1:

输入:tasks = [“A”,“A”,“A”,“B”,“B”,“B”], n = 2
输出:8
解释:A -> B -> (待命) -> A -> B -> (待命) -> A -> B
在本示例中,两个相同类型任务之间必须间隔长度为 n = 2 的冷却时间,而执行一个任务只需要一个单位时间,所以中间出现了(待命)状态。

示例 2:

输入:tasks = [“A”,“A”,“A”,“B”,“B”,“B”], n = 0
输出:6
解释:在这种情况下,任何大小为 6 的排列都可以满足要求,因为 n = 0
[“A”,“A”,“A”,“B”,“B”,“B”]
[“A”,“B”,“A”,“B”,“A”,“B”]
[“B”,“B”,“B”,“A”,“A”,“A”]

诸如此类

示例 3:

输入:tasks = [“A”,“A”,“A”,“A”,“A”,“A”,“B”,“C”,“D”,“E”,“F”,“G”], n = 2
输出:16
解释:一种可能的解决方案是:
A -> B -> C -> A -> D -> E -> A -> F -> G -> A -> (待命) -> (待命) -> A -> (待命) -> (待命) -> A

提示:

1 < = t a s k . l e n g t h < = 1 0 4 1 <= task.length <= 10^4 1<=task.length<=104
tasks[i] 是大写英文字母
n 的取值范围为 [0, 100]

参考题解:https://leetcode.cn/problems/task-scheduler/solutions/196302/tong-zi-by-popopop/

#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;

class Solution {
public:
    int leastInterval(vector<char>& tasks, int n) {
        int len = tasks.size();
        vector<int> vec(26);
        for (int i = 0; i < tasks.size(); i++) {
            vec[tasks[i] - 'A']++;
        }
        sort(vec.begin(), vec.end(), [](int& x, int& y) {return x > y; });
        int cnt = 1;
        while (cnt < vec.size() && vec[cnt] == vec[0]) cnt++;
        return max(len, cnt + (n + 1) * (vec[0] - 1));
    }
};

int main() {
    vector<char> tasks = { 'A','A','A','B','B','B' };
    Solution sol;
    int res = sol.leastInterval(tasks, 2);
    cout << res << endl;
    return 0;
}

647. 回文子串

给你一个字符串 s ,请你统计并返回这个字符串中 回文子串 的数目。

回文字符串 是正着读和倒过来读一样的字符串。

子字符串 是字符串中的由连续字符组成的一个序列。

具有不同开始位置或结束位置的子串,即使是由相同的字符组成,也会被视作不同的子串。

示例 1:

输入:s = “abc”
输出:3
解释:三个回文子串: “a”, “b”, “c”

示例 2:

输入:s = “aaa”
输出:6
解释:6个回文子串: “a”, “a”, “a”, “aa”, “aa”, “aaa”

提示:

1 <= s.length <= 1000
s 由小写英文字母组成

经典动态规划题目,可以一个二维数组 dp 利用进行求解。

状态转移方程为:

if (len == 2) {
    dp[i][j] = (s[i] == s[j]);
}
else {
    dp[i][j] = dp[i + 1][j - 1] && (s[i] == s[j]);
}

代码入下:

#include<vector>
#include<string>
#include<iostream>

using namespace std;

class Solution {
public:
    int countSubstrings(string s) {
        int num = s.size();
        vector<vector<bool>> dp(num, vector<bool>(num));
        for (int i = 0; i < num; i++) {
            dp[i][i] = true;
        }
        int res = num;
        for (int len = 2; len <= num; len++) {
            for (int i = 0; i < num - len + 1; i++) {
                int j = i + len - 1;
                if (len == 2) {
                    dp[i][j] = (s[i] == s[j]);
                }
                else {
                    dp[i][j] = dp[i + 1][j - 1] && (s[i] == s[j]);
                }
                if (dp[i][j] == true) res++;
            }
        }
        return res;
    }
};

int main() {
    string s = "aaaaa";
    Solution sol;
    int res = sol.countSubstrings(s);
    cout << res;
}

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

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

相关文章

Linux系统中的IP地址、主机名、和域名解析

1.IP地址 每一台联网的电脑都会有一个地址&#xff0c;用于和其它计算机进行通讯 IP地址主要有2个版本&#xff0c;V4版本和V6版本&#xff08;V6很少用&#xff0c;暂不涉及&#xff09; IPv4版本的地址格式是&#xff1a;a.b.c.d&#xff0c;其中abcd表示0~255的数字&…

【爬虫实战】-爬取微博之夜盛典评论,爬取了1.7w条数据

前言&#xff1a; TaoTao之前在前几期推文中发布了一个篇weibo评论的爬虫。主要就是采集评论区的数据&#xff0c;包括评论、评论者ip、评论id、评论者等一些信息。然后有很多的小伙伴对这个代码很感兴趣。TaoTao也都给代码开源了。由于比较匆忙&#xff0c;所以没来得及去讲这…

vue3安装 router 路由

安装路由 cnpm i vue-router在src文件夹下创建router/index.ts import {createRouter,createWebHashHistory} from vue-router const routercreateRouter({history:createWebHashHistory(),routes:[{path:"/",name:home,component: () > import(../views/Home/i…

基于OCR的包装产品生产日期识别系统

基于OCR的包装产品生产日期识别系统 背景技术方案PaddleOCR模型应用数据挑战与解决方案优化策略 项目实施步骤结果与展望 背景 在工业生产中&#xff0c;产品包装上的生产日期信息是至关重要的&#xff0c;它关系到物资的时效性和质量。为了更快、更准确地提取这些信息&#x…

阿里云云服务器u1实例和e实例有什么区别?

阿里云服务器u1和e实例有什么区别&#xff1f;ECS通用算力型u1实例是企业级独享型云服务器&#xff0c;ECS经济型e实例是共享型云服务器&#xff0c;所以相比较e实例&#xff0c;云服务器u1性能更好一些。e实例为共享型云服务器&#xff0c;共享型实例采用非绑定CPU调度模式&am…

统一网关 Gateway【微服务】

文章目录 1. 前言2. 搭建网关服务3. 路由断言工厂4. 路由过滤器4.1 普通过滤器4.2 全局过滤器4.3 过滤器执行顺序 5. 跨域问题处理 1. 前言 通过前面的学习我们知道&#xff0c;通过 Feign 就可以向指定的微服务发起 http 请求&#xff0c;完成远程调用。但是这里有一个问题&am…

API(Date类,SimpleDateFormat类,Calendar类,JDK8时间相关类,包装类,算法小题)

文章目录 【常用API】今日内容教学目标 第一章 Date类1.1 Date概述1.2 Date常用方法 第二章 SimpleDateFormat类2.1 构造方法2.2 格式规则2.3 常用方法2.4 练习1(初恋女友的出生日期)2.5 练习2(秒杀活动) 第三章 Calendar类3.1 概述3.2 常用方法3.3 get方法示例3.4 set方法示例…

微机原理常考简答题(二)

一&#xff0c;简述8086CPU响应可屏蔽中断的条件及过程。 CPU响应可屏蔽中断的条件是有中断请求&#xff0c;中断标志IF1开中断&#xff0c;现行指令执行结束。 CPU响应可屏蔽中断的过程&#xff1a;CPU在INTR引脚上接到一个中断请求信号&#xff0c;如果此时IF1&#xff0c;并…

小知识分享2

文章目录 1.TCP/IP协议2.四次挥手断开连接3.TCP的三次握手和四次挥手4.在什么情况下需要设置WINS Proxy&#xff1f;5.用户与用户账户有什么不同&#xff1f;为什么需要使用用户账户&#xff1f; 1.TCP/IP协议 1、TCP/IP、Transmission Control Protocol/internet Protocol,传…

LeetCode刷题:142. 环形链表 II

题目&#xff1a; 是否独立解决&#xff1a;否&#xff0c;参考了解题思路解决问题&#xff0c;思考了用快慢指针&#xff0c;栈&#xff0c;统计链表数量定位尾巴节点&#xff08;因为是环形链表所以是死循环&#xff0c;链表数量用while循环统计不出来&#xff09;都没解决 解…

ActiveMQ反序列化RCE漏洞复现(CVE-2023-46604)

漏洞名称 Apache ActiveMQ OpenWire 协议反序列化命令执行漏洞 漏洞描述 Apache ActiveMQ 是美国阿帕奇&#xff08;Apache&#xff09;软件基金会所研发的一套开源的消息中间件&#xff0c;它支持Java消息服务、集群、Spring Framework等。 OpenWire协议在ActiveMQ中被用于…

Oracle数据库 CentOS7上修改hostname后无法启动解决办法

目录 一、问题背景 二、解决问题 三、重启数据库 四、重启监听 一、问题背景 CentOS系统需要修改hostname&#xff0c;修改后oracle数据库无法启动和正常运行。 系统&#xff1a;CentOS7.3 数据库版本&#xff1a;Oracle 11g Express Edtion 二、解决问题 通过which orac…

用C#实现简单的线性回归

前言 最近注意到了NumSharp&#xff0c;想学习一下&#xff0c;最好的学习方式就是去实践&#xff0c;因此从github上找了一个用python实现的简单线性回归代码&#xff0c;然后基于NumSharp用C#进行了改写。 NumSharp简介 NumSharp&#xff08;NumPy for C#&#xff09;是一…

【自译】【精华】MIT麻省理工学院技术双月刊(The Bimonthly MIT Technology Review)2024年1~2月【创新版块概览(一)】

导读&#xff1a; 今年是 《MIT技术评论杂志》 创刊125周年纪念年&#xff08;该杂志自1899年创刊&#xff09;&#xff0c;笔者将2024开年第1期&#xff08;1月~2月号&#xff09;的创新版块&#xff08;Innovation Issue&#xff09;中的重要内容进行梳理&#xff0c;获得近年…

软件测试进阶自动化测试流程

如果想让测试在公司的项目中发挥出它最大的价值&#xff0c;并不是招两个测试技术高手&#xff0c;或引入几个测试技术&#xff0c;而是测试技术对项目流程的渗透&#xff0c;以及测试流程的改进与完善。虽然&#xff0c;当然测试行业前景乐观&#xff0c;许多中小企业也都在引…

【计算机组成原理】高速缓冲存储器 Cache 的三种映射方式(Cache Mapping)

Cache映射 Cache Mapping 缓存是计算机系统中常见的一种高速存储器&#xff0c;用于临时存储常用数据&#xff0c;以便快速访问。在缓存中&#xff0c;有三种常见的映射方式&#xff0c;分别是直接映射、全相联映射和组相联映射。 直接映射 Direct Mapping 在直接映射中&…

Debian12 安装jenkins 公钥配置

jenkins公钥配置 参考&#xff1a;Debian Jenkins 软件包 这是 Jenkins 的 Debian 软件包存储库&#xff0c;用于自动安装和升级。 要使用此存储库&#xff0c;请先将密钥添加到您的系统&#xff08;对于每周发布行&#xff09;&#xff1a; sudo wget -O /usr/share/keyring…

IT从业人员如何养生?

目前&#xff0c;电脑对人体生理和心理方面的负面影响已日益受到人们的重视。为此科学使用电脑&#xff0c;减少电脑和网络的危害是十分必要的。好代码网总结了一些it从业人员的保健知识&#xff0c;分享给大家。 一是要增强自我保健意识 工作间隙注意适当休息&#xff0c;一般…

计算机毕业设计 | SpringBoot+vue的家庭理财 财务管理系统(附源码)

1&#xff0c;绪论 1.1 项目背景 网络的发展已经过去了七十多年&#xff0c;网络技术的发展&#xff0c;将会影响到人类的方方面面&#xff0c;网络的出现让各行各业都得到了极大的发展&#xff0c;为整个社会带来了巨大的生机。 现在许多的产业都与因特网息息相关&#xff…

MATLAB 2023a软件下载安装教程

编程如画&#xff0c;我是panda&#xff01; 这次给大家带来的是MATLAB 2023a的下载安装教程 前言 MATLAB&#xff0c;即Matrix Laboratory的缩写&#xff0c;是一款强大的科学计算软件&#xff0c;以其独特的矩阵计算基础、丰富的数学函数库和直观的数据可视化工具而闻名。作…