数据结构与算法:去除重复字母

2023-11-01

给你一个仅包含小写字母的字符串,请你去除字符串中重复的字母,使得每个字母只出现一次。需保证返回结果的字典序最小(要求不能打乱其他字符的相对位置)。

示例 1:

输入: "bcabc"
输出: "abc"

示例 2:

输入: "cbacdcbc"
输出: "acdb"

解题思路:

  1. 判断字符串可能出现的特殊情况

  2. 用一个record数组记录字符串中字母出现的次数;

  3. 申请一个字符串栈stack用来存储去除重复字母的结果,并利用它的特性帮助我们找到正确的次序;

  4. 遍历字符串s

  5. 从0~top,遍历stack 判断当前字符s[i]是否存在于栈stack中,如果当前字符是否存在于栈的定义一个falg 标记isExist, 0表示不存在, 1表示存在

  6. 如果isExist存在,record[s[i]]位置上的出现次数减一,并继续遍历下一个字符; 表示当前的stack已经有这个字符没有必要处理这个重复的字母;

  7. 如果isExist不存在,则

    如果不存在,则需要循环一个找到一个正确的位置,然后在存储起来;

    如果不存在,跳过栈中所有比当前字符大、且后面还会出现的元素,然后将当前字符入栈

    top > -1表示栈非空

    stack[top] > s[i]表示栈顶元素比当前元素大

    record[stack[top]] > 1表示后面还会出现

    通过一个while循环找到将栈中位置错误的数据,出栈. 找当前合适的位置,则结束while循环;

    找到合理的位置后,则将当前字符s[i]入栈;

8.直到遍历完所有字符后,则为字符串栈stack 添加一个结束符'\0',并返回当前字符串首地址;

代码实现:

