【LeetCode每日一题】【2023/1/3】2042. 检查句子中的数字是否递增

news2024/10/4 11:23:45

文章目录

  • 2042. 检查句子中的数字是否递增
    • 方法1:直接遍历
      • 写法2:按本题特有条件
    • 方法2:栈
    • 方法3:std::stringstream
      • 写法2


2042. 检查句子中的数字是否递增

LeetCode: 2042. 检查句子中的数字是否递增

简单 \color{#00AF9B}{简单} 简单

句子是由若干 token 组成的一个列表,token 间用 单个 空格分隔,句子没有前导或尾随空格。每个 token 要么是一个由数字 0-9 组成的不含前导零的 正整数 ,要么是一个由小写英文字母组成的 单词

  • 示例,"a puppy has 2 eyes 4 legs" 是一个由 7 个 token 组成的句子:"2""4" 是数字,其他像 "puppy" 这样的 tokens 属于单词。

给你一个表示句子的字符串 s ,你需要检查 s 中的 全部 数字是否从左到右严格递增(即,除了最后一个数字,s 中的 每个 数字都严格小于它 右侧 的数字)。

如果满足题目要求,返回 true ,否则,返回 false

示例 1:

在这里插入图片描述

输入:s = "1 box has 3 blue 4 red 6 green and 12 yellow marbles"
输出:true
解释:句子中的数字是:1, 3, 4, 6, 12 。
这些数字是按从左到右严格递增的 1 < 3 < 4 < 6 < 12

示例 2:

输入:s = "hello world 5 x 5"
输出:false
解释:句子中的数字是:5, 5 。这些数字不是严格递增的。

示例 3:

在这里插入图片描述

输入:s = "sunset is at 7 51 pm overnight lows will be in the low 50 and 60 s"
输出:false
解释:s 中的数字是:7, 51, 50, 60 。这些数字不是严格递增的。

示例 4:

输入:s = "4 5 11 26"
输出:true
解释:s 中的数字是:4, 5, 11, 26 。
这些数字是按从左到右严格递增的:4 < 5 < 11 < 26

提示:

  • 3 <= s.length <= 200
  • s 由小写英文字母、空格和数字 09 组成(包含 09
  • s 中数字 token 的数目在 2100 之间(包含 2100
  • s 中的 token 之间由单个空格分隔
  • s 中至少有 两个 数字
  • s 中的每个数字都是一个 小于 100 数,且不含前导零
  • s 不含前导或尾随空格

方法1:直接遍历

直接遍历字符串。每次遇到 数字字符 时,记录该数值为 num ,并且继续往后遍历。如果后面紧跟 数字字符,则更新 num(将之前的 num 乘以10再加本次数字)。

此外,还需要记录最大值 biggest ,用于和每次遍历得到的 num 进行比较。若不符合 严格递增 的条件( num <= biggest ),则直接返回 false

#include <string>
#include <cctype>
using namespace std;

class Solution
{
public:
    bool areNumbersAscending(string s)
    {
        int biggest = 0;
        for (auto it = s.begin(); it != s.end();)
        {
            if (!std::isdigit(*it))
            {
                it++;
                continue;
            }

            int num = 0;
            while (it != s.end() && std::isdigit(*it))
            {
                num = 10 * num + *it - '0';
                it++;
            }
            if (num > biggest)
                biggest = num;
            else
                return false;
        }
        return true;
    }
};

复杂度分析

  • 时间复杂度: O ( n ) O(n) O(n)。其中,n 为字符串 s 的长度。在上面的写法中,即使有内外两层循环,但本质上还是对字符串 s一次 遍历。内循环是接着外循环遍历下去的,字符串中的每个字符都只被遍历 一次

  • 空间复杂度: O ( 1 ) O(1) O(1)。只用到了一些变量,占用常数空间。

参考结果

Accepted
98/98 cases passed (4 ms)
Your runtime beats 30.38 % of cpp submissions
Your memory usage beats 40.51 % of cpp submissions (6.2 MB)

写法2:按本题特有条件

实际上,本题给出的条件中,s 中的每个数字都是一个 小于 100 数。也就说明每个数最多只占 2 位。这样的话我们可以把上述代码中的循环去掉。每次遇到 数字字符 时,直接把 下一个 字符“拿进来”。如果下一个字符也是数字字符,就更新 num ;否则直接“扔掉”该字符。

#include <string>
#include <cctype>
using namespace std;

class Solution
{
public:
    bool areNumbersAscending(string s)
    {
        int biggest = 0;
        for (auto it = s.begin(); it != s.end();)
        {
            if (!std::isdigit(*it))
            {
                it++;
                continue;
            }

            int num = *it;
            it++;
            if (std::isdigit(*it))
            {
                num = 10 * num + *it - '0';
                it++;
            }

            if (num > biggest)
                biggest = num;
            else
                return false;
        }
        return true;
    }
};

复杂度分析

  • 时间复杂度: O ( n ) O(n) O(n)。其中,n 为字符串 s 的长度。

  • 空间复杂度: O ( 1 ) O(1) O(1)。只用到了一些变量,占用常数空间。

参考结果

Accepted
98/98 cases passed (0 ms)
Your runtime beats 100.00 % of cpp submissions
Your memory usage beats 56.33 % of cpp submissions (6.1 MB)

方法2:栈

在遍历字符串的时候,我们假设一次遍历只能处理一个字符(例如外部设备很慢,一次只能给出一个字符之类)。当我们遇到一个数字字符时,是不知道它处在数的第几位的。例如在一个 空格 之后接收到一个 数字字符 1 ,它有可能就是 1 这个数,但是它也有可能是 十几一百多。因此我们要从前往后记录这些数,再从后往前把每个数乘上 10的i次方 再加起来。

首先,方法1 中的写法实际上也可以看做一个 隐式 。(当然,“隐式栈”一般指“调用栈”,这里只是个比喻。)

while (it != s.end() && std::isdigit(*it))
{
    num = 10 * num + *it - '0';
    it++;
}

num = 10 * num + *it - '0' 这一句我们可以看作把一个个 数字字符 记录在了一个 “栈” 里,这个 “栈” 本身是一个 整型变量 int,我们把每个 数字字符 都存到了这个变量里。

如果要写明一个 的实现的话,可以参考以下代码:

#include <string>
#include <stack>
using namespace std;

class Solution
{
public:
    bool areNumbersAscending(string s)
    {
        s.push_back(' ');

        stack<int> stk;
        int biggest = 0;

        for (const auto &c : s)
        {
            if ('0' <= c && c <= '9')
            {
                stk.emplace(c);
            }
            else
            {
                if (stk.empty())
                    continue;

                int num = 0;
                int multiple = 1;
                while (!stk.empty())
                {
                    num += stk.top() * multiple;
                    multiple *= 10;
                    stk.pop();
                }
                if (num > biggest)
                    biggest = num;
                else
                    return false;
            }
        }
        return true;
    }
};

复杂度分析

  • 时间复杂度: O ( n ) O(n) O(n)。其中,n 为字符串 s 的长度。

  • 空间复杂度: O ( n ) O(n) O(n)。栈会占用 O ( n ) O(n) O(n)的空间。

参考结果

Accepted
98/98 cases passed (0 ms)
Your runtime beats 100.00 % of cpp submissions
Your memory usage beats 56.33 % of cpp submissions (6.1 MB)

同样地,对于本题每个数最多 2 位的条件,我们也可以把 简化为对一个长度为 2char 数组的维护:

#include <string>
#include <cmath>
#include <cstdint>
using namespace std;

class Solution
{
public:
    bool areNumbersAscending(string s)
    {
        s.push_back(' ');

        char nums[2]{};
        int index = 0;
        int biggest = 0;

        for (const auto &c : s)
        {
            if ('0' <= c && c <= '9')
            {
                nums[index] = c - '0';
                index++;
            }
            else
            {
                int num = 0;
                if (index == 1)
                    num = nums[0];
                else if (index == 2)
                    num = 10 * nums[0] + nums[1];
                else
                    continue;

                if (num > biggest)
                    biggest = num;
                else
                    return false;

                *(uint16_t *)nums = 0;
                index = 0;
            }
        }
        return true;
    }
};

*(uint16_t *)nums = 0 这一句中,由于 nums 是一个长度为 2char 类型数组,而一个 char 类型变量占 1 字节,因此 nums 总占 2 字节,也就是16位。这里把 nums 指针强制转换为一个 16 位的无符号整数指针,再设为 0 ( 0000H ),就是一次性把 nums 的两个元素都设为了 0

复杂度分析

  • 时间复杂度: O ( n ) O(n) O(n)。其中,n 为字符串 s 的长度。

  • 空间复杂度: O ( 1 ) O(1) O(1)。只用到了一些变量,占用常数空间。

参考结果

Accepted
98/98 cases passed (0 ms)
Your runtime beats 100.00 % of cpp submissions
Your memory usage beats 17.72 % of cpp submissions (6.3 MB)

方法3:std::stringstream

我们可以使用C++标准库中的 std::stringstream 字符串流类来实现。由于 stringstream>>运算符重载 在向外提取数据时,在空格处可以自动停止,因此对于我们划分 token 来说比较有帮助。同时,如果 >> 右边的参数是一个 数值类型 的变量,它还可以自动将字符串转换为对应的数,并赋值给这个数。

我们首先把字符串 s 中所有字符都插入字符串流中,然后定义一个 整型变量 来接收。当把非 数字字符 (非’0’~‘9’)传给一个数值类型变量时,stringstream 会在状态位中设置 failbit 。此时我们只需要清除状态位,然后调用 get() 成员函数“扔掉”这个字符就行,再继续遍历。

#include <string>
#include <sstream>
using namespace std;

class Solution
{
public:
    bool areNumbersAscending(string s)
    {
        stringstream ss{s};
        int biggest = 0;

        while (ss.good())
        {
            int num = 0;
            ss >> num;
            if (!ss.fail())
            {
                if (num > biggest)
                    biggest = num;
                else
                    return false;
            }
            else
            {
                ss.clear();
                ss.get();
            }
        }
        return true;
    }
};

复杂度分析

  • 时间复杂度:可能为 O ( n ) O(n) O(n)。其中,n 为字符串 s 的长度。

    • cppreference上并未给出 std::stringstream 的构造及个别操作的时间复杂度。
  • 空间复杂度:可能为 O ( n ) O(n) O(n)

    • cppreference上并未给出 std::stringstream 的构造及个别操作的时间复杂度。

参考结果

Accepted
98/98 cases passed (0 ms)
Your runtime beats 100.00 % of cpp submissions
Your memory usage beats 29.12 % of cpp submissions (6.2 MB)

写法2

我们可以换一种方式。上一种是将每个 token 提取到 整型变量 中,然后根据是否成功来继续操作。我们也可以把每个 token 提取到 字符串变量 中。根据题目给出的条件:

每个 token 要么是一个由数字 0-9 组成的不含前导零的 正整数 ,要么是一个由小写英文字母组成的 单词

我们可以判断每个 token 中的任一字符(如第一个字符),只要这个 字符数字字符 ,那么整个 token 都是由 数字字符 组成的。这时,我们调用 std::stoi 函数将字符串转化为 int 即可。

#include <string>
#include <sstream>
using namespace std;

class Solution
{
public:
    bool areNumbersAscending(string s)
    {
        stringstream ss{s};
        string &token = s;
        int biggest = 0;

        while (!ss.eof())
        {
            ss >> token;
            if (std::isdigit(token[0]))
            {
                const int num = std::stoi(s);
                if (num > biggest)
                    biggest = num;
                else
                    return false;
            }
        }
        return true;
    }
};

复杂度分析(同写法1)

  • 时间复杂度:可能为 O ( n ) O(n) O(n)。其中,n 为字符串 s 的长度。

    • cppreference上并未给出 std::stringstream 的构造及个别操作的时间复杂度。
  • 空间复杂度:可能为 O ( n ) O(n) O(n)

    • cppreference上并未给出 std::stringstream 的构造及个别操作的时间复杂度。

参考结果

Accepted
98/98 cases passed (0 ms)
Your runtime beats 100.00 % of cpp submissions
Your memory usage beats 77.22 % of cpp submissions (6.1 MB)

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

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

相关文章

202301-第一周资讯

大家好&#xff0c;欢迎来到本周资讯&#xff0c;在过去的一周内呢&#xff0c;我们在示例DEMO、文档、教学视频上都有了较多的产出并且帮助大家解决了不少问题&#xff0c;赶紧看看上周成果吧&#xff01; 目录 DEMO 动态TopN报表 导出图文报告的脚本示例 Superpage pc端…

【FPGA】基本实验步骤演示 | Verilog编码 | 运行合成 | 设备/引脚分配 | 综合/实施 | 设备配置

写在前面&#xff1a;本章的目的是让你理解与门、或门和非门的行为&#xff0c;并使用 Verilog 语言实现多输入与门、或门和非门。在生成输入信号之后&#xff0c;你需要通过模拟来验证这些门的操作&#xff0c;并使用 FPGA 来验证 Verilog 实现的电路的行为。 0x00 引入&#…

Vue+Echarts监控大屏实例十六:Echarts对接天地图插件开发

一、实例概述 本实例实现echarts使用天地图组件的开发,通过修改echarts中百度地图及高德地图插件实现echarts中使用天地图的使用。本实例实现对于监控界面的相关开发资料,提供实例源码、开发过程视频及实现过程。   1. Echarts参考文档: echarts   2. 高德地图插件:ech…

P1455 搭配购买

题目描述 明天就是母亲节了&#xff0c;电脑组的小朋友们在忙碌的课业之余挖空心思想着该送什么礼物来表达自己的心意呢&#xff1f;听说在某个网站上有卖云朵的&#xff0c;小朋友们决定一同前往去看看这种神奇的商品&#xff0c;这个店里有 nn 朵云&#xff0c;云朵已经被老板…

非Web服务弱口令检查工具下载与使用

今天继续给大家介绍渗透测试相关知识&#xff0c;本文主要内容是非Web服务弱口令检查工具下载与使用。 免责声明&#xff1a; 本文所介绍的内容仅做学习交流使用&#xff0c;严禁利用文中技术进行非法行为&#xff0c;否则造成一切严重后果自负&#xff01; 再次强调&#xff1…

操作系统的运行机制和体系结构

文章目录&#x1f380;前言&#xff1a;本篇博客知识总览&#x1f3c5;运行机制&#x1f387;两种指令&#x1f387;两种状态&#x1f387;两种程序&#x1f3c5;操作系统的内核&#x1f387;内核概念&#xff1a;&#x1f3c5;操作系统的体系结构&#x1f3af;最常考点&#x…

DevOps - Jenkins可视化流水线(后端部分)

目录 &#x1f9e1;创建DevOps工程 &#x1f9e1;拉取代码 &#x1f9e1;项目编译 &#x1f9e1;构建镜像 &#x1f9e1;推送镜像 &#x1f9e1;部署到Dev环境 &#x1f9e1;邮件功能 &#x1f9e1;激活微服务 &#x1f49f;这里是CS大白话专场&#xff0c;让枯燥的学习…

zookeeper下载安装

1、环境准备 ZooKeeper服务器是用Java创建的&#xff0c;它运行在JVM之上。需要安装JDK 7或更高版本。 2、上传 将下载的ZooKeeper放到/opt/ZooKeeper目录下 #上传zookeeper altp put f:/setup/apache-zookeeper-3.5.6-bin.tar.gz #打开 opt目录 cd /opt #创建zooKeeper目录…

电子招标采购系统源码之什么是电子招投标系统?

随着互联网时代的到来&#xff0c;各行业都受到不同的影响&#xff0c;其中招投标行业也不例外。为了顺应互联网潮流的发展&#xff0c;电子招投标逐渐取代传统的纸质的招投标方式&#xff0c;给招标方、投标方、招标代理等各方也带来了前所未有的机遇与挑战。那么什么是电子招…

日志采集 - Filebeat

Filebeat 是什么&#xff1f; Filebeat是本地文件的日志数据采集器&#xff0c;可监控日志目录或特定日志文件&#xff08;tail file&#xff09;&#xff0c;并将它们转发给Elasticsearch或Logstatsh进行索引、kafka等。 是使用 Golang 实现的轻量型日志采集器&#xff0c;也…

Spring Boot配置MinIO(实现文件上传、读取、下载、删除)

一、 MinIO MinIO 是一个基于Apache License v2.0开源协议的对象存储服务。它兼容亚马逊S3云存储服务接口&#xff0c;非常适合于存储大容量非结构化的数据&#xff0c;例如图片、视频、日志文件、备份数据和容器/虚拟机镜像等&#xff0c;而一个对象文件可以是任意大小&#x…

INSERT ON DUPLICATE KEY UPDATE返回值引起的小乌龙

一、东窗事发 某个版本送测,测试大佬给提了一个缺陷,且听我描述描述: 一个学习任务: 两个一模一样的学习动态: 产品定义:学习任务(生字学习)完成后,会在小程序生成一个动态,再次完成不重复生成obviously,上边出现的两个动态不符合“罗辑” 二、排查看看 既然出现了两个动态…

dubbo源码实践-transport 网络传输层的例子

1 Transporter层概述Transporter层位于第2层&#xff0c;已经实现了完整的TCP通信&#xff0c;定义了一套Dubbo自己的API接口&#xff0c;支持Netty、Mina等框架。官方定义&#xff1a;transport 网络传输层&#xff1a;抽象 mina 和 netty 为统一接口&#xff0c;以 Message 为…

剑指 Offer 09. 用两个栈实现队列

用两个栈实现一个队列。队列的声明如下&#xff0c;请实现它的两个函数 appendTail 和 deleteHead &#xff0c;分别完成在队列尾部插入整数和在队列头部删除整数的功能。(若队列中没有元素&#xff0c;deleteHead 操作返回 -1 ) 示例 1&#xff1a; 输入&#xff1a; ["…

自然语言处理 第11章 问答系统 复习

问答系统问答系统概述问答系统定义问答(QA)系统发展历程问答系统分类&#xff1a;问答系统框架&#xff1a;内容提要专家系统检索式问答系统1.问题分析主要功能&#xff1a;问题分类 和 关键词提取问题分类实现方法2.关键词提取检索模块相关文档检索句段检索3. 答案抽取模块检索…

回顾2022年,展望2023年

这里写目录标题回顾2022年博客之星你参加了吗&#xff1f;学习方面写博客方面在涨粉丝方面展望2023回顾2022年 时间如梭&#xff0c;转眼间已经2023年了。 你开始做总结了吗&#xff1f; 博客之星你参加了吗&#xff1f; 这是 2022 博客之星 的竞选帖子&#xff0c; 请你在这…

【从零开始学习深度学习】36. 门控循环神经网络之长短期记忆网络(LSTM)介绍、Pytorch实现LSTM并进行训练预测

上一篇文章介绍了一种门控循环神经网络门控循环单元GRU&#xff0c;本文将介绍另一种常用的门控循环神经网络&#xff1a;长短期记忆&#xff08;long short-term memory&#xff0c;LSTM&#xff09;&#xff0c;它比GRU稍复杂一点。 本文将介绍其实现方法&#xff0c;并使用其…

leetcode 221. 最大正方形-java题解

题目所属分类 动态规划 前面写过一个面积最大的长方形 传送门 f[i, j]表示&#xff1a;所有以(i,j)为右下角的且只包含 1 的正方形的边长最大值 原题链接 在一个由 ‘0’ 和 ‘1’ 组成的二维矩阵内&#xff0c;找到只包含 ‘1’ 的最大正方形&#xff0c;并返回其面积。 代…

最邻近方法和最邻近插入法求TSP问题近似解(可视化+代码)

摘要&#xff1a;本文总体内容为介绍用最邻近方法(Nearest Neighbor Algorithm) 和最邻近插入法求解旅行商问题(Traveling Saleman Problem,TSP)。同时使用python实现算法&#xff0c;并调用networkx库实现可视化。此文为本人图论课下作业的成品&#xff0c;含金量&#xff1a;…

【若依】前后端分离版本

一、何为框架&#xff1f;若依框架又是什么&#xff1f;具备什么功能&#xff1f; 框架的英文为Framework&#xff0c;带有骨骼&#xff0c;支架的含义。在软件工程中&#xff0c;框架往往被定义为整个或部分系统的可重用设计&#xff0c;是一个可重复使用的设计构件。类似于一…