zoukankan      html  css  js  c++  java
  • Cracking the Coding Interview(Stacks and Queues)

    1.Describe how you could use a single array to implement three stacks.

    我的思路:一般堆栈的实现会利用一个数组,这里一个数组若实现3个堆栈,直接考虑把数组划分为3个部分,相当于3个独立的数组,所以就有以下的实现。

                  但是,这种实现方式的缺点在于均分了每个stack需要的space,但是事先无法确定每个stack是否需要更多的space相比于其他的stack。但是针对这个缺陷我没有想到解决的方案。但是书中提供了一种解决思路。

    class stack_share_array
    {
    public:
    	int top;
    	int gap;
    	stack_share_array(int initnum,int gap_dis):top(initnum),gap(gap_dis)
    	{
    
    	}
    	void push(int num)
    	{
    		array[top] = num;
    		top += gap;
    	}
    	int pop()
    	{
    		top -= gap;
    		int result = array[top];
    		return result;
    	}
    	static int array[15];
    };
    

    分成3个使用方法如下使用:

            stack_share_array* stackthree[3];
    	for (int i = 0;i < 3;i++)
    	{
    		stackthree[i] = new stack_share_array(i,3);
    	}
    	int test1 = 10;
    	int test2 = 20;
    	int test3 = 30;
    	stackthree[0]->push(test1++);
    	stackthree[0]->push(test1++);
    	stackthree[0]->push(test1++);
    	stackthree[0]->push(test1++);
    	stackthree[0]->push(test1++);
    
    	stackthree[1]->push(test2++);
    	stackthree[1]->push(test2++);
    	stackthree[1]->push(test2++);
    	stackthree[1]->push(test2++);
    	stackthree[1]->push(test2++);
    
    	stackthree[2]->push(test3++);
    	stackthree[2]->push(test3++);
    	stackthree[2]->push(test3++);
    	stackthree[2]->push(test3++);
    	stackthree[2]->push(test3++);
    

    3种划分方式多种多样,不限于上限的实现。也可以不等分的划分。

    另一种思路:一种在数组里面形成链表的思路,及每个数组单元重新定义,除了保存堆栈的存储信息之外保存前一个元素的信息,方便堆栈顶部的向前移动。这样就能够比较自由的分配3个堆栈所占数组的空间。

    2.How would you design a stack which,in addition to push and pop,also has a function min which returns the minimum element?Push,pop and min should all operate in O(1) time.

     我的思路:

    因为min要能够在O(1)能够返回结果,所以min的操作必定之前保存的应该有记录。我第一直觉是用一个int保存最小值,但是细细想一下,如果pop()之后无法确保这个最小值是否被pop(),如果pop()了,无法更新余下的最小值,思考了很久之后发现可以保存一个根据当前top值来返回min的min数组,从开始堆栈内容为0的时候进行记录。所以这个数组的长度应该与设计堆栈的数组的长度相同。

    class stack_min
    {
    public:
    	int array[15];
    	int min_array[16];
    	int top;
    
    	stack_min():top(0)
    	{
    		min_array[0] = BIG;
    	}
    	void push(int num)
    	{
    		array[top] = num;
    		top ++;
    		if (num < min_array[top - 1])
    		{
    			min_array[top] = num;
    		}
    		else
    		{
    			min_array[top] = min_array[top - 1];
    		}
    	}
    	int pop()
    	{
    		top --;
    		int result = array[top];
    		return result;
    	}
    	int min()
    	{
    		return min_array[top];
    	}
    };
    

     这样空间复杂度有些高,书中提供另外一种能够节约空间复杂度的算法。

    思路是将min数组设计为一个堆栈,这样就能够不需要重复保存很多冗余的最小值。因为利用数组会重复保存同样的最小值多次。

    3.Imagine a (Literal) stack of plates.If the stack gets too high,it might topple.Therefore,in real life,we would likely start a new stack when the previous stack exceeds some threshold, Implement a data structure SetOfStacks that mimics this.SetOfStacks should be composed of several stacks, and should create a new stack once the previous one exceeds capacity.SetOfStacks.push() and SetOfStacks.pop() should behave identically to a single stack (that is,pop() should return the same values as it would if there were just a single stack).

    Follow up

    Implement a function popAt(int index) which performs a  pop operation on a specific sub-stack.

    class Stack
    {
    public:
    	int top;
    	int array[10];
    
    	Stack():top(0)
    	{
    
    	}
    	void push(int num)
    	{
    		array[top] = num;
    		top ++;
    	}
    	int pop()
    	{
    		top --;
    		int result = array[top];
    		return result;
    	}
    };
    class setofstacks
    {
    public:
    	Stack* stackArray[10];
    	int x;
    	setofstacks():x(0)
    	{
    		for (int i = 0;i < 10;i++)
    		{
    			stackArray[i] = new Stack();
    		}
    	}
    	void push(int num)
    	{
    		if (stackArray[x]->top < 10)
    		{
    			stackArray[x]->push(num);
    		}
    		else
    		{
    			x++;
    			push(num);
    		}
    	}
    	int pop()
    	{
    		if (stackArray[x]->top > 0)
    		{
    			return stackArray[x]->pop();
    		}
    		else
    		{
    			x--;
    			return pop();
    		}
    	}
    	int popAt(int index)
    	{
    		return stackArray[index]->pop();
    	}
    };
    

     上面我的实现有这些问题。

    首先,数组长度固定,如果最后一个堆栈用完,无法扩展数组长度。

    其次,popAt(index)之后也许需要把后面的元素向前挪动,不然就会出现类似内存碎片一样的无法利用的空间。

    4.Write a program to move the disks from the first rod to the last using Stacks.

     关于汉诺塔的问题一直都是递归的经典问题,但是一般都是计算时间复杂度的举例,利用堆栈模拟这个过程还真不太会...

    模拟的过程实习也是一个实际问题转换为编程问题,需要进行一些抽象化。

    class Tower
    {
    public:
    	//
    	stack<int>* disks;
    	int num;
    	Tower(int i):num(i)
    	{
    		disks = new stack<int>();
    	}
    	int index()
    	{
    		return num;
    	}
    	void add(int d)
    	{
    		if (!disks->empty() && disks->top() <= d)
    		{
    			return;
    		}
    		else
    		{
    			disks->push(d);
    		}
    	}
    	void movetopto(Tower* t)
    	{
    		int top = disks->top();
    		disks->pop();
    		t->add(top);
    		cout<<"Move disk"<<top<<"from"<<index()<<"to"<<t->index()<<endl;
    	}
    	void moveDisks(int n,Tower* dst,Tower* buffer)
    	{
    		if (n>0)
    		{
    			moveDisks(n-1,buffer,dst);
    			movetopto(dst);
    			buffer->moveDisks(n-1,dst,this);
    		}
    	}
    };
    

    5.Implement a MyQueue class which implements a queue using two stacks.

    class queue
    {
    public:
    	Stack* stacktwo[2];
    	queue()
    	{
    		for (int i = 0;i < 2;i++)
    		{
    			stacktwo[i] = new Stack();
    		}
    	}
    	void push(int num)
    	{
    		stacktwo[0]->push(num);
    	}
    	int pop()
    	{
    		if (stacktwo[1]->top == 0)
    		{
    			while (stacktwo[0]->top != 0)
    			{
    				stacktwo[1]->push(stacktwo[0]->pop());
    			}
    		}
    		return stacktwo[1]->pop();
    	}
    };
    

     一个堆栈存放push()进来的元素,pop()的时候直接pop()另外一个堆栈,如果空了则将第一个堆栈中的元素添加进来,再执行pop()操作,这样两次之后就是先进先出的队列。

    6.Write a program to sort a stack in ascending order.You should not make any assumptions about how the stack is implemented.The following are the only functions that should be used to write this program:push|pop|peek|isEmpty.

     copy code from the book:

    public static Stack<Interger> sort(Stack<Integer> s)
    {
        Stack<Integer> r = new Stack<Integer>();
        while(!s.isEmpty())
        {
            int tmp = s.pop();
            while(!r.isEmpty() && r.peek() > tmp)
                s.push(r.pop());
            r.push(tmp)
        }
        return r;
    }
    
  • 相关阅读:
    JAVA 关键字
    github 上传代码到仓库

    创建链表及使用
    关于MAP文件的使用(转贴)
    styledcomponent使用(一)
    关于EDM模型中多个实体之间循环引用导致保存数据失败的解决方案一例
    C#格式化字符串
    [原]存取AVD设备SD卡中的文件
    NSStirng、NSArray、以及枚举(Method小集合)
  • 原文地址:https://www.cnblogs.com/weixliu/p/3316827.html
Copyright © 2011-2022 走看看