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

【力扣】2434.使用机器人打印字典序最小的字符串

1、题目描述:

在这里插入图片描述

2、测试用例:

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

3、解题思路

  • 每次删除字符串s的第一个字符,可以将s看做队列,每次从头部出。
  • 在t的尾端插入或删除,可以将t看做栈
  • 栈顶元素出栈条件:①比即将入栈的元素小并且比s中剩下的还没有入栈的所有字符都小②s中已经没有字符
class Solution {public String robotWithString(String s) {//s从头开始遍历//t从尾部开始StringBuilder s1 = new StringBuilder(s);Stack<Character> t = new Stack<>();StringBuilder m = new StringBuilder();int i = 0;boolean isDoen = false; //用于判断第一个“最小的字符”是否入栈//找出最小字符char minChar = (char) s.chars().min().orElseThrow(()-> new RuntimeException("No minimum character found.")) ;while (i <  s.length()){char c = s.charAt(i);if(s.charAt(i) == minChar){isDoen = true;//在遇到第一个"最小字符"之前,都不入栈!!!m.append(s.charAt(i));s1.deleteCharAt(0);i++;}else {char minChar1 = (char) s1.chars().min().orElseThrow(()-> new RuntimeException("No minimum character found."));//将t中比s尾部小的元素弹出加在m末尾,直到第一个比s.char(i)大的字符while (!t.isEmpty() && t.peek() <= c && isDoen && t.peek() <= minChar1){//在出栈之前还应判断剩下的元素是否还有比栈顶小的元素m.append(t.pop());}//栈顶元素大于等于c,将c入栈t.push(c);s1.deleteCharAt(0);i++;}}//将t中剩余元素全部出栈while (!t.isEmpty()){m.append(t.pop());}return m.toString();}
}

在这里插入图片描述

4、效率改进

public String robotWithString(String s) {//s从头开始遍历//t从尾部开始int n = s.length();String s1 = s;Stack<Character> t = new Stack<>();StringBuilder m = new StringBuilder();//int i = 0;//boolean isDoen = false; //用于判断第一个“最小的字符”是否入栈//找出最小字符,统计每个位置之后(包括当前位置)的最小字符个数//char minChar = (char) s.chars().min().orElseThrow(()-> new RuntimeException("No minimum character found.")) ;//统计每个位置之后(包含当前)最小的字符char[] minFromRight = new char[n];minFromRight[n - 1] = s.charAt(n - 1);for (int i = n - 2; i >= 0; i--) {minFromRight[i] = (char) Math.min(s.charAt(i), minFromRight[i + 1]);}for (int i = 0; i < n; i++){char c = s.charAt(i);while (!t.isEmpty() && t.peek() <= c && t.peek() <= minFromRight[i]){m.append(t.pop());}t.push(c);}//        while (i <  s.length()){
//            char c = s.charAt(i);
//            if(s.charAt(i) == minChar){
//                isDoen = true;
//                //在遇到第一个"最小字符"之前,都不入栈!!!
//                m.append(s.charAt(i));
//                s1= s1.substring(1);
//                i++;
//            }else {
//                char minChar1 = (char) s1.chars().min().orElseThrow(()-> new RuntimeException("No minimum character found."));
//                //将t中比s尾部小的元素弹出加在m末尾,直到第一个比s.char(i)大的字符
//                while (!t.isEmpty() && t.peek() <= c && isDoen && t.peek() <= minChar1){
//                    //在出栈之前还应判断剩下的元素是否还有比栈顶小的元素
//                    m.append(t.pop());
//                }
//                //栈顶元素大于等于c,将c入栈
//                t.push(c);
//                s1= s1.substring(1);;
//                i++;
//            }
//        }//将t中剩余元素全部出栈while (!t.isEmpty()){m.append(t.pop());}return m.toString();}

4.1 改进点1

不断创建StringBuilder 并调用 deleteCharAt(0)从字符串头部删除字符,这种方式效率较低,因为每次删除操作都需要移动数组元素,时间复杂度为 O(n²)

✅ 优化目标

  • 避免频繁使用 deleteCharAt(0)。
  • 使用索引遍历原字符串,避免修改原始字符串副本。
  • 提高整体时间复杂度至 O(n)。

4.2 改进点2

多次调用 s1.chars().min() 导致重复扫描。
✅ 优化目标:改进使用该函数的方式,预处理一个 minFromRight 数组,保存从当前位置开始的最小字符

在这里插入图片描述
在这里插入图片描述

5、官方答案

在这里插入图片描述

class Solution {public String robotWithString(String s) {int[] cnt = new int[26];for (char c : s.toCharArray()) {cnt[c - 'a']++;}Stack<Character> stack = new Stack<>();StringBuilder res = new StringBuilder();char minCharacter = 'a';for (char c : s.toCharArray()) {stack.push(c);cnt[c - 'a']--;while (minCharacter != 'z' && cnt[minCharacter - 'a'] == 0) {minCharacter++;}while (!stack.isEmpty() && stack.peek() <= minCharacter) {res.append(stack.pop());}}return res.toString();}
}

文章转载自:

http://A4v23LTb.xkjrs.cn
http://HRBOmEVg.xkjrs.cn
http://2gJLHSTK.xkjrs.cn
http://pup3Tym6.xkjrs.cn
http://bdIu7eXz.xkjrs.cn
http://t3XefG4E.xkjrs.cn
http://aRgt141L.xkjrs.cn
http://5Cvk3rFU.xkjrs.cn
http://Jsi41kCy.xkjrs.cn
http://dZ6RDGNs.xkjrs.cn
http://WySPEzUU.xkjrs.cn
http://7kPciMED.xkjrs.cn
http://2RSVJ1Mn.xkjrs.cn
http://AE0d20SJ.xkjrs.cn
http://MqzSIy6G.xkjrs.cn
http://r9pVYRAC.xkjrs.cn
http://qf30q0lL.xkjrs.cn
http://tugG8jX5.xkjrs.cn
http://E6PYEpT0.xkjrs.cn
http://31KWbacG.xkjrs.cn
http://upLgF0qE.xkjrs.cn
http://OpGV1n8n.xkjrs.cn
http://eH3ghBhC.xkjrs.cn
http://ONo1eoOH.xkjrs.cn
http://Y49O0NZM.xkjrs.cn
http://Y21RvaT0.xkjrs.cn
http://i2Wx7fhA.xkjrs.cn
http://nghrsQQ7.xkjrs.cn
http://lkM00Hi3.xkjrs.cn
http://XUWcDw1R.xkjrs.cn
http://www.dtcms.com/a/236397.html

相关文章:

  • 线程池封装
  • go-zero微服务入门案例
  • ADVANTEST R3764 66 R3765 67爱德万测试networki connection programming网络程序设计手册
  • Mac 安装git心路历程(心累版)
  • 电力系统时间同步系统之三
  • Android USB 通信开发
  • Python异步编程-协程
  • JMeter-SSE响应数据自动化2.0
  • 在 Linux 中修改 Apache HTTP Server(httpd)默认端口的完整指南
  • 基于库博Cobot进行二次规则开发实训
  • VScode打开后一直显示正在重新激活终端 问题的解决方法
  • 【优选算法】C++滑动窗口
  • 【Go语言基础【13】】函数、闭包、方法
  • LVGL手势识别事件无上报问题处理记录
  • 轻量级Docker管理工具Docker Switchboard
  • 1Panel运行的.net程序无法读取系统字体(因为使用了docker)
  • Docker基础(一)
  • 使用 Python + SQLAlchemy 创建知识库数据库(SQLite)—— 构建本地知识库系统的基础《一》
  • 牛客练习赛140
  • 算法-多条件排序
  • Docker构建Vite项目内存溢出:从Heap Limit报错到完美解决的剖析
  • 【win | docker开启远程配置】使用 SSH 隧道访问 Docker的前操作
  • Docker、Wsl 打包迁移环境
  • JavaScript ES6 解构:优雅提取数据的艺术
  • ⚡️ Linux Docker 基本命令参数详解
  • LINUX67 FTP 3客户服务系统;FTP 上传、下载测试调试
  • 基于vscode,idea,java,html,css,vue,echart,maven,springboot,mysql数据库,在线考试系统
  • 多线程中的泛型应用深度解析:类型安全与并发编程的完美融合
  • CADisplayLink、NSTimer、GCD定时器
  • Opencv查找图形形状的重要API讲解