news 2026/10/28 8:07:04

LeetCode 942题解析:双指针实现DI字符串匹配

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
LeetCode 942题解析:双指针实现DI字符串匹配

1. 题目解析:理解DI字符串匹配的核心逻辑

今天我们来拆解LeetCode 942题"DI String Match"(增减字符串匹配),这是一道看似简单但蕴含精妙设计思想的字符串处理题目。给定一个仅包含'I'(Increase)和'D'(Decrease)的字符串S,我们需要返回一个排列perm,使得对于所有i(0 ≤ i < S.length)都满足:

  • 如果S[i] == 'I',那么perm[i] < perm[i+1]
  • 如果S[i] == 'D',那么perm[i] > perm[i+1]

举个例子,当输入S = "IDID"时,一个有效的输出可以是[0,4,1,3,2]。我们来验证一下:

  • 第一个字符'I':0 < 4 ✔
  • 第二个字符'D':4 > 1 ✔
  • 第三个字符'I':1 < 3 ✔
  • 第四个字符'D':3 > 2 ✔

1.1 问题背后的数学原理

这道题本质上是在构建一个满足特定增减条件的排列。关键在于理解:

  1. 排列perm的长度总是比输入字符串S长1(因为需要n+1个数字来表示n个比较关系)
  2. 使用的数字必须是0到n的连续整数(n为字符串长度),且不能重复
  3. 需要巧妙利用数字的范围来满足连续的增减要求

2. 解题思路与算法设计

2.1 贪心算法:双指针的经典应用

最优雅的解决方案是采用贪心算法配合双指针技巧。具体思路如下:

  1. 初始化两个指针:low=0,high=n(字符串长度)
  2. 准备一个空数组result用于存储结果
  3. 遍历字符串S的每个字符:
    • 遇到'I':将当前low值放入结果,low++
    • 遇到'D':将当前high值放入结果,high--
  4. 最后将剩下的low(或high,此时两者相等)放入结果
def diStringMatch(S): low, high = 0, len(S) result = [] for c in S: if c == 'I': result.append(low) low += 1 else: result.append(high) high -= 1 result.append(low) # 此时low == high return result

2.2 为什么这个算法有效?

这个算法的精妙之处在于:

  • 遇到'I'时,我们总是选择当前可用的最小数字,确保后面无论选什么数字都能满足递增
  • 遇到'D'时,我们总是选择当前可用的最大数字,确保后面无论选什么数字都能满足递减
  • 最后剩下的数字一定是low和high相遇的值,放在末尾不会影响前面的关系

3. 复杂度分析与优化空间

3.1 时间复杂度

该算法只需要一次线性遍历:

  • 时间复杂度:O(n),其中n是字符串长度
  • 空间复杂度:O(1)额外空间(不考虑输出结果占用的空间)

3.2 可能的变种与扩展

  1. 如果要求返回所有可能的有效排列而不仅是一个,问题就变成了回溯算法问题
  2. 如果数字范围不是0-n而是任意n+1个不同数字,算法依然适用
  3. 可以扩展为三维情况,比如同时处理'I'、'D'和'E'(Equal)的情况

4. 实际编码中的注意事项

4.1 边界条件处理

在实现时需要注意:

  • 空字符串输入:应返回[0]
  • 全'I'字符串:应该是递增序列[0,1,...,n]
  • 全'D'字符串:应该是递减序列[n,n-1,...,0]

4.2 语言特性利用

不同语言可以优化实现方式:

  • 在Python中,使用列表的append操作效率很高
  • 在C++中,可以预先分配好vector的大小避免动态扩容
  • 在Java中,使用ArrayList同样需要注意初始容量

5. 测试用例设计技巧

好的测试用例应该包含:

  1. 常规案例:"IDID" → [0,4,1,3,2]
  2. 极端案例:"III" → [0,1,2,3]
  3. 另一个极端:"DDD" → [3,2,1,0]
  4. 混合案例:"DIDI" → [4,0,3,1,2]
  5. 单字符案例:"D" → [1,0]

6. 与相似题目的对比

