【每日挠头算法题(3)】字符串解码|数组中重复的数字

简介: 【每日挠头算法题(3)】字符串解码|数组中重复的数字

一、字符串解码

点我直达~

思路:栈

这道题怎么看都好像是用栈来实现,因为有左右括号。(可是第一时间我没想到)

  • 遍历字符串,此时会有几种情况:
  • 1.如果是数字字符,给一个num变量,将该字符转化成数字存储起来。
  • 2.如果是字母(题目说只可能是小写),给一个字符串str,将该字母存储到字符串里。
  • 3.如果是" [ ",此时需要将刚才的数字和字母分别入栈,将数字num入到nums栈,str入到strs栈,然后清空num和str
  • 4.如果是" ] “,先将nums栈的栈顶元素取出来给给top变量,然后循环top次将str追加到strs栈的栈顶元素后面,比如这时候strs栈栈顶元素是"aaa”,str是"ab",top = 2,那么就将str追加,结果为:aaaabab。最后再将strs栈的栈顶元素赋值回给str。
  • 注意:遇到" ] “后,下一个字符不可能是” [ ",不符合题目要求,只可能是数字字符或字母字符,仍然会按照正常的流程继续走下去。
  • 最后返回str即可。

具体代码如下:

class Solution {
public:
    string decodeString(string s) 
    {
        int num = 0; //存储数字
        string str = ""; //存储字符串
        stack<int> nums; //遇到'[':数字入数字栈
        stack<string> strs;//字符串入字符串栈
        for(int i = 0;i<s.size();++i)
        {
            if(s[i] >='0' && s[i] <= '9')
            {
                //如果出现连续的数字,个位就要*10再加起来
                num = num * 10 + (s[i] - '0') ;
            }
            else if(s[i] >= 'a' && s[i] <='z')
            {
                str = str + s[i];
            }
            else if(s[i] == '[')
            {
                //入数字栈
                nums.push(num);
                num = 0;
                //入字符串栈
                strs.push(str);
                str = "";
            }
            //遇到']'了
            else
            {
                int top = nums.top();
                nums.pop();
                for(int j = 0;j<top;++j)
                {
                    //注意这里是将str追加到栈顶元素之后
                    strs.top() += str;
                }
                //将栈顶元素给回str
                //']'之后接下来的字符不可能是'[',这不符合题目要求
                //所以接下来的字符不管是数字还是字母,都可以正常进行
                str = strs.top();
                strs.pop();
            }
        }
        return str;
    }
};

时间复杂度:O(N),空间复杂度O(1)

二、数组中重复的数字

点我直达~

思路1:计数法

具体过程如下:

  • 1.开一个n大小的顺序表,初始化为0,作为0~n-1区间的每个数字出现的次数。
  • 2.遍历一遍数组,将出现的数字在计数顺序表的位置++,比如:出现的数字是5,那么就在顺序表的下标5的位置+1
  • 3.如果计数顺序表中的任意元素出现次数大于1,则说明对应的元素重复出现,返回即可。

具体代码如下:

class Solution {
public:
    int findRepeatNumber(vector<int>& nums) 
    {
        int n = nums.size();
        vector<int> count(n);
        for(int i =0;i<nums.size();++i)
        {
            count[nums[i]]++;
            if(count[nums[i]] > 1)
                return nums[i];
        }
        return -1;
    }
};

时间复杂度O(n),空间复杂度O(n)

思路2:原地交换法

这个方法也可以理解为:岗位对接人才问题。

具体如下:

  • 1.这个原地交换法就相当于分配工作,每个索引代表一个工作岗位,每个岗位必须专业对口,既0索引必须0元素才能上岗。而我们的目的就是找出溢出的人才,既0索引岗位有多个0元素竞争。
  • 2.我们先从0索引岗位开始遍历,首先我们看0索引是不是已经专业对口了,如果已经专业对口既nums[0]=0,那我们就跳过0岗位看1岗位。
  • 3.如果0索引没有专业对口,那么我们看现在0索引上的人才调整到他对应的岗位上,比如num[0]=2,那我们就把2这个元素挪到他对应的岗位上既num[2],这个时候有两种情况:
  • 1、num[2]岗位上已经有专业对口的人才了,既num[2]=2,这就说明刚刚那个在num[0]上的2是溢出的人才,我们直接将其返回即可。
  • 2、num[2]上的不是专业对口的人才,那我们将num[0]上的元素和num[2]上的元素交换,这样num[2]就找到专业对口的人才了。
  • 4.之后重复这个过程直到帮num[0]找到专业对口的人才,然后以此类推帮num[1]找人才、帮num[2]找人才,直到找到溢出的人才。

