LeetCode 面试题 16.18. 模式匹配

2023-11-07 02:44

本文主要是介绍LeetCode 面试题 16.18. 模式匹配,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

文章目录

  • 一、题目
  • 二、C# 题解

一、题目

  你有两个字符串,即 patternvaluepattern 字符串由字母 "a""b" 组成,用于描述字符串中的模式。例如,字符串 "catcatgocatgo" 匹配模式 "aabab"(其中 "cat""a""go""b"),该字符串也匹配像 "a""ab""b" 这样的模式。但需注意 "a""b" 不能同时表示相同的字符串。编写一个方法判断value字符串是否匹配pattern字符串。

示例 1:

输入: pattern = “abba”, value = “dogcatcatdog”
输出: true

示例 2:

输入: pattern = “abba”, value = “dogcatcatfish”
输出: false

示例 3:

输入: pattern = “aaaa”, value = “dogcatcatdog”
输出: false

示例 4:

输入: pattern = “abba”, value = “dogdogdogdog”
输出: true
解释: “a”=“dogdog”,b=“”,反之也符合规则

提示:

  • 1 <= len(pattern) <= 1000
  • 0 <= len(value) <= 1000
  • 你可以假设 pattern 只包含字母 "a""b"value 仅包含小写字母。

  点击此处跳转题目。

二、C# 题解

  1. 判断长度是否满足要求。
    即判断是否存在一对 (aStr, bStr),使得 aLen * aNum + bLen * bNum = value.Length。其中

    • aStr / bStr 分别为 a / b 匹配的字符串。
    • aLen / bLen 分别为 aStr / bStr 的长度。
    • aNum / bNum 分别为 pattern 中 a / b 的个数。
  2. 对于所有的有序对 (aStr, bStr),顺序取 pattern 中的每个字符,判断 value 对应位置是否匹配。

  代码中用 lens 存储所有的有序对 (aStr, bStr)

public class Solution {public bool PatternMatching(string pattern, string value) {int n    = pattern.Length, l = value.Length;   // pattern 长度int aNum = pattern.Sum(a => a == 'a' ? 1 : 0); // pattern 中 a 的个数int bNum = n - aNum;                           // pattern 中 b 的个数List<int[]> lens = new List<int[]>(); // lens[i][0]/lens[i][1] 分别为 a/b 匹配的字符串长度if (aNum == 0) {if (l % bNum != 0) return false;lens.Add(new[] { 0, l / bNum });}else if (bNum == 0) {if (l % aNum != 0) return false;lens.Add(new[] { l / aNum, 0 });}elsefor (int i = 0; i <= l / aNum; i++)if ((l - i * aNum) % bNum == 0)lens.Add(new[] { i, (l - i * aNum) / bNum });foreach (var len in lens) {           // 每种 a/b 对应的长度都试一遍bool      ans   = true;           // 记录该种长度下是否匹配成功string?[] abStr = { null, null }; // 记录 a/b 对应匹配的字符串int       index = 0;              // 当前 value 中的匹配位置for (int j = 0; j < pattern.Length; j++) {int    ab    = pattern[j] - 'a';              // 1 表示 a,2 表示 bint    abLen = len[ab];                       // 取出 a_b 对应的匹配字符串长度string sub   = value.Substring(index, abLen); // 查看 value 中的字符串index += abLen;                               // 更新位置if (abStr[ab] == null) {                      // 之前未出现,则用 abStr 记录下来if (abStr[1 - ab] == sub) return false;   // 如果和另一个字符匹配的字符串一样,则返回 falseabStr[ab] = sub;}else if (abStr[ab] != sub) { // 匹配失败ans = false;             // 该情况返回 falsebreak;}}if (ans) return true; // 如果该情况匹配成功,直接返回 true}return false;}
}
  • 时间:68 ms,击败 66.67% 使用 C# 的用户
  • 内存:36.72 MB,击败 33.33% 使用 C# 的用户

