当前位置: 首页 > wzjs >正文

上海传媒公司ceoseo外链工具软件

上海传媒公司ceo,seo外链工具软件,外贸网站建设哪家比较好,专业做网站建设的Leetcode 316: 去除重复字母 是一道考察贪心思想与栈在字符串操作中使用的经典题目。该题的目标是让结果字符串既是 字典序最小,又不包含重复字符,而且在原字符串中字符的相对顺序要保持不变。下面列举几种解法,并分析其实现方式和时间复杂度…

Leetcode 316: 去除重复字母 是一道考察贪心思想与栈在字符串操作中使用的经典题目。该题的目标是让结果字符串既是 字典序最小,又不包含重复字符,而且在原字符串中字符的相对顺序要保持不变。下面列举几种解法,并分析其实现方式和时间复杂度。


题目描述

输入:给定一个字符串 s,其中包含小写字母。
输出:返回 s 的一个子序列,该子序列需要满足以下条件:

  1. 包含原字符串的所有字符(去重后),每个字符只出现一次。
  2. 所有字符的相对顺序与原字符串中一致。
  3. 输出字典序最小的结果。

示例输入输出:

输入:s = "bcabc"
输出:"abc"输入:s = "cbacdcbc"
输出:"acdb"

解法 1:贪心 + 单调栈

思路

  1. 从后往前构造结果:
    • 使用一个栈模拟最终结果字符串。
    • 按顺序遍历字符串,将字符加入栈中时确保:
      • 每个字符只出现一次;
      • 字典序尽可能小。
  2. 计算当前字符是否可以移除
    • 一个字符可以从栈中移除,如果移除它不会导致后续字符串无法构成完整的唯一字符集合。
    • 使用 lastIndex[] 数组记录每个字符最后出现的索引位置,判断是否还有后续机会添加该字符。
  3. 辅助判断当前字符是否已在结果中
    • 用一个 inStack 记录栈中是否已有某个字符,避免重复。
实现步骤
  • 遍历过程:
    • 如果当前字符已在栈中,跳过。
    • 如果当前字符比栈顶字符字典序小,并且栈顶字符在后面还会出现,则弹出栈顶字符,使得当前字符能够被加入栈中。
  • 最终栈中存储了构造好的结果。

代码模板

class Solution {public String removeDuplicateLetters(String s) {int[] lastIndex = new int[26]; // 记录字符最后出现的位置boolean[] inStack = new boolean[26]; // 标记字符是否在栈中// 记录每个字符最后出现的位置for (int i = 0; i < s.length(); i++) {lastIndex[s.charAt(i) - 'a'] = i;}Deque<Character> stack = new ArrayDeque<>(); // 用双端队列模拟单调栈for (int i = 0; i < s.length(); i++) {char c = s.charAt(i);// 如果当前字符已经在栈中,跳过if (inStack[c - 'a']) {continue;}// 当栈顶元素的字典序大于当前字符,并且栈顶元素在后面还会出现,可以弹出栈顶元素while (!stack.isEmpty() && stack.peekLast() > c && lastIndex[stack.peekLast() - 'a'] > i) {char removed = stack.pollLast();inStack[removed - 'a'] = false; // 标记移除}// 将当前字符加入栈中stack.offerLast(c);inStack[c - 'a'] = true; // 标记加入}// 将栈中字符拼接成结果字符串StringBuilder result = new StringBuilder();for (char c : stack) {result.append(c);}return result.toString();}
}

复杂度分析

  • 时间复杂度
    • 遍历字符串一次 O(n);
    • 栈的入栈与出栈操作总时间复杂度为 O(n);
    • 因此,总体复杂度为 O(n)
  • 空间复杂度
    • 栈、数组 lastIndexinStack,额外空间为 O(26),即 O(1)(因为最多只有 26 个小写字母)。

适用场景

  • 题目明确要求字典序最小,并且需要在保证原字符顺序基础上去重时,这种方法最优。

解法 2:贪心递归法

思路

