剑指offer第五题

一、两个栈实现队列
思路:栈得特征就是先进后出,队列是先进先出。所以既然是两个栈实现队列。比如是一个数组[5,4,8,6,9,2]。我们希望输出是296854.所以可以先入第一个栈,这样的话5就在最下面,2在最上面。然后再判断第二个是否为空,如果是空的,再把第一个栈得数据依次取出来依次入第二个栈(一定要判断第二个栈是否为空,具体我现在还不明白,如果不为空,直接输出第二个栈)。这样的话,2就在最下面,5在最上面。然后再把第二个栈出栈,就可以和输入时候得顺序一致了,从而达到队列先进先出的效果。

import java.util.Stack;

public class Solution {
    Stack<Integer> stack1 = new Stack<Integer>();
    Stack<Integer> stack2 = new Stack<Integer>();
    
    public void push(int node) {
        stack1.push(node);
    }
    
    public int pop() {
        if(stack2.empty())
        {
            while(!(stack1.empty()))
                  {
                      stack2.push(stack1.pop());
                  }
        }
                  return stack2.pop();
    }
}

把这个算法测试一下

import java.util.Scanner;
import java.util.Stack;

public class StackQueue {
	Stack<Integer> stack1=new Stack<Integer>();
	Stack<Integer> stack2=new Stack<Integer>();
	public void Push(int node)
	{
		stack1.push(node);
	}
	public void Pop()
	{
		if(stack2.empty())
		{
			while(!(stack1.empty()))
			{
				stack2.push(stack1.pop());
			}
			
		}
		while(!(stack2.empty()))
		{
			System.out.print(stack2.pop()+" ");
		}
	}
	public static void main(String[] args)
	{
		 StackQueue sa=new  StackQueue();
		 Scanner s=new Scanner(System.in);
		 int n=s.nextInt();
		 int[]arr=new int[n];
		 for(int i=0;i<n;i++)
		 {
			 arr[i]=s.nextInt();
		 }
		 for(int i=0;i<n;i++)
		 {
			 sa.Push(arr[i]);
		 }
		 System.out.println(sa.stack1);
		 sa.Pop();
	}
	
}

输入:

6
8 4 5 2 3 0

输出:

[8,4,5,2,3,0]
8 4 5 2 3 0

注意:在输入里面(1)第一次输入n和第二次输入数据是默认回车换行的
(2)输入数组得时候,要用空格隔开
(3)如果直接输出栈得话。从底到上(正好和平时取出的顺序相反),且是在一个大括号里。

二、两个队列实现栈(1 2 3 4 5 6)
思路:同样,在进栈环节也是将数据进入第一个队列。因为队列是先进先出,所以即便把第一个队列值取出(12345顺序取出)放在第二个队列(还是12345)也还是输入的顺序,但是我们要得到(54321).所以两个队列实现栈比两个栈实现队列难一些。
具体想法是把第一个队列除了最后一个元素外都进第二个队列,然后再输出第一个队列的最后一个元素。然后这时第一个队列空了,第二个队列n-1个数。再把这n-1个数进队列一,这时候第一个队列n-1个元素,第二个队列又空了,然后再把第一个队列除了最后一个之外进第二个队列,然后再输出第一个队列得最后一个元素。然后此时第二个队列是n-2个,第一个队列空了。然后再进行之前得操作,直到第一个队列没有元素为止。
直接实现测试代码:

import java.util.LinkedList;
import java.util.Queue;
import java.util.Scanner;
import java.util.Stack;

public class QueueStack {
	Queue<Integer> q1=new LinkedList<Integer>(); 
	Queue<Integer> q2=new LinkedList<Integer>();
	public void Add(int node)
	{
		q1.add(node);
	}
	public void Pull()
	{
		if(q2.isEmpty())
		{   
			while(!(q1.isEmpty()))
			{
				int len=q1.size(); 
				for(int i=0;i<len-1;i++)
				{
					q2.add(q1.remove());
				}
				System.out.print(q1.remove()+" ");
				if(q1.isEmpty())
				{
					while(!(q2.isEmpty()))
					{
						q1.add(q2.remove());
					}
				}
			}
		}
	}
	public static void main(String[] args)
	{
		QueueStack Q=new QueueStack();
		int n;
		Scanner s=new Scanner(System.in);
		n=s.nextInt();
		int[] arr=new int[n];
		for(int i=0;i<n;i++)
		{
			arr[i]=s.nextInt();
		}
		for(int i=0;i<n;i++)
		{
			Q.Add(arr[i]);
		}
		Q.Pull();
		
	}

注意:
(1)定义队列不像定义栈那么简单,需要利用多态性通过实现类来定义
(2)队列的进队是add()函数,出队是remove()和pull(),对应栈中的pop()。也是取出当前元素,删除这个节点的意思。peek()和element()对应于栈中的peek,只读取头元素,不删除。
(3)判断是否为空,栈中是empty(),队列中是isEmpty()。
(4)队列原样输出也是和栈一样的,从头到尾(就是和输入顺序一样)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值