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

由于之前看了牛客网的数据结构和算法的课程知道了左神,现在找到了这本书当作入门书做做吧,虽然书的题解都是java实现的,但好在用c++实现难度不大。

第一章 栈和队列

题目1:单调栈结构
给定一个不含有重复值数组arr找到每一个i位置左边和右边离i位置最近且值比arr[i]小的位置。返回所有位置相应的信息。

方法一:无脑遍历时间复杂度O(n^2),每个位置分别向左和向右遍历一下,总可以确定

#include "stdafx.h"
#include<iostream>
#include <iomanip>
using namespace std;
int ** rightWay(int arr[] ,  int size)
{
	//如果要返回二维数组,只能返回指向二维数组的指针,首先在栈中申请一个元素为一位数组的数组
	int **res=new int*[size];

	for (int i=0;i<size;++i)
	{
		//再在栈中为一位数组申请储存空间
		res[i]=new int[2];
		int leftIndex,rightIndex,lefti=i-1,righti=i+1;
		if (i==0)
		{
			leftIndex=-1;
		}
		if (i==size-1)
		{
			rightIndex=-1;
		}
		for (;i!=0&&arr[lefti]>arr[i]&&lefti>=0;lefti--)
		{
		}
		if (lefti==-1)
		{
			leftIndex=-1;
		}
		else{leftIndex=lefti;}
		for (;i!=0&&arr[righti]>arr[i]&&righti<=6;righti++)
		{
		}
		if (righti==7)
		{
			rightIndex=-1;
		}
		else{rightIndex=righti;}
		res[i][0]=leftIndex;
		res[i][1]=rightIndex;
		
	}
	return res;
}

int _tmain(int argc, _TCHAR* argv[])
{
	int arr1[7]={3,4,1,5,6,2,7};
	int**p=rightWay(arr1,7);
	for (int A=0;A<7;++A)
	{
		std::cout<<"{";bool a=1;
		for (int B=0;B<2;++B)
		{
			std::cout<<setw(2)<<p[A][B];
			if (a)
			{
				cout<<",";a=0;
			}
		}
		std::cout<<"}"<<std::endl;
	}
	return 0;
}


方法二:单调栈结构,关键在于生成所有位置的相应信息,时间复杂度做到O(n)

//由于会出现重复的元素,于是在栈中的元素从之前的int变成了queue<int>
#include "stdafx.h"
#include <iostream>
#include <stack>
#include <iomanip>
using namespace std;
int** MonotoneStackArchitecture1(int arr[],int size){
    //如果要返回二维数组,只能返回指向二维数组的指针,首先在栈中申请一个元素为一位数组的数组
	int**res=new int*[size];
	stack<int>stack1;
	for(int i=0;i<size;++i){
	    //再在栈中为一位数组申请储存空间
		res[i]=new int[2];
		}
	for(int i=0;i<size;++i){

		if(stack1.empty()||arr[stack1.top()]<arr[i]){
			stack1.push(i);
		}
		else
		{
			while(!stack1.empty()&&arr[stack1.top()]>arr[i]){
				int tmp=stack1.top();
				stack1.pop();
				if (stack1.empty())
				{
					res[tmp][0]=-1;
				}
				else
					res[tmp][0]=stack1.top();
				res[tmp][1]=i;
			}
			stack1.push(i);//之前数据一直不对,就是因为没有把元素右侧最近的元素位置压入栈中。
		}
	}
	while(!stack1.empty()){
		int tmp=stack1.top();
		stack1.pop();
		if (stack1.empty())
		{
			res[tmp][0]=-1;
		}
		else res[tmp][0]=stack1.top();
		res[tmp][1]=-1;	
	}
	return res;
}
int _tmain(int argc, _TCHAR* argv[])
{
	int arr1[7]={3,4,1,5,6,2,7};
	int**p=MonotoneStackArchitecture1(arr1,7);
	for (int A=0;A<7;++A)
	{
		std::cout<<"{";bool a=1;
		for (int B=0;B<2;++B)
		{
			std::cout<<setw(2)<<p[A][B];
			if (a)
			{
				cout<<",";a=0;
			}
		}
		std::cout<<"}"<<std::endl;
	}
	return 0;
}


题目1.1:单调栈结构(进阶)

给定一个含有重复值数组arr找到每一个i位置左边和右边离i位置最近且值比arr[i]小的位置。返回所有位置相应的信息。

// 由于会出现重复的元素,于是将栈中的元素从int改成了queue<int>
#include "stdafx.h"
#include <iostream>
#include <stack>
#include <iomanip>
#include <queue>
using namespace std;
int** MonotoneStackArchitecture1(int arr[],int size){
	int**res=new int*[size];
	stack<queue<int> >stack1;
	for(int i=0;i<size;++i){
		res[i]=new int[2];
	}
	for(int i=0;i<size;++i){
		if(stack1.empty()||arr[stack1.top().back()]<arr[i]){
			queue<int> queue1;
			queue1.push(i);
			stack1.push(queue1);
		}
		else
		{
			while(!stack1.empty()&&arr[stack1.top().back()]>arr[i]){
				queue<int> tmpQ=stack1.top();//总是用一个tmp来记录直接被弹出的单调栈的元素
				stack1.pop();
				if(stack1.empty())
				{
					while(!tmpQ.empty()){
						int tmp=tmpQ.back();
						tmpQ.pop();
						res[tmp][0]=-1;
						res[tmp][1]=i;
					};
				}
				else{
					while(!tmpQ.empty()){
						int tmp=tmpQ.front();
						tmpQ.pop();//原先一直有三个数据没有被赋值,错在tmpQ.pop()这里pop出去的元素并不是t.back(),而是tmpQ.front()
						res[tmp][0]=stack1.top().back();
						res[tmp][1]=i;
					};
				}
			}
			if (!stack1.empty()&&!stack1.top().empty()&&arr[stack1.top().back()]==arr[i])//判断条件之前没加  !stack1.empty()&&!stack1.top().empty()  然后报错
			{
				cout<<1<<endl;
				stack1.top().push(i);//之前数据一直不对,就是因为没有把元素右侧最近的元素位置压入栈中。
			}
			else{
				queue<int> queue1;
				queue1.push(i);
				stack1.push(queue1);
			}
		}
	}
	while(!stack1.empty()){
		queue<int> tmpQ=stack1.top();
		stack1.pop();
		if(stack1.empty())
		{
			while(!tmpQ.empty()){
				int tmp=tmpQ.front();//原先一直有三个数据没有被赋值,错在tmpQ.pop()这里pop出去的元素并不是t.back(),而是tmpQ.front()
				tmpQ.pop();
				res[tmp][0]=-1;
				res[tmp][1]=-1;
			};
		}
		else{
			while(!tmpQ.empty()){
				int tmp=tmpQ.front();//原先一直有三个数据没有被赋值,错在tmpQ.pop()这里pop出去的元素并不是t.back(),而是tmpQ.front()
				tmpQ.pop();
				res[tmp][0]=stack1.top().back();
				res[tmp][1]=-1;
			};
		}
	}
	return res;
}
int _tmain(int argc, _TCHAR* argv[])
{
	int arr1[9]={3,1,3,4,3,5,3,2,2};
	int**p=MonotoneStackArchitecture1(arr1,9);
	for (int A=0;A<9;++A)
	{
		std::cout<<"{";bool a=1;
		for (int B=0;B<2;++B)
		{
			std::cout<<setw(2)<<p[A][B];
			if (a)
			{
				cout<<",";a=0;
			}
		}
		std::cout<<"}"<<std::endl;
	}
	delete p;
	return 0;
}


猜你喜欢

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