  1. 贪心核心
    • 整个问题的目标是找到字典序最小的合法子序列,可以利用递归分治思想逐步找到当前字典序最小的字符。
    • 每次递归,选择剩余字符串中字典序最小的字符作为当前分割点,然后递归处理剩余部分。
  2. 递归具体实现
    • 首先遍历字符串,找到在当前范围内未重复字符的最小字符。
    • 将其作为结果的第一个字符,并递归寻找剩余部分的结果。

代码模板

class Solution {public String removeDuplicateLetters(String s) {if (s.isEmpty()) {return "";}// 统计每个字符出现的次数int[] count = new int[26];for (char c : s.toCharArray()) {count[c - 'a']++;}// 找到字典序最小的字符作为当前结果的第一个字符char minChar = 'z' + 1;int minIndex = -1;for (int i = 0; i < s.length(); i++) {char c = s.charAt(i);if (c < minChar) {minChar = c;minIndex = i;}count[c - 'a']--;if (count[c - 'a'] == 0) {break; // 找到第一个未重复的字符,停止。}}// 递归处理剩余部分,去掉 minChar 后面的所有 minCharString remaining = s.substring(minIndex + 1).replaceAll(String.valueOf(minChar), "");return minChar + removeDuplicateLetters(remaining);}
}

复杂度分析

  • 时间复杂度
    • 每次递归遍历一次字符串,最坏情况下需要递归 26 次。
    • 总时间复杂度为 O(26 * n) = O(n)(近似线性)。
  • 空间复杂度
    • 由于递归调用堆栈,空间复杂度为 O(26) = O(1)。

适用场景

  • 对于数据规模小的输入(如只包含少量字符,或字符串长度较小),递归法更易于理解。
  • 如果题目允许更高复杂度约束,这种形式可用于竞赛或面试时快速实现。

解法 3:基于贪心的双索引法

思路

这是单调栈法的另一种实现形式:

  1. 从左到右维护当前最优字符选择
    • 预先统计每个字符在剩余部分的最远位置。
    • 遍历时构造结果,始终从当前子串范围内优先选择字典序最小且未重复的字符。
  2. 动态规划全局最优解。

快速 AC 策略

  • 优先选择单调栈法(解法 1):
    • 时间复杂度 O(n),实现简单,能快速通过。
    • 注意使用 boolean[]int[] 做标记,减少重复计算。
  • 在面试中优先写递归法(解法 2):
    • 简单易实现,能快速写出功能完备的代码,但对长字符串性能可能不如栈法。

无论比赛还是面试,熟练掌握单调栈模板均可快速 AC!

http://www.dtcms.com/wzjs/12137.html

相关文章:

  • 做社群的网站有哪些企业网站模板免费
  • 响应式网站常用宽度网站seo策划方案实例
  • 公司要建设网站需要那些程序新闻发稿平台
  • 建设网站选什么地方的主机怎么推广app让人去下载
  • 襄阳商城网站建设百家号自媒体平台注册
  • 江苏连云港网站建设公司营销案例最新
  • 专业做俄语网站建设网站建设制作模板
  • 宝安网站建设公司企业网站推广建议
  • 卖网站赚钱企业网站运营推广
  • 泊头在哪做网站比较好网红推广
  • 设置html编辑器seo课程排行榜
  • 萌导航seo的基本步骤包括哪些
  • wordpress升级教程宁波seo外包方案
  • wordpress 证书seo服务深圳
  • 建设网站的主要任务微信公众号推广
  • 在线商城网站制作惠州seo网络推广
  • 荣成市住房和城乡建设局网站做任务赚佣金一单10块
  • 中国域名根服务器深圳优化公司找高粱seo服务
  • 济南网站自然优化b站推广引流最佳方法
  • 国外优秀设计网站连云港seo优化公司
  • 3维网站制作技术网络兼职平台
  • 建大仁科公司网站产品推广计划怎么写
  • 中国家装家居网seo点石论坛
  • wordpress gravatar关键词seo价格
  • 建设工程合同索赔的原因有哪些seo免费诊断
  • 国内男女直接做的视频网站百度seo关键词优化
  • 手机如何免费做网站app拉新一手渠道商
  • 做网站需要留什么条件百度首页 百度一下
  • 深圳网站关键字优化小红书怎么推广引流
  • wordpress百度收录查阅南宁百度seo排名优化软件