  优化掉 lens 后,可以提升效率:

public class Solution {public bool PatternMatching(string pattern, string value) {int n    = pattern.Length, l = value.Length;   // pattern 长度int aNum = pattern.Sum(a => a == 'a' ? 1 : 0); // pattern 中 a 的个数int bNum = n - aNum;                           // pattern 中 b 的个数if (aNum == 0) return Repeat(value, bNum);if (bNum == 0) return Repeat(value, aNum);for (int aLen = 0; aLen <= l / aNum; aLen++) {if ((l - aLen * aNum) % bNum != 0) continue;int       bLen  = (l - aLen * aNum) / bNum;string?[] abStr = { null, null };int       index = 0;bool      ans   = true;for (var i = 0; i < pattern.Length; i++) {int    ab    = pattern[i] - 'a';int    abLen = ab == 0 ? aLen : bLen;string sub   = value.Substring(index, abLen);index += abLen;if (abStr[ab] == null) {                    if (abStr[1 - ab] == sub) return false; abStr[ab] = sub;}else if (abStr[ab] != sub) { ans = false;             break;}}if (ans) return true;}return false;}// 判断 value 是否重复 n 次public bool Repeat(string value, int n) {if (value.Length % n != 0) return false;int l = value.Length / n;for (int i = 0; i < l; i++)for (int j = 1; j < n; j++)if (value[(j - 1) * l + i] != value[j * l + i])return false;return true;}
}
  • 时间:60 ms,击败 100.00% 使用 C# 的用户
  • 内存:36.51 MB,击败 66.67% 使用 C# 的用户

这篇关于LeetCode 面试题 16.18. 模式匹配的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/360729

相关文章

哈希leetcode-1

目录 1前言 2.例题  2.1两数之和 2.2判断是否互为字符重排 2.3存在重复元素1 2.4存在重复元素2 2.5字母异位词分组 1前言 哈希表主要是适合于快速查找某个元素(O(1)) 当我们要频繁的查找某个元素,第一哈希表O(1),第二,二分O(log n) 一般可以分为语言自带的容器哈希和用数组模拟的简易哈希。 最简单的比如数组模拟字符存储,只要开26个c

荣耀嵌入式面试题及参考答案

在项目中是否有使用过实时操作系统? 在我参与的项目中,有使用过实时操作系统。实时操作系统(RTOS)在对时间要求严格的应用场景中具有重要作用。我曾参与的一个工业自动化控制项目就采用了实时操作系统。在这个项目中,需要对多个传感器的数据进行实时采集和处理,并根据采集到的数据及时控制执行机构的动作。实时操作系统能够提供确定性的响应时间,确保关键任务在规定的时间内完成。 使用实时操作系统的

leetcode-24Swap Nodes in Pairs

带头结点。 /*** Definition for singly-linked list.* public class ListNode {* int val;* ListNode next;* ListNode(int x) { val = x; }* }*/public class Solution {public ListNode swapPairs(L

leetcode-23Merge k Sorted Lists

带头结点。 /*** Definition for singly-linked list.* public class ListNode {* int val;* ListNode next;* ListNode(int x) { val = x; }* }*/public class Solution {public ListNode mergeKLists

C++ | Leetcode C++题解之第393题UTF-8编码验证

题目: 题解: class Solution {public:static const int MASK1 = 1 << 7;static const int MASK2 = (1 << 7) + (1 << 6);bool isValid(int num) {return (num & MASK2) == MASK1;}int getBytes(int num) {if ((num &

一些其他面试题

阿里二面:那你来说说定时任务?单机、分布式、调度框架下的定时任务实现是怎么完成的?懵了。。_哔哩哔哩_bilibili 1.定时算法 累加,第二层每一个格子是第一层的总时间400 ms= 20 * 20ms 2.MQ消息丢失 阿里二面:高并发场景下引进消息队列有什么问题?如何保证消息只被消费一次?真是捏了一把汗。。_哔哩哔哩_bilibili 发送消息失败

【每日一题】LeetCode 2181.合并零之间的节点(链表、模拟)

【每日一题】LeetCode 2181.合并零之间的节点(链表、模拟) 题目描述 给定一个链表,链表中的每个节点代表一个整数。链表中的整数由 0 分隔开,表示不同的区间。链表的开始和结束节点的值都为 0。任务是将每两个相邻的 0 之间的所有节点合并成一个节点,新节点的值为原区间内所有节点值的和。合并后,需要移除所有的 0,并返回修改后的链表头节点。 思路分析 初始化:创建一个虚拟头节点

C语言 | Leetcode C语言题解之第393题UTF-8编码验证

题目: 题解: static const int MASK1 = 1 << 7;static const int MASK2 = (1 << 7) + (1 << 6);bool isValid(int num) {return (num & MASK2) == MASK1;}int getBytes(int num) {if ((num & MASK1) == 0) {return

zookeeper相关面试题

zk的数据同步原理?zk的集群会出现脑裂的问题吗?zk的watch机制实现原理?zk是如何保证一致性的?zk的快速选举leader原理?zk的典型应用场景zk中一个客户端修改了数据之后,其他客户端能够马上获取到最新的数据吗?zk对事物的支持? 1. zk的数据同步原理? zk的数据同步过程中,通过以下三个参数来选择对应的数据同步方式 peerLastZxid:Learner服务器(Follo

java常用面试题-基础知识分享

什么是Java? Java是一种高级编程语言,旨在提供跨平台的解决方案。它是一种面向对象的语言,具有简单、结构化、可移植、可靠、安全等特点。 Java的主要特点是什么? Java的主要特点包括: 简单性:Java的语法相对简单,易于学习和使用。面向对象:Java是一种完全面向对象的语言,支持封装、继承和多态。跨平台性:Java的程序可以在不同的操作系统上运行,称为"Write once,