【LeetCode】2047. 句子中的有效单词数

题目

2047. 句子中的有效单词数

句子仅由小写字母('a''z')、数字('0''9')、连字符('-')、标点符号('!''.'',')以及空格(' ')组成。每个句子可以根据空格分解成 一个或者多个 token ,这些 token 之间由一个或者多个空格 ' ' 分隔。

如果一个 token 同时满足下述条件,则认为这个 token 是一个有效单词:

  • 仅由小写字母、连字符和/或标点(不含数字)。
  • 至多一个 连字符 '-' 。如果存在,连字符两侧应当都存在小写字母("a-b" 是一个有效单词,但 "-ab""ab-" 不是有效单词)。
  • 至多一个 标点符号。如果存在,标点符号应当位于 token 的 末尾

这里给出几个有效单词的例子:"a-b.""afad""ba-c""a!""!"

给你一个字符串 sentence ,请你找出并返回 sentence有效单词的数目

示例 1:

输入:sentence = "cat and  dog"
输出:3
解释:句子中的有效单词是 "cat"、"and" 和 "dog"

示例 2:

输入:sentence = "!this  1-s b8d!"
输出:0
解释:句子中没有有效单词
"!this" 不是有效单词,因为它以一个标点开头
"1-s" 和 "b8d" 也不是有效单词,因为它们都包含数字

示例 3:

输入:sentence = "alice and  bob are playing stone-game10"
输出:5
解释:句子中的有效单词是 "alice"、"and"、"bob"、"are" 和 "playing"
"stone-game10" 不是有效单词,因为它含有数字

示例 4:

输入:sentence = "he bought 2 pencils, 3 erasers, and 1  pencil-sharpener."
输出:6
解释:句子中的有效单词是 "he"、"bought"、"pencils,"、"erasers,"、"and" 和 "pencil-sharpener."

提示:

  • 1 <= sentence.length <= 1000
  • sentence 由小写英文字母、数字(0-9)、以及字符(' ''-''!''.'',')组成
  • 句子中至少有 1 个 token

题解1

思路

  • 注意到句子符合正则表达式,根据规则绘制状态转移图并编写解析程序

  • 状态转移图:【LeetCode】2047. 句子中的有效单词数_第1张图片

代码

class Solution:
    def isLetter(self, c):
        return 'a' <= c <= 'z'

    def isDigit(self, c):
        return '0' <= c <= '9'

    def isPunctuationMark(self, c):
        return c == '!' or c == '.' or c == ','

    def countValidWords(self, sentence: str) -> int:
        status = 0
        res = 0
        for c in sentence:
            if self.isLetter(c):
                if status == 0 or status == 1:
                    status = 1
                elif status == 2 or status == 3:
                    status = 3
                else:
                    status = 5
            elif self.isPunctuationMark(c):
                if status == 0 or status == 1 or status == 3:
                    status = 4
                else:
                    status = 5
            elif c == '-':
                if status == 1:
                    status = 2
                else:
                    status = 5
            elif c == ' ':
                if status == 1 or status == 3 or status == 4:
                    res += 1
                status = 0
            else:
                status = 5
        if status == 1 or status == 3 or status == 4:
            res += 1
        return res

复杂度

  • 时间复杂度: O ( n ) O(n) O(n)
  • 空间复杂度: O ( 1 ) O(1) O(1)

题解2

思路

  • 相对题解1自己写正则解析器,使用python自带的正则解析器

代码

import re
class Solution:
    def countValidWords(self, sentence: str) -> int:
        for c in sentence:
            rd = re.compile(r'(?:(?<=\s)|(?<=^))([a-z]+\-[a-z]+|[a-z]+)?(?(1)[\!\,\.]?|[\!\,\.])(?:(?=\s)|(?=$))')
            return len(rd.findall(sentence))

复杂度

  • 时间复杂度: O ( n ) O(n) O(n)
  • 空间复杂度: O ( 1 ) O(1) O(1)

题解3

思路

  • 将句子根据空格分为多个Token,并判断每个Token是否合法
  • 存在数字或标点不在末尾则不合法
  • 若存在多于一个’-’,或是’-'两边没有小写字母则不合法
  • 否则合法

代码

class Solution:
    def countValidWords(self, sentence: str) -> int:
        def isToken(s: str) -> bool:
            hasHyphens = False
            for i, ch in enumerate(s):
                if ch.isdigit() or (ch in "!.," and i < len(s) - 1):
                    return False
                if ch == '-':
                    if hasHyphens or i == 0 or i == len(s) - 1 or not s[i - 1].islower() or not s[i + 1].islower():
                        return False
                    hasHyphens = True
            return True
        return sum(isToken(s) for s in sentence.split())

复杂度

  • 时间复杂度: O ( n ) O(n) O(n)
  • 空间复杂度: O ( 1 ) O(1) O(1)

你可能感兴趣的:(#,LeetCode,leetcode,算法,职场和发展)