图解过程如下:

具体代码如下:

class Solution {
public:
    int findRepeatNumber(vector<int>& nums) 
    {
        int i = 0;
        while(i < nums.size())
        {
            //岗位和人才对口了,继续往下找,直到找到溢出的人才
            if(i == nums[i])
            {
                ++i;
                continue;
            }
            //情况1.该人才是溢出人才
            if(nums[i] == nums[nums[i]])
                return nums[i];
            //情况2.不是溢出人才,那就把该人才调整到对应岗位
            else
                swap(nums[i],nums[nums[i]]);
        }
        return -1;
    }
};

时间复杂度O(n),空间复杂度O(1)

总结

通过今天的两道题:

  • 1.我发现只要有括号的匹配,或者有涉及到括号的,都可以考虑使用栈来解决。
  • 2.对于找重复的数字/字符串/字符等,均可使用计数法,空间复杂度O(N)来统计出现次数。
    或者使用“岗位对接人才”的原地交换法解决此类问题。
相关文章
|
2月前
|
算法
Leetcode 初级算法 --- 数组篇
Leetcode 初级算法 --- 数组篇
46 0
|
2月前
|
算法 程序员 索引
数据结构与算法学习七:栈、数组模拟栈、单链表模拟栈、栈应用实例 实现 综合计算器
栈的基本概念、应用场景以及如何使用数组和单链表模拟栈,并展示了如何利用栈和中缀表达式实现一个综合计算器。
48 1
数据结构与算法学习七:栈、数组模拟栈、单链表模拟栈、栈应用实例 实现 综合计算器
|
2月前
|
算法
两个字符串匹配出最长公共子序列算法
本文介绍了最长公共子序列(LCS)问题的算法实现,通过动态规划方法求解两个字符串的最长公共子序列,并提供了具体的编程实现细节和示例。
103 1
两个字符串匹配出最长公共子序列算法
|
2月前
|
存储 算法 定位技术
数据结构与算法学习二、稀疏数组与队列,数组模拟队列,模拟环形队列
这篇文章主要介绍了稀疏数组和队列的概念、应用实例以及如何使用数组模拟队列和环形队列的实现方法。
27 0
数据结构与算法学习二、稀疏数组与队列,数组模拟队列,模拟环形队列
|
4月前
|
算法 Java
掌握算法学习之字符串经典用法
文章总结了字符串在算法领域的经典用法,特别是通过双指针法来实现字符串的反转操作,并提供了LeetCode上相关题目的Java代码实现,强调了掌握这些技巧对于提升算法思维的重要性。
|
4月前
|
存储 算法 Java
深入算法基础二分查找数组
文章深入学习了二分查找算法的基础,通过实战例子详细解释了算法的逻辑流程,强调了确定合法搜索边界的重要性,并提供了Java语言的代码实现。
深入算法基础二分查找数组
|
4月前
|
算法
【Azure Developer】完成算法第4版书中,第一节基础编码中的数组函数 histogrm()
【Azure Developer】完成算法第4版书中,第一节基础编码中的数组函数 histogrm()
|
4月前
|
算法
【算法】模拟算法——外观数组(medium)
【算法】模拟算法——外观数组(medium)
|
2天前
|
机器学习/深度学习 算法
基于改进遗传优化的BP神经网络金融序列预测算法matlab仿真
本项目基于改进遗传优化的BP神经网络进行金融序列预测,使用MATLAB2022A实现。通过对比BP神经网络、遗传优化BP神经网络及改进遗传优化BP神经网络,展示了三者的误差和预测曲线差异。核心程序结合遗传算法(GA)与BP神经网络,利用GA优化BP网络的初始权重和阈值,提高预测精度。GA通过选择、交叉、变异操作迭代优化,防止局部收敛,增强模型对金融市场复杂性和不确定性的适应能力。
105 80
|
21天前
|
算法
基于WOA算法的SVDD参数寻优matlab仿真
该程序利用鲸鱼优化算法(WOA)对支持向量数据描述(SVDD)模型的参数进行优化,以提高数据分类的准确性。通过MATLAB2022A实现,展示了不同信噪比(SNR)下模型的分类误差。WOA通过模拟鲸鱼捕食行为,动态调整SVDD参数,如惩罚因子C和核函数参数γ,以寻找最优参数组合,增强模型的鲁棒性和泛化能力。