char *removeDuplicateLetters(char *s) {
    /*
     ① 特殊情况处理,s为空,或者字符串长度为0;
     ② 特殊情况,s的长度为1,则没有必要后续的处理,则直接返回s;
     */
    if (s == NULL || strlen(s) == 0) {
        return "";
    }
    if (strlen(s) == 1) {
        return s;
    }
    //record数组,用来记录字符串s中每个字符未来会出现的次数;
    char record[26] = {0};
    int len = (int)strlen(s);
    //申请一个字符串stack;(用栈的特性来进行stack字符串的数据进出)
    char* stack = (char*)malloc(len * 2 * sizeof(char));
    //memset(void *s, int ch, size_t n) 将stack len*2*sizeof(char)长度范围的空间填充0;
    memset(stack, 0, len * 2 * sizeof(char));
    //stack 栈顶赋初值为-1;
    int top = -1;
    //1.统计每个字符的频次
    //例如bcabc  recod[26] = {1,2,2};
    int i;
    for (i = 0; i < len; i++) {
        record[s[i] - 'a']++;
    }
    //2.遍历s,入栈
    for (i = 0; i < len; i++) {
        //isExist 标记, 判断当前字符是否存在栈中;
        int isExist = 0;
        //①从0~top,遍历stack 判断当前字符s[i]是否存在于栈stack中
        //如果当前字符是否存在于栈的flag, 0表示不存在, 1表示存在
        //top指向栈顶(也是执行stack字符串最后一个字符的位置,表示字符串长度上限)
        for (int j = 0; j <= top; j++) {
            if (s[i] == stack[j]) {
                isExist = 1;
                break;
            }
        }
        //② 如果存在,record[s[i]]位置上的出现次数减一,并继续遍历下一个字符
        //③ 如果不存在,则需要循环一个正确位置存储起来;
        //④ 如果不存在,跳过栈中所有比当前字符大、且后面还会出现的元素,然后将当前字符入栈
        // top > -1表示栈非空
        //stack[top] > s[i]表示栈顶元素比当前元素大
        //record[stack[top]] > 1表示后面还会出现
        //例如b,c因为不符合以下条件会直接入栈.stack[] = "bc",但是当当前字符是"a"时,由于bcabc,a不应该是在stack的顺序是"bca",所以要把位置不符合的字符出栈;
        //top = 1,stack[top] > s[i], c>a; 并且stack[top] 在之后还会重复的出现,所以我们可以安心的把stack中的栈顶C出栈,所以stack[]="b",top减一后等于0; 同时也需要将record[c]出现次数减一;
        //top=0,stack[top]>s[i],b>a,并且stack[top] 在之后还会出现,所以stack把栈顶b出栈,所以此时栈stack[]="",top减一后等于-1, 此时栈中位置不正确的字符都已经移除;
        if (isExist == 1) {
            record[s[i] - 'a']--;
        } else {
            while (top > -1 && stack[top] > s[i] && record[stack[top] - 'a'] > 1) {
                // 跳过该元素,频次要减一
                record[stack[top] - 'a']--;
                // 出栈
                top--;
            }
            //⑤ 结束while 循环;
            //循环结束的3种可能性:(1)移动到栈底(top == -1) ; (2)栈顶元素小于当前元素(stack[top] <= s[i]) (3)栈顶元素后面不出现(record[stack[top]] == 1)
            // 此时,当前元素要插入到top的下一个位置
            // top往上移动1位
            top++;
            // 入栈
            stack[top] = s[i];
        }
    }
    //结束栈顶添加字符结束符
    stack[++top] = '\0';
    return stack;
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

数据结构与算法:去除重复字母 的相关文章

随机推荐

  • 【Python】ftfy 包的理解和使用

    一 介绍 ftfy 是一个用于修复和清理 Unicode 文本的 Python 软件包 它的全称是 fixes text for you 意思是它可以自动检测和纠正常见的 Unicode 文本问题 Unicode 是一种字符编码标准 用于表
  • 样式兼容性的问题。

    这里的所属公司 公司名有时候长 有时候短 要考虑长度问题 高度要写活 让他换行 使用pading 去控制高度
  • 如何快速实现Modbus RTU和Modbus TCP协议转换?

    Modbus协议是工业现场串口设备之间常用的连接方式 其中最常见的就是Modbus RTU和Modbus TCP两种 许多工厂需要将现场各种不同型号设备的数据都能够通过一个上位机软件或者设备触摸屏整合起来监控管理 目前上位机大部分用的Mod
  • element table表格滚动条

    项目场景 table表头过长需要添加滚动条 问题描述 原因 一般情况表头过长 会自动出现滚动条 但是在大型项目开发过程中 有的情况会在总的母版文件中设置禁用滚动条 所以当需要滚动条时 找不到 解决方案 添加css样式 display blo
  • VS中写QT的软件如何输出安装包exe文件

    1 选择Release 和对应的平台 我这里是X64的 2 点击本地Windows调试器 在项目文件当中找到release中找到自己的exe文件 3 复制exe文件到新的文件夹 然后打开对应平台的命令行 我这里是64位的所以要选VS 201
  • 奖励模型Reward Model如何训练?

    image png 如上图所示 ChatGPT 并不是直接让人工去标注每一句话的真实得分是多少 尽管模型最终要预测的就是每句话的得分 而是让人去对 4 句话按照好坏程度进行 排序 通过这个 排序序列 模型将会学习如何为每一个句子进行打分 用
  • Fabric模块功能介绍(一)

    主要有5个模块 分别是peer orderer cryptogen configtxgen configtxlator 模块 功能 peer 主节点模块 负责存储区块链数据 运行维护链码 orderer 交易打包 排序模块 cryptoge
  • python爬虫+数据分析(MySQL)+可视化(echarts,词云)bootstrap前端界面展示

    以下需要一些html css mysql python bootstrap基础 python爬虫 数据分析 准备 在pycharm python的开发环境 需下载 该项目下下载相应需要的包 代码有 import re from bs4 im
  • 在网页中嵌入天气信息

    方式1 在后台通过webservice天气接口信息 比较好自定义和灵活设置但是代码量和复杂度都比较大 方式2 使用js库调用 原始漂亮 但是局限性比较大 方式3 使用一些平台开放的代码 可以直接使用 样式多样 分享 http weather
  • 数据库驱动mysql-connector-java-5.1.46-bin.jar下载及在idea中导入该jar包

    数据库驱动mysql connector java 5 1 46 bin jar下载及在idea中导入该jar包 参考资料 https www cnblogs com bj171104 p 12705567 html https blog
  • Object.setPrototypeOf 与 Object.create() 的区别

    在讲之前 我们先回顾下创建对象的几种方式 并且Object new Object 和 Object create 的区别 字面量方式创建对象 let person name nick 构造函数式创建对象 let person new Obj
  • 【yarn】yarn LocalizedResource 状态机正常执行流程

    1 概述 上一篇文章 Yarn Yarn Service端如何处理客户端提交的任务 在上一篇文章中 我们知道服务器接收到客户端提交的任务之后 会启动多个状态机进行联合操作 最终来解决任务提交之后的全流程 多个状态机合作完成任务 然后我们看了
  • 移植Opencv 1.10到WINCE/WM

    本文来自http blog csdn net hellogv 引用必须注明出处 如何把opencv1 10移植到wince WM 因为如果懂得裁剪opencv 那么就可以在更多设备 PC 手机 开发板 上玩更多更好玩的算法 因此 移植和裁剪
  • Unity小技巧之发射弓箭,弓箭朝向问题

    很多初学的小伙伴 遇到一个问题就是在实例化弓箭或其他物体时 弓箭的朝向会随着人物的转向而改变 例如这样 错误演示 那如何解决呢 只需要将箭的正前方作为添加力的方向代码如下所示 GameObject game Instantiate Reso
  • Java代码一键生成神器,支持Jpa/Mybatis/plus多种ORM框架,亲测好用

    2023年08月11日重磅升级 点击访问 Java代码生成神器 自动化生成Java实体类 代码 增删改查功能 今天给大家介绍一款绝对让你惊艳的Java代码生成器 这款神器可以支持输入json sql和Java实体类 自动识别语言类型 并生成
  • 关于对象能不能直接访问私有成员的问题

    对象能不能直接访问私有成员 分两种情况 如果是在类 包括友元类 内定义的对象 可以 在类外 不行 举个简单的例子 include
  • 使用maven的插件(tomcat)启动web工程方法

    前言 现在很多公司的web项目都是使用SpringBoot来搭建的 但是有一个国产开源框架JFinal 快速开发框架 使用的人数慢慢也变多了 对于集中式开发的小项目 使用JFinal框架很快捷 真的 基于JFinal框架 有一个EOVA系统
  • 旋转彩色三叶草

  • Android面试汇总-Android内存和性能优化面试

    一 app优化 app优化 工具 Hierarchy Viewer 分析布局 工具 TraceView 测试分析耗时的 App启动优化 布局优化 响应优化 内存优化 电池使用优化 网络优化 App启动优化 针对冷启动 App启动的方式有三种
  • 数据结构与算法:去除重复字母

    给你一个仅包含小写字母的字符串 请你去除字符串中重复的字母 使得每个字母只出现一次 需保证返回结果的字典序最小 要求不能打乱其他字符的相对位置 示例 1 输入 bcabc 输出 abc 示例 2 输入 cbacdcbc 输出 acdb 解题