当前位置:网站首页>LeetCode刷题:用栈实现队列 与 字符串解码
LeetCode刷题:用栈实现队列 与 字符串解码
2022-07-21 14:25:00 【散一世繁华,颠半世琉璃】
1.用栈实现队列
请你仅使用两个栈实现先入先出队列。队列应当支持一般队列支持的所有操作(push、pop、peek、empty):
实现 MyQueue 类:
void push(int x) :将元素 x 推到队列的末尾
int pop() :从队列的开头移除并返回元素
int peek() :返回队列开头的元素
boolean empty(): 如果队列为空,返回 true ;否则,返回 false
说明:
你只能使用标准的栈操作 —— 也就是只有 push to top, peek/pop from top, size, 和 is empty 操作是合法的。
你所使用的语言也许不支持栈。你可以使用 list 或者 deque(双端队列)来模拟一个栈,只要是标准的栈操作即可。
示例一:
1.双栈实现
分析此问题,题目要求我们使用两个栈实现队列,因此,我们将一个栈作为输入栈,另一个栈作为输出栈;
每次pop或peek的时候,若输出栈outStack为空,则将输入栈的全部元素依次弹出并压入输出栈,这样输出栈从栈顶到栈低的顺序就是从队首往队尾的顺序了。 即实现了题目要求。具体代码如下所示:
class MyQueue {
private static Stack<Integer> inStack;//输入栈
private static Stack<Integer> outStack;//输出栈
public MyQueue() {
inStack=new Stack<Integer>();
outStack=new Stack<Integer>();
}
public void push(int x) {
inStack.push(x);
}
public int pop() {
if(outStack.isEmpty()){
inToOut();
}
return outStack.pop();
}
public int peek() {
if(outStack.isEmpty()){
inToOut();
}
return outStack.peek();
}
public boolean empty() {
return inStack.isEmpty() && outStack.isEmpty();
}
public void inToOut(){
//将输入栈中的数据一次压如输出栈
while(!inStack.isEmpty()){
outStack.push(inStack.pop());
}
}
}
/** * Your MyQueue object will be instantiated and called as such: * MyQueue obj = new MyQueue(); * obj.push(x); * int param_2 = obj.pop(); * int param_3 = obj.peek(); * boolean param_4 = obj.empty(); */
2.GIF动图演示
3.时间复杂度分析
时间复杂度: push \texttt{push} push和 empty \texttt{empty} empty为 O ( 1 ) O(1) O(1), pop \texttt{pop} pop和 peek \texttt{peek} peek为均摊 O ( 1 ) O(1) O(1)。对于每个元素,至多入栈和出栈各两次,故均摊复杂度为 O ( 1 ) O(1) O(1)。
空间复杂度: O ( n ) O(n) O(n)。其中 n是操作总数。对于有 n n n 次 push \texttt{push} push操作的情况,队列中会有 n n n 个元素,故空间复杂度为 O ( n ) O(n) O(n)。
代码在LeetCode中的执行情况如下所示:
2.字符串解码
给定一个经过编码的字符串,返回它解码后的字符串。
编码规则为: k[encoded_string],表示其中方括号内部的 encoded_string 正好重复 k 次。注意 k 保证为正整数。
你可以认为输入字符串总是有效的;输入字符串中没有额外的空格,且输入的方括号总是符合格式要求的。
此外,你可以认为原始数据不包含数字,所有的数字只表示重复的次数 k ,例如不会出现像 3a 或 2[4] 的输入。
示例一:
示例二:
示例三:示例四:
1.栈操作
此题是中等难度的题目,读者需要仔细揣摩并理解!
该题的具体实现算法如下,遍历这个栈:
如果当前的字符为数位,解析出一个数字(连续的多个数位)并进栈
如果当前的字符为字母或者左括号,直接进栈
如果当前的字符为右括号,开始出栈,一直到左括号出栈,出栈序列反转后拼接成一个字符串,此时取出栈顶的数字,就是这个字符串应该出现的次数,我们根据这个次数和字符串构造出新的字符串并进栈
重复如上操作,最终将栈中的元素按照从栈底到栈顶的顺序拼接起来,就得到了答案。
注意:这里的LinkedList是一个双链表集合,可以用来模拟栈!
下表是LinkedList对应的部分API,有兴趣的同学可以自行去网上搜索!
Modifier and Type | Method and Description |
---|---|
E | peekLast() 检索但不删除此列表的最后一个元素,如果此列表为空,则返回 null 。 |
void | addLast(E e) 将指定的元素追加到此列表的末尾。 |
E | removeLast() 从此列表中删除并返回最后一个元素。 |
具体的实现代码如下所示:
class Solution {
int ptr;
public String decodeString(String s) {
LinkedList<String> stk = new LinkedList<String>();
ptr = 0;
while (ptr < s.length()) {
char cur = s.charAt(ptr);
if (Character.isDigit(cur)) {
// 获取一个数字并进栈
String digits = getDigits(s);
stk.addLast(digits);
} else if (Character.isLetter(cur) || cur == '[') {
// 获取一个字母并进栈
stk.addLast(String.valueOf(s.charAt(ptr++)));
} else {
//遇见了“]”
++ptr;
LinkedList<String> sub = new LinkedList<String>();
while (!"[".equals(stk.peekLast())) {
sub.addLast(stk.removeLast());
}
Collections.reverse(sub);
// 左括号出栈
stk.removeLast();
// 此时栈顶为当前 sub 对应的字符串应该出现的次数
int repTime = Integer.parseInt(stk.removeLast());
StringBuffer t = new StringBuffer();
String o = getString(sub);
// 构造字符串
while (repTime-- > 0) {
t.append(o);
}
// 将构造好的字符串入栈
stk.addLast(t.toString());
}
}
return getString(stk);
}
public String getDigits(String s) {
StringBuffer ret = new StringBuffer();
while (Character.isDigit(s.charAt(ptr))) {
ret.append(s.charAt(ptr++));
}
return ret.toString();
}
public String getString(LinkedList<String> v) {
StringBuffer ret = new StringBuffer();
for (String s : v) {
ret.append(s);
}
return ret.toString();
}
}
3.时间复杂度分析
这里的算法实现主要是遍历一次String字符串,除了遍历字符串以外我们还需要将字符解码后的每个字符都压入栈中,因此时间复杂度为 O ( n ) O(n) O(n);空间上我们使用了LinkedList作为存储解码后的字符,因此,空间复杂度为 O ( n ) O(n) O(n);具体代码在LeetCode中的执行情况如下所示:
边栏推荐
- How to avoid the risk of mismatch between Ethernet interface and wiring
- IP protocol, the king of defending
- leetcode 724.寻找数组的中心下标
- Typescript learning
- Data center cable management
- Some tool modifications
- 申万宏源证券股票低佣金开户靠谱吗,可靠安全吗
- leetcode 1413. Sum step by step to get the minimum value of positive numbers
- Vector container member function reserve() and iterator failure
- leetcode 310. Minimum height tree
猜你喜欢
Wechat applet_ 19. Custom components -behaviors
AUTOCAD——JOIN合并命令
Haproxy2.6 load installation configuration
Idea connects to MySQL database
问题来了:4GB物理内存的机器上申请8G内存能成功吗?
The role of visual management of communication infrastructure in ISO 2.0
爬虫与反爬:一场无休止之战
百度飞桨EasyDL X 韦士肯:看轴承质检如何装上“AI之眼”
What is the culprit of the failure of digital transformation?
Typora Beta版过期解决
随机推荐
leetcode1588. Sum of all odd length subarrays
申万宏源证券股票低佣金开户靠谱吗,可靠安全吗
leetcode 1582. Special position in binary matrix
Goldfish rhca memoirs: cl210 performs image operation -- compare image format + build custom image
leetcode 1582. 二进制矩阵中的特殊位置
YOLOPose实战:手把手实现单阶段的人体姿态估计+代码解读
leetcode 1732.找到最高海拔
The development trend of the meta universe has been supported, and the era that everything can be a meta universe seems to have arrived
免杀exe技术探讨
Wechat applet_ 19. Custom components -behaviors
W3school和W3Cschool的区别
NETCORE - Middleware (1)
如何高效地实现基础设备可视化
The role of visual management of communication infrastructure in ISO 2.0
How to map the SSM framework file upload to the database
A device from black to white (with front desk 0day)
数据中心线缆管理
Zabbix3.0 alarm settings
64. Minimum path and
在Cygwin环境下构建和使用EmberZNet PRO Zigbee Host应用程序