美文网首页
数据结构与算法-练习2

数据结构与算法-练习2

作者: 卡布奇诺_95d2 | 来源:发表于2020-04-27 17:25 被阅读0次

一、字符编码问题

题目: 字符串编码,编码规则为: k[encoded_string],表示其中方括号内部的 encoded_string 正好重复 k 次。注意 k 保证为正整数。你可以认为输入字符串总是有效的;输入字符串中没有额外的空格,且输入的方括号总是符合格式要求的。此外,你可以认为原始数据不包含数字,所有的数字只表示重复的次数 k ,例如不会出现像 3a 或 2[4] 的输入。
例如:
s = "3[a]2[bc]", 返回 "aaabcbc".
s = "3[a2[c]]", 返回 "accaccacc".
s = "2[abc]3[cd]ef", 返回 "abcabccdcdcdef".

算法思路

以"3[a]2[bc]"为例:
1、初始化一个栈stack,用来存储结果;
2、遍历字符串,将']'字符前的所有字符都入栈,此时stack里面保存的字符为3[a;
3、当检测到字符']'时,说明已经有一个完整编码的字符串了(此时为"3[a]"),此时开始对栈里面的字符串进行解码。
4、由编码格式可以看出,字符是在[]中,循环次数是在[]外面。因此,可将栈里面的数据元素依次出栈。
4.1 当遇见'['之前,此时出栈的都是字符,可暂时写入另一个栈。
4.2 当遇见'['时,说明编码的字符已经完全出栈,栈里面剩下的就是循环次数了。
4.3 将栈里面的数据继续出栈,直至栈为空或者栈顶数据不是数字字符时,停止出栈。
由上面三步可以得出,编码的字符串为"a",编码的次数为"3"。因此,只需要将字符串"a"循环3次再次入stack栈即可。入栈完成后,stack里面的保存的数据为"aaa";
5、当原字符串未结束时,重复2-4步,直至完成整个字符串的搜索。
6、得到最终于的字符串''aaabcbc"保存在stack栈中。

代码实现

BOOL isNum(char c){
    if(c >= '0' && c <= '9') return YES;
    return NO;
}

char * decodeString(char * s){
    int len = strlen(s);
    int stackSize = 50;
    char *stack = (char*)malloc(stackSize*sizeof(char));
    int stackTop = -1;
    int numTimes = 0;
    
    int i = 0;
    while(i < len){
        if(s[i] != ']'){
            stack[++stackTop] = s[i];
            i++;
        }
        else{
            char *charTemp = (char*)malloc(stackSize*sizeof(char));
            int charTempTop = -1;
            while(stack[stackTop] != '['){
                charTemp[++charTempTop] = stack[stackTop];
                stackTop--;
            }
            stackTop--;
            numTimes = 0;
            char strOfInt[11] = {0};
            int oriTop = stackTop;
            while(stackTop != -1 && isNum(stack[stackTop])){
                stackTop --;
            }
            for(int j = stackTop+1; j<=oriTop; j++){
                strOfInt[j-stackTop-1] = stack[j];
            }
            numTimes = atoi(strOfInt);
            
            for(int i = 0; i < numTimes; i++){
                int j = charTempTop;
                while(j != -1){
                    stack[++stackTop] =charTemp[j--];
                }
            }
            free(charTemp);
            charTemp = NULL;
            i++;
        }
    }
    return stack;
}

二、去掉重复字母问题

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

算法思路

该题目的重点是:返回字典序最小,且不打乱其它字符的位置。
如何返回字典序最小?则按字母顺序排列即可。
那不打乱其它字符的位置?此时,字符出现的剩余次数就可以用来判断。
例如:"cdacdcbc",为了保证字典序最小,栈里面的元素应该从小到大排列。当栈里面的元素按"cd"排列时,突然出现比"d"小的字符"a",并且后面不会再出现"d"字符,此时应该将a入栈,并从"a"开始重新按字母大小排序,这样才能保证字典序最小。

代码实现

char *removeDuplicateLetters(char *s){
    int len = strlen(s);
    char* stack = (char*)malloc(len*2 * sizeof(char));
    int stackTop = -1;
    //1、 遍历s,标记每个字符出现的次数
    char record[26+1] = {0};
    for(int i = 0; i < len; i++){
        record[s[i]-'a'] += 1;
    }
    
    for(int i = 0; i<len; i++){
        //遍历栈里面存的数据,查看是否是栈已经存放了该数据
        int exist = 0;
        for(int j = 0; j<=stackTop; j++){
            if(stack[j] == s[i]){
                exist = 1;
                break;
            }
        }
        
        if(exist == 1){
            record[s[i] - 'a']--;
        }
        else{
            //当前栈里面的元素是否为空,不为空的话,需要将当前字符与栈顶比较;
            //1、栈顶为空时,直接将元素入栈;
            //2、栈顶不为空时,且当前元素比栈顶元素小时:
            //2.1 栈顶元素后面不会再出现,即record[stack[stackTop] - 'a']>1,此时当前元素直接入栈;
            //  如s=cdacbcbc,当前元素s[2]=a时,由于d后面不会再有,因此此时的a直接入栈;
            //2.2 栈顶元素后面还会再出现,需要将当前栈元素出栈,并且由于栈顶元素已经比较过一次,故record[s[i] - 'a']--;
            //  重复比较栈顶,直至所有符合2.2条件的数据都出栈后,再将s[i]入栈;
            //  如s=bcabc,
            //      当前元素s[2]=a时,由于c后面还会出现,故c需要先出栈,且c出现的次数要减1;
            //      此时栈中剩下b,由于b比a大且b后面也会再出现,因此b也要先出栈,且b出现的次数要减1;
            //      此时栈里面已经没有元素了,则需要将a入栈;
            while(stackTop != -1 && stack[stackTop]>s[i] && record[stack[stackTop] - 'a']>1){
                record[stack[stackTop] - 'a']--;
                stackTop--;
            }
            stack[++stackTop] = s[i];
        }
    }
    stack[++stackTop] = '\0';
    
    return stack;
}

相关文章

  • 算法与数据结构(1),List

    算法与数据结构(1),List 算法与数据结构(2),Map 算法与数据结构(3),并发结构 习惯了,深夜更新博客...

  • 算法与数据结构(3),并发结构

    算法与数据结构(1),List 算法与数据结构(2),Map 算法与数据结构(3),并发结构 本来已经合上电脑了,...

  • 前端干货 -03

    37. 算法 算法地址 数据结构与算法 JavaScript 描述. 章节练习https://github.com...

  • 数据结构与算法

    数据结构与算法之美 数据结构与算法之美1--如何学数据结构与算法之美2--复杂度分析(上)数据结构与算法之美3--...

  • 算法与数据结构(2),Map

    算法与数据结构(1),List 算法与数据结构(2),Map 算法与数据结构(3),并发结构 睡了不到六个小时,被...

  • 数据结构与算法-目录

    数据结构与算法-目录 C语言篇 数据结构和算法-C语言篇1-绪论数据结构和算法-C语言篇2-初识算法数据结构与算法...

  • IOS开发_数据结构

    1、数据结构; 2、算法; 3、数据结构与算法; 1、数据结构; 1.1 概念: 数据结构:数据结构是计算...

  • 数据结构 -- C++ STL中的数据结构与算法[2]

    数据结构 -- C++ STL中的数据结构与算法[2] 接前一篇 数据结构 -- C++ STL中的数据结构与算法...

  • 数据结构与算法 - 查找

    数据结构与算法系列文章数据结构与算法 - 时间复杂度数据结构与算法 - 线性表数据结构与算法 - 树形结构数据结构...

  • 创作101第一季丨第1天丨学习笔记

    数据结构与算法_第一章_2 程序 = 算法 + 数据结构, 算法 = 逻辑 + 控制。 数据结构两大用途:一是用于...

网友评论

      本文标题:数据结构与算法-练习2

      本文链接:https://www.haomeiwen.com/subject/ldaewhtx.html