分析:队列有先进先出的特点,所以我们使用两个栈,st1用来存放元素,st2用来实际返回
(1)假设有元素1和2进入st1,在需要Pop()时,我们将st1中的元素全部弹出放入st2中,此时就是2为栈底,1为栈顶(借用卡哥的图)有一个要点:先判断st2中是否没有元素了,才能将st1中的元素弹出加入到st2中。
(2)Peek()返回头部节点,和Pop()写法类似,将返回值改为Peek即可,本质没区别
public class MyQueue {
Stack<int> st1;
Stack<int> st2;
public MyQueue() {
st1 = new Stack<int>();
st2 = new Stack<int>();
}
public void Push(int x) {
st1.Push(x);
}
public int Pop() {
if(st2.Count != 0)
{
return st2.Pop();
}
else
{
while(st1.Count != 0)
{
st2.Push(st1.Pop());
}
return st2.Pop();
}
}
public int Peek() {
if(st2.Count != 0)
{
return st2.Peek();
}
else
{
while(st1.Count != 0)
{
st2.Push(st1.Pop());
}
return st2.Peek();
}
}
public bool Empty() {
return st1.Count == 0 && st2.Count == 0;
}
}
/**
* 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();
* bool param_4 = obj.Empty();
*/
分析:和上个题目类似,也是一个容器用来存放元素,另一个容器用来返回最终值。
(1)设定q1输出元素,q2存放元素,假如q1已有元素1,现在需要加入元素2,那么就先把q1中的元素都弹出来放入q2中,再把元素2加入q1,再将q2中的元素全部加入到q1,遵循队列原则,这些元素(也就是元素1)都会放到q1的尾部,也就是第一个元素是2,第二个元素是1。
(2)实现了Push功能,我们的队列的顺序就已经是遵循栈的原则了(先进后出)其余直接返回头部,或者弹出即
public class MyStack {
Queue<int> q1;
Queue<int> q2;
public MyStack() {
q1 = new Queue<int>();
q2 = new Queue<int>();
}
public void Push(int x) {
while(q1.Count > 0)
{
q2.Enqueue(q1.Dequeue());
}
q1.Enqueue(x);
while(q2.Count > 0)
{
q1.Enqueue(q2.Dequeue());
}
}
public int Pop() {
return q1.Dequeue();
}
public int Top() {
return q1.Peek();
}
public bool Empty() {
return q1.Count == 0 && q2.Count == 0;
}
}
/**
* Your MyStack object will be instantiated and called as such:
* MyStack obj = new MyStack();
* obj.Push(x);
* int param_2 = obj.Pop();
* int param_3 = obj.Top();
* bool param_4 = obj.Empty();
*/
分析:本题想到栈作为解题,当遇到左括号的时候就添加右括号,直到遇到右括号就开始弹出看是否相等。
(1)首先是要记得写else if,因为最后的判断语句要弹出元素
(2)其次就是写判断条件 st1.Count == 0,因为输入元素s也可能是"(()“,这样栈中会有两个右括号,那么第二个右括号完全没有就会出现报错,所以记得return false
(3)最后也要判断一下栈中的元素是否为空,因为也可能是s只输入”)",那么for循环中也没有地方处理该元素
说句题外话:看到新题肯定考虑不到这么多情况,都是一边做一边报错一边去想,最后总结一下,至少保证下次看见思路更多一点就行
public class Solution {
public bool IsValid(string s) {
Stack<char> st1 = new Stack<char>();
for(int i = 0; i < s.Length; i++)
{
if(s[i] =='{')
{
st1.Push('}');
}
else if(s[i] =='[')
{
st1.Push(']');
}
else if(s[i] =='(')
{
st1.Push(')');
}
else if(st1.Count == 0 || st1.Pop() != s[i])
{
return false;
}
}
if(st1.Count != 0)
{
return false;
}
return true;
}
}
分析:还是使用栈,把字符串中的所有元素都加入到栈,如果有一样的那就弹出该元素。假设栈中有ab,而字符串下一个元素是b,那就直接弹出b,此时栈中只有a,继续下一个元素的判断
public class Solution {
public string RemoveDuplicates(string s) {
Stack<char> st1 = new Stack<char>();
for(int i = 0; i < s.Length; i++)
{
if(st1.Count != 0 && st1.Peek() == s[i])
{
st1.Pop();
}
else
{
st1.Push(s[i]);
}
}
//新的字符串方法Concat:将指定的字符串参数连接到字符串上
//直接将栈中的字符连接成字符串
// st1.Reverse:栈是先进后出,需要翻转元素
return string.Concat(st1.Reverse());
//还有一种写法 就是将栈中的元素拼接成字符串即可
/*
string str = "";
while(st1.Count > 0)
{
str += st1.Pop();
}
return str;
*/
}
}