一:元素出栈、入栈顺序的合法性。如入栈的序列(1,2,3,4,5),出栈序列为(4,5,3,2,1)。
思路:假设现在有两个数组arr1[]和arr2[],分别保存出栈和入栈的序列,有一个索引index从0开始,指向arr1,有一个出栈索引outdex指向从0开始指向arr2,用arr1[index]与arr2[outdex]相比较,如果相等,index++,outdex++,然后继续比较,如果不相等,index++,上面的两个序列在第一次相等是inde与outdex的指向就如下图所示,
接下来继续走,直到任意一个数组越界,如下图:
此时,index已经越界,但是outdex还指向数组内,我们也没有比较完,因此我们就需要有一个数据结构来保存之前不想等的数据,而这个数据结构就是栈,具体代码实现如下:代码中用到的栈的操作可参考
https://blog.csdn.net/virgofarm/article/details/80065574
#include<stdio.h>
#include<assert.h>
#include<windows.h>
int StackIsLegal(int* arr, int size, int* arr2, int size2)
{
Stack s;
StackInit(&s);
int index = 0;
int outdex = 0;
assert(arr);
assert(arr2);
//两个数组大小都不一样,肯定不合法
if (size != size2)
return 0;
while (index < size)
{
//如果两个数组中的内容不相等,就让arr中的元素入栈
if (arr[index] != arr2[outdex] && index < size)
{
StackPush(&s, arr[index]);
index++;
}
//相等
if (arr[index] == arr2[outdex])
{
index++;
outdex++;
}
}
while (!StackEmpty(&s))
{
//如果数组arr访问完了,就拿栈顶元素
if (StackTop(&s) == arr2[outdex])
{
StackPop(&s);
outdex++;
}
//没进入if肯定不合法
return 0;
}
if (outdex >= size2)
return 1;
else
return 0;
}
int main()
{
int arr[] = { 1, 2, 3, 4, 5 };
int arr2[] = { 4, 5, 3, 2, 1 };
int size = sizeof(arr) / sizeof(arr[0]);
int size2 = sizeof(arr2) / sizeof(arr2[0]);
printf("%d\n", StackIsLegal(arr, size, arr2, size2));
system("pause");
return 0;
}
二:一个数组实现两个栈(共享栈)
思路:这个题思路比较简单,我们可以将数组分为两部分,下标为偶数的封装为一个栈,下标为奇数的封装为一个栈,这样就可以用一个数组实现两个栈,但这样做不太好,因为假设你只向偶数栈中插入元素,直到偶数栈满了,但实际上数组还有空间,但是你并不能再插入元素了,这样就造成很大的空间浪费。具体代码实现如下:
StackAndInterview.c
#include "StackAndInterview.h"
void StackInit(PSStack s)
{
assert(s);
s->Top1 = 0;//偶数栈从0开始
s->Top2 = 1;//奇数栈从1开始
}
void StackPush(PSStack s, int flag, DataType data)
{
assert(s);
if (flag == 1)//入到偶数栈
{
if (s->Top1 == MAX_SIZE)
{
printf("栈已满!\n");
return;
}
s->arr[s->Top1] = data;
s->Top1 += 2;
}
else
{
if (s->Top1 > MAX_SIZE)
{
printf("栈已满!\n");
return;
}
s->arr[s->Top2] = data;
s->Top2 += 2;
}
}
void StackPop(PSStack s, int flag)
{
assert(s);
if (flag == 1)//出栈1
{
if (s->Top1 == 0)
{
printf("栈已空!\n");
return;
}
s->Top1 -= 2;
}
else
{
if (s->Top2 == 1)
{
printf("栈已空!!!\n");
return;
}
s->Top2 -= 2;
}
}
int StackSize(PSStack s, int flag)
{
assert(s);
if (flag == 1)
return s->Top1 / 2;
else
return s->Top2 / 2;
}
int StackEmpty(PSStack s, int flag)
{
assert(s);
if (flag == 1)
{
if (s->Top1 == 0)
return 1;
return 0;
}
else
{
if (s->Top2 == 1)
return 1;
else
return 0;
}
}
DataType StackTop(PSStack s, int flag)
{
assert(s);
if (flag == 1)
{
if (s->Top1 == 0)
{
printf("栈已空!\n");
return 0;
}
return s->arr[s->Top1 - 2];
}
else
{
if (s->Top2 == 1)
{
printf("栈已空!\n");
return 0;
}
return s->arr[s->Top2 - 2];
}
}
StackAndInterview.h
#pragma once
#include <assert.h>
#include <stdio.h>
#define MAX_SIZE 10
typedef int DataType;
typedef struct ShareStack
{
DataType arr[MAX_SIZE];
int Top1;//栈1用数组的偶数下标
int Top2;//栈2用数组的奇数下标
}SStack, *PSStack;
void StackInit(PSStack s);
void StackPush(PSStack s, int flag, DataType data);
void StackPop(PSStack s, int flag);
int StackSize(PSStack s, int flag);
int StackEmpty(PSStack s, int flag);
DataType StackTop(PSStack s, int flag);
test.c
#include "StackAndInterview.h"
#include <Windows.h>
void Test6()
{
SStack s;
StackInit(&s);
StackPush(&s, 1, 1);
StackPush(&s, 1, 3);
StackPush(&s, 1, 5);
StackPush(&s, 1, 7);
StackPush(&s, 1, 9);
printf("S1Top = %d\n", StackTop(&s, 1));
StackPush(&s, 2, 2);
StackPush(&s, 2, 4);
StackPush(&s, 2, 6);
StackPush(&s, 2, 8);
StackPush(&s, 2, 10);
printf("S2Top = %d\n", StackTop(&s, 2));
StackPop(&s, 1);
printf("S1Top = %d\n", StackTop(&s, 1));
printf("S1Size = %d\n", StackSize(&s, 1));
printf("S2Size = %d\n", StackSize(&s, 2));
}
int main()
{
//Test1();//面试题1方法1
//Test2();//面试题方法2
//Test3();//面试题2
//Test4();//面试题3
//Test5();//面试题4
Test6();//面试题5
system("pause");
return 0;
}