这道题与以下LeetCode题目有相似之处:

    1. Remove Duplicate Letters(同样需要处理字符顺序)
    1. Remove K Digits(贪心算法的应用)
    1. Max Chunks To Make Sorted II(处理排列顺序)

但942题的独特之处在于它要求构造而非验证或修改排列,这要求我们对问题有更深入的理解。

7. 实际应用场景

虽然看起来像纯数学问题,但这种模式匹配在实际中有广泛应用:

  1. 基因序列分析中特定模式的识别
  2. 用户行为模式的升降趋势分析
  3. 股票价格波动模式的匹配
  4. 游戏AI中对手行为模式的预测

8. 刷题建议与学习路径

对于想系统学习这类问题的同学,建议:

  1. 先掌握基本的贪心算法概念
  2. 练习双指针技巧(如Two Sum问题)
  3. 理解排列组合的基本性质
  4. 从简单构造类问题入手(如本题)
  5. 逐步过渡到更复杂的模式匹配问题

我个人在刷这道题时的体会是:看似简单的题目往往蕴含着精妙的算法思想。这道题教会我们,有时候不需要复杂的结构,用两个指针和基本的贪心策略就能优雅地解决问题。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/28 8:06:40

Qt飞机大战实战项目:CMake构建、QGraphicsView分层与delta time平滑移动

简介&#xff1a;本资源是一份基于Qt框架开发的完整‘飞机大战’游戏源码工程&#xff0c;面向C与Qt初学者及游戏开发入门者&#xff0c;帮助其掌握跨平台GUI应用开发、2D图形渲染、事件驱动逻辑设计等核心实践能力。压缩包共223个文件&#xff0c;包含60张PNG游戏素材图、105个…

作者头像 李华
网站建设 2026/10/28 8:06:21

容器配置持久化与CI/CD优化实战指南

1. 容器重启后配置丢失的行业痛点上周帮朋友公司排查一个线上事故&#xff0c;他们的订单服务在容器重启后所有配置全部丢失&#xff0c;导致整个支付链路瘫痪了47分钟。这绝不是个例——根据CNCF 2023年度调查报告&#xff0c;87%的中小企业在容器化转型过程中都遇到过类似问题…

作者头像 李华
网站建设 2026/10/28 8:05:55

Rust标准库vs手写汇编:17倍性能神话背后的工程真相

1. 这不是性能神话&#xff0c;而是一场被误读的工程实验“DHH 用大模型把 Rust 手撕成汇编&#xff1a;性能狂飙 17 倍背后的工程倒退”——这个标题像一记重锤砸在程序员社区的舆论场上。它精准踩中了当下最敏感的三根神经&#xff1a;DHH&#xff08;Ruby on Rails 创始人&a…

作者头像 李华
网站建设 2026/10/28 8:05:38

蜻蜓优化算法与BP神经网络融合的分类模型实践

1. 项目概述&#xff1a;蜻蜓优化算法与BP神经网络的融合应用这个项目实现了一种创新的机器学习建模方法——将蜻蜓优化算法(DA)与BP神经网络相结合&#xff0c;用于解决分类问题。我在实际工业项目中多次应用这种组合&#xff0c;发现它特别适合中小规模数据集的分类任务&…

作者头像 李华
网站建设 2026/10/28 8:05:00

思源宋体CN:开源中文字体的排版基建实践指南

1. 项目概述&#xff1a;为什么“思源宋体CN”不是又一个字体下载链接&#xff0c;而是值得你花15分钟认真读完的排版基建资源 最近在帮某高校实验室做学术论文模板优化时&#xff0c;团队里三位不同专业背景的同事——一位偏爱LaTeX的物理系博士、一位日常用InDesign做期刊封…

作者头像 李华
网站建设 2026/10/28 8:04:46

RStudio升级后表格输出异常的解决方案

1. RStudio升级后表格输出异常问题解析最近在RStudio 2023.12.0版本升级后&#xff0c;不少用户反馈在控制台输出数据框时出现了格式异常问题。作为一名长期使用RStudio进行数据分析的从业者&#xff0c;我在实际项目中遇到了同样的情况&#xff1a;原本整齐排列的表格输出变成…

作者头像 李华