《程序员代码面试指南》it名企算法与数据结构题目最优解(第二版)刷题笔记day1

由于之前看了牛客网的数据结构和算法的课程知道了左神,现在顺便就买了他的书做做题吧,虽然书的题解都是java实现的,但好在用c++实现难度不大。

第一章 栈和队列

题目一设计一个支持 push,pop,top 操作,并能在常数时间内检索到最小元素的栈。

push(x) – 将元素 x 推入栈中。
pop() – 删除栈顶的元素。
top() – 获取栈顶元素。
getMin() – 检索栈中的最小元素。

class MinStack {
public:
	MinStack() {
	}
	void push(int x) {
		databace.push(x);
		if (stackMin.empty()||x<=stackMin.top())
		{
			stackMin.push(x);
		}
		else{

			stackMin.push(stackMin.top());
		}
	}

	void pop() {
		databace.pop();
		stackMin.pop();
	}

	int top() {
		return databace.top();
	}

	int getMin() {
		return stackMin.top();
	}
private:
    //用database和stackMin两个栈实现
	stack<int> databace;//保存当前栈中的元素	
	stack<int> stackMin;//保存每一步的最小值
};

题目二使用栈实现队列的下列操作:

push(x) – 将一个元素放入队列的尾部。
pop() – 从队列首部移除元素。
peek() – 返回队列首部的元素。
empty() – 返回队列是否为空。

class MyQueue {
public:
	int a;
	MyQueue() {
	}
	void push(int x) {
		stackpush.push(x);
	}
	void push1(){
		while(!stackpush.empty()){
			stackpop.push(stackpush.top());
			stackpush.pop();
		}
	}
	int pop() {
		if (stackpop.empty())
		{
			while (!stackpush.empty())
			{
				push1();
			}
		}
		a=stackpop.top();
		stackpop.pop();
		return a;
	}
	int peek() {
		if (stackpop.empty())
		{
			while(!stackpush.empty()){
				push1();
			}
		}
		a=stackpop.top();
		return a;
	}
	bool empty() {
		if (stackpop.empty()&&stackpush.empty())
		{
			return true;
		}else return false;
	}
private:
    //两个栈实现队列:1.如果stackpush要往stackpop中压入数据,那么必须一次性把stackpush中的数据全部压入。
    //               2.如果stackpop不为空,stackpush绝对不能向stackpop中压入数据
	stack<int> stackpush;//压入栈,在压入数据是只往这个栈中压入
	stack<int> stackpop;//弹出栈,在弹出数据时只从这个栈弹出
};

题目三如何仅用递归函数和栈操作逆序一个栈:一个栈依次压入1,2,3,4,5,那么从栈顶到栈底分别为5,4,3,2,1。将这个栈转置后,从栈顶到栈底为1,2,3,4,5,也就是实现栈中元素的逆序,但是只能用递归函数来实现,不能用其他数据结构。

#include "stdafx.h"
#include <iostream>
#include <stack>
using namespace std;
//递归函数一:将栈底元素返回并删除
int getAndRemoveLastElement(stack<int> &a){   //pass-by-reference
	int last=a.top();
	a.pop();
	if (a.empty())
	{
		return last;
	}
	else{
		int b=getAndRemoveLastElement(a);
		a.push(last);
		return b;
	}
}
//递归函数二:逆序一个栈,就是题目要求实现的方法,该方法用到了第一个递归函数
void reverse(stack<int> &stack){   //pass-by-reference
	if(stack.empty()){
		return ;
	}
	int c=getAndRemoveLastElement(stack);
	reverse(stack);
	stack.push(c);
}
int main(){
	stack<int> a;
	for (int s=0;s<10;++s)
	{
		a.push(s);
	}
	reverse(a);
	int b;
	for (int s=0;s<10;++s)
	{
		b=a.top();
		a.pop();
		std::cout<<b<<" "<<std::endl;
	}
	return 0;
}

题目四猫狗队列
宠物、狗和猫的类如下:

public class Pet{
        private String type;
        public Pet(String type){
            this.type = type;          
        }
        public String getPetType(){
            return this.type;
        }
    }
    public class Dog extends Pet {
        public Dog(){
            super("dog");
        }
    }
    public class Cat extends Pet{
        public Cat(){
            super("cat");
        }
    }

实现一种猫狗队列的结构,要求如下:

1.用户可以调用add方法将cat类或者dog类的实例放入队列中;
2.用户可以调用pollAll方法,将队列中所有的实例按照队列的先后顺序依次弹出;
3.用户可以调用pollDog方法,将队列中dog类的实例按照队列的先后顺序依次弹出;
4.用户可以调用pollCat方法,将队列中cat类的实例按照队列的先后顺序依次弹出;
5.用户可以调用isEmpty方法,检查队列中是否还有dog和cat的实例;
6.用户可以调用isDogEmpty方法,检查队列中是否还有do的实例;
7.用户可以调用isCatEmpty方法,检查队列中是否还有cat的实例。

#pragma once
#include <string>
#include <queue>
#include <iostream>
using namespace std;
//本题应实现将不同的实例盖上时间戳的方法,但是又不能改变用户本身的类,所以定义一个新的类
//c++实现宠物、猫、狗类
class Pet{
public:
	Pet(string type){
		this->type = type;          
	}
	Pet(){};
	string getPetType(){
		return this->type;
	}
private: 
	string type;
};
class Dog : public Pet {
public:
	Dog():Pet("dog"){//这里原先代码是:Dog(){Pet::Pet("dog")}报错,原因是:在构造派类时,会先调用基类的构造函数,再执行派生类构造函数。而你的写法是告诉程序在执行派生类构造函数时,把基类的构造函数作为一个普通函数进行调用。而在派生类构造函数之前调用的基类构造函数并没有声明,因此会报错
	}
};
class Cat : public Pet{
public:
	Cat():Pet("cat"){
	}
};

//分割-----------------------------------------------------------------------------
//定义的新的类peterPetQueue
class peterPetQueue{
public:
	long getLong(){
		return b;
	}
	peterPetQueue(Pet a1,long b1){
		this->a=a1;
		this->b=b1;
	}
private:
	Pet a; //用户原有的实例
	long b;//时间戳
};
//大体来说,首先有一个不断累加的数据项,用来表示实例进队列的时间;同时有两个队列,一个是只放dog类实例的队列DogQueue,同理另一个为CatQueue
class catAndDog
{
public:
	catAndDog(){
		this->count1=0;
	}
	void add(Pet item){//这里原先报错:Error LNK2001 无法解析的外部符号 原因是我在基类Pet中的Pet()只是声明,没有给出定义
		if (item.getPetType()=="cat")
		{
			CatQueue.push(peterPetQueue(item,count1++));
		}
		else{
			DogQueue.push(peterPetQueue(item,count1++));
		}
	}
	void pollDog(){
		while(!DogQueue.empty()){
			DogQueue.pop();
		}
	}
	void pollCat(){
		while(!CatQueue.empty())
			CatQueue.pop();
	}
	bool isEmpty(){
		if (CatQueue.empty()&&DogQueue.empty())
		{
			return true;
		}
		else return false;
	}
	bool isDogEmpty(){
		if (DogQueue.empty())
		{
			return true;
		}
		else return false;
	}
	bool isCatEmpty(){
		if (CatQueue.empty())
		{
			return true;
		}
		else return false;
	}
	void pollAll(){
		while(!DogQueue.empty()&&!CatQueue.empty()){
			if (DogQueue.front().getLong()>CatQueue.front().getLong())
			{
				CatQueue.pop();
			}
			else DogQueue.pop();
		}
		if (!DogQueue.empty())
		{
			DogQueue.pop();
		}
		if (!CatQueue.empty())
		{
			CatQueue.pop();
		}
	}

private:
	queue<peterPetQueue> CatQueue;
	queue<peterPetQueue> DogQueue;
	long count1;
};


猜你喜欢

转载自blog.csdn.net/qq_43241311/article/details/88631339