算法视频课笔记-初三1-数组/队列/栈及其相互转换

本文详细介绍了如何使用固定数组实现大小固定的栈和队列,包括基本的压栈、出栈、入队、出队操作。此外,还展示了如何设计一个特殊栈,使其在O(1)时间复杂度下完成push、pop和getMin操作。最后,探讨了如何用栈结构实现队列以及用队列实现栈,强调了在转换过程中保持数据结构特性的关键点。
摘要由CSDN通过智能技术生成

【题目1】用数组结构实现大小固定的队列和栈

队列:先进先出
栈:先进后出

【使用固定数组实现栈的功能】

public static class ArrayStack{
	private Integer[] arr;
	private Integer index;
	public ArrayStack(int initSize){
		if(initSize < 0){
			throw new IllegalArgumentException("The init size is less than 0");
		}
		arr = new Integer[initSize];
		index = 0;
	}
	
	public Integer peek(){
		if(index == 0){
			return null;
		}
		return arr[index -1];
	}
	//压栈过程
	public push(int obj){
		if(index == arr.length){
			throw new ArrayIndexOutOfBoundsException("The stack is full");
		}
		//如果栈没有满,放入新的数字
		arr[index++] = obj;
		
	}
	//出栈过程
	public Integer pop(){
		if(index == 0){
			throw new ArrayIndexOutOfBoundsException("The stack is empty!");
		}
		return arr[--index];
	}
}

【固定数组实现队列功能】
【思路】定义两个指针,end和start,其中end表示表位位置(进的数应该添加在哪里),start表示表头(出的数从哪里拿)
设置size变量对end和start进行解耦,当size==队列长度的时候不能添加,当size<队列长度的时候可以添加。

public static class ArrayQueue{
	//初始化数组,数组大小,开始指针,结束指针
	private Integer[] arr;
	private Interger size;
	private Integer start;
	private Integer end;
	//初始化该数组队列
	public ArrayQueue(int initSize){
		if(initSize < 0){
			throw new IllegalArgumentException("The init size is less than 0");
		}
		//对数据进行初始化
		arr = new Integer[initSize];
		size = 0;
		start = 0;
		end = 0;
	}
	//peek返回当前数组队列中的第一个元素是啥
	public Interger peek(){
		if(size == 0){
			return null;
		}
		return arr[start];
		
	}
	//进队操作
	public void push(int obj){
		//队列满的时候报错
		if(size == arr.length){
			throw new ArrayIndexOutOfBoundsException("The queue is full");
		}
		//队列不满则将数字添加到队列中
		size++;
		arr[end] = obj;
		end = nextIndex(arr.length, end);
	}
	//队列的弹出逻辑
	public Integer poll(){
		if(size == o){
			throw new ArrayIndexOutOfBoundsException("The queue is empty");
		}
		size--;
		int temp = arr[start];
		start = nextIndex(arr.length, start);
		return temp;
		
	}
}
//nextIndex函数返回index的位置,如果队列满了,则返回开头
public int nextIndex(int size, int index){
	return index == size - 1 ? 0 : index + 1;
}

【题目2】实现一个特殊的栈,在实现栈的基本功能的基础上,在实现返回栈中最小元素的操作

【要求】1.pop、push、getMin操作的时间复杂度都是O(1)
2.设计的栈类型可以使用线程的栈
【思路】使用两个栈,另一个栈用来同步存储当前的最小值结构。

public static class MyStack2{
	private Stack<Integer> stackData;
	private Stack<Integer> stackMin;
	
	//初始化两个栈
	public MyStack2(){
		this.stackData = new Stack<Integer>();
		this.stackMin = new Stack<Integer>();
	}
	//压栈操作,如果值小于最小栈栈顶直接压入,如果值大于或等于最小栈栈顶则重复压入栈顶值
	public void push(int newNum){
		if(this.stackMin.isEmpty()){
			this.stackMin.push(newNum);
		}else if(newNum < this.getmin()){
			this.stackMin.push(newNum);
		}else{
			int newMin = this.stackMin.peek();
			this.stackMin.push(newMin);
		}
		this.stackData.push(newNum);//最后将值压入data栈中
	}
	
	public int pop(){
		if(this.stackData.isEmpty()){
			throw new RuntimeException("Your stack is empty!");
		}
		this.stackMin.pop();
		return stackData.pop();
	}
	
	//定义返回最小值栈的栈顶操作
	public int getmin(){
		if(this.stackMin.isEmpty()){
			throw new RuntimeException("Your stack is empty!");
		}
		return this.stackMin.peek();
	}
}

【问题3.1】如何用队列实现栈结构

【思路】使用两个队列循环倒,依次弹出返回每个队列中的最后一个元素,最终得到栈的输出

public static class TwoQueuesStack{
	private Queue<Integer> queue;
	private Queue<Integer> help;
	
	public TwoQueuesStack(){
		queue = new LinkedList<Integer>();
		help = new LinkedList<Integer>();
	}
	
	public void push(int pushInt){
		queue.add(pushInt);
	}
	//peek功能相当于查看当前栈顶元素
	public int peek(){
		if(queue.isEmpty()){
			throw new RuntimeException("Stack is empty!");
		}
		while(queue.size() != 1){
			help.add(queue.poll());
		}
		int res = queue.poll();
		help.add(res);
		swap();
		return res;
	}
	public int pop(){
		if(queue.isEmpty()){
			throw new RuntimeException("Stack is empty!");
		}
		//queue中数值>1的时候,依次将queue中的值加入help中去
		while(queue.size() > 1){
			help.add(queue.poll());
		}
		//返回queue队列中的剩下最后的一个元素
		int res = queue.poll();
		//交换引用(queue和help数组进行交换)
		swap();
		return res;
	}
	
	private void swap(){
		Queue<Integer> temp = help;
		help = queue;
		queue = temp;
	}
}

【问题3.2】如何用栈结构实现队列结构

【用两个栈实现】将push栈中的元素压入pop栈,即实现与队列相同的先进先出
【注意】(1)pop栈中入股中途还有元素未弹出干净,此时不能往pop栈中压栈(即pop栈未空才能压栈)//
(2)每次从push出栈和压栈进pop一定要倒干净,不能留一些元素

public static class twoStackQueue{

	private Stack<Integer> stackPush;
	private Stack<Integer> stackPop;
	
	public TwoStacksQueue(){
		stackPush = new Stack<Integer>();
		stackPop = new Stack<Integer>();
	}
	
	public void push(int pushInt){
		stackPush.push(pushInt);
		dao();
	}
	public int poll(){
		if(stackPop.empty() && stackPush.empty()){
			throw new RuntimeException("Queue is empty!");
		}
		dao();
		return stackPop.pop();
	}
	//当栈之间倒完了才能进行peek操作
	public int peek(){
		if(stackPop.empty() && stackPush.empty()){
			throw new RuntimeException("Queue is empty!")
		}
		dao();
		return stackPop.peek()
	}
	
	//将两个栈中的元素进行倒换
	public void dao(){
		if(stackPop.isEmpty()){					//pop栈必须为空
			while(!stackPush.isEmpty()){		//将push栈中元素弹干净
				stackPop.push(stackPush.pop());
			}
		}
	}

}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值