看完了书,准备把书中的代码全部手敲一遍,正好九度上有《剑指Offer》的专题,于是就在上面做了。原题不贴,只贴代码及简单解释。部分题目仅从Oj的角度看是没什么意思的,必须按照题目的要求来解才有意义。虽然平时项目用的代码多是java,但a题还是喜欢用C/C++。
题目1384:二维数组中的查找
两种思路:书上的思路是从右上或者左下开始搜索,一次排除一行或一列。另一种思路是逐行排除,因为是有序的,因此可以用二分。下面是两种思路的代码:
#include <cstdio>
using namespace std;
const int MAX=1000;
int matrix[MAX][MAX];
bool findNumber(int m,int n,int t)
{
bool sign=0;
if (m>0&&n>0&&matrix!=NULL)
{
int row = 0,column = n-1;
while (row<m&&column>=0)
{
if (t==matrix[row][column])
{
sign = true;
break;
}else if (t>matrix[row][column])
{
row++;
}else
{
column--;
}
}
}
return sign;
}
int main()
{
int m(0),n(0),t(0);
while(scanf("%d %d",&m,&n)!=EOF)
{
scanf("%d",&t);
for(int i=0;i<m;++i)
{
for(int j=0;j<n;++j)
{
scanf("%d",&matrix[i][j]);
}
}
if(findNumber(m,n,t))
printf("Yes\n");
else
printf("No\n");
}
}
#include <cstdio>
using namespace std;
const int MAX=1000;
int matrix[MAX][MAX];
int main()
{
int m(0),n(0),t(0);
while(scanf("%d %d",&m,&n)!=EOF)
{
scanf("%d",&t);
int size(n-1);
for(int i=0;i<m;++i)
{
for(int j=0;j<n;++j)
{
scanf("%d",&matrix[i][j]);
}
}
int sign=0;
for(int i=0;0==sign && i<m;++i)
{
if(t<matrix[i][0])
{
sign=0;
break;
}
else if(t>matrix[i][size])
{
continue;
}
else
{
int low(0),high(size);
while(low<=high)
{
int mid=(low+high)/2;
if(matrix[i][mid]==t)
{
sign=1;
break;
}
else if(matrix[i][mid]<t)
{
low=mid+1;
}
else
{
high=mid-1;
}
}
}
}
if(sign)
printf("Yes\n");
else
printf("No\n");
}
}
题目1510:替换空格
思路是从后往前替换,代码如下:
#include <stdio.h>
#include <string.h>
int main(void){
char str[1000001];
int len;
int new_len;
int i;
int cnt;
gets (str);
len = strlen (str);
cnt = 0;
for (i=0; i<len; ++i){
if (str[i] == ' ')
++cnt;
}
new_len = len + 2 * cnt;
str[new_len] = '\0';
--len;
--new_len;
while (len >= 0&&new_len>len){
if (str[len] != ' '){
str[new_len] = str[len];
--new_len;
}
else{
str[new_len--] = '0';
str[new_len--] = '2';
str[new_len--] = '%';
}
--len;
}
puts (str);
return 0;
}
题目1511:从尾到头打印链表
这个没什么好说的,用栈,代码如下:
#include <cstdio>
#include <stack>
using namespace std;
const int MAX=10000;
int main()
{
int number;
std::stack<int> stackNumber;
while(scanf("%d",&number)!=EOF&&number!=-1)
{
stackNumber.push(number);
}
while (!stackNumber.empty()) {
printf("%d\n",stackNumber.top());
stackNumber.pop();
}
return 0;
}
题目1385:重建二叉树
根据前序遍历和中序遍历的特点先构建出此二叉树来,再输出其后序遍历序列。代码如下:
#include <cstdio>
#include <stack>
using namespace std;
bool findTree = false;
typedef struct Node
{
int value;
Node * left;
Node * right;
Node(int value)
{
this->value = value;
left = right = NULL;
}
}TreeNode;
TreeNode* RebuildTree(int *startPreOrder,int *endPreOrder,int *startMidOrdre,int *endMidOrdre){
int rootPreeValue =startPreOrder[0];
TreeNode* root=new Node(rootPreeValue);
if (startPreOrder==endPreOrder) {
if (startMidOrdre==endMidOrdre&&*startPreOrder==*startMidOrdre) {
return root;
}else{
findTree = false;
return root;
}
}
int *midRoot = startMidOrdre;
while (midRoot<endMidOrdre&&*midRoot!=rootPreeValue) {
midRoot++;
}
if (midRoot==endMidOrdre&&*midRoot!=rootPreeValue) {
findTree = false;
return root;
}
long leftLength = midRoot - startMidOrdre;
if (leftLength>0) {
root->left =RebuildTree(startPreOrder+1,startPreOrder+leftLength,startMidOrdre,midRoot-1);
}
if (endPreOrder-startPreOrder-leftLength>0) {
root->right =RebuildTree(startPreOrder+leftLength+1,endPreOrder,midRoot+1,endMidOrdre);
}
return root;
}
void printTree(TreeNode* tree){
if (tree==NULL) {
return;
}
if (tree->left!=NULL) {
printTree(tree->left);
}
if (tree->right!=NULL) {
printTree(tree->right);
}
printf("%d ",tree->value);
}
int main()
{
int number;
int preOrder[1000],midOrder[1000];
while(scanf("%d",&number)!=EOF)
{
if (number<=0) {
printf("No\n");
}
for (int i=0; i<number; i++) {
scanf("%d",&preOrder[i]);
}
for (int i=0; i<number; i++) {
scanf("%d",&midOrder[i]);
}
findTree = true;
TreeNode* tree =RebuildTree(preOrder,preOrder+number-1,midOrder,midOrder+number-1);
if (findTree) {
printTree(tree);
printf("\n");
}else{
printf("No\n");
}
}
return 0;
}
题目1512:用两个栈实现队列
栈1存储新插入的,栈2负责输出,栈2为空时,把栈1的数据倒过去。代码如下:
#include <cstdio>
#include <stack>
#include <vector>
#include <iostream>
using namespace std;
stack<int> st1,st2;
void pop(){
if (st2.size()<=0) {
while (!st1.empty()) {
int value = st1.top();
st1.pop();
st2.push(value);
}
}
if (st2.empty()) {
printf("-1\n");
}else{
printf("%d\n",st2.top());
st2.pop();
}
}
void push(int val){
st1.push(val);
}
int main()
{
int m,n;
char operStr[15];
scanf("%d",&m);
for (int i=0; i<m; i++) {
scanf("%s",operStr);
if (operStr[1]=='U') {
scanf("%d",&n);
push(n);
}else{
pop();
}
}
return 0;
}
题目1386:旋转数组的最小数字
二分查找的灵活应用,注意特殊情况,代码如下:
#include <cstdio>
#include <stack>
#include <vector>
#include <iostream>
using namespace std;
int MinInorder(int *data,int index1,int index2){
int result=data[index1];
for (index1+=1; index1<=index2; index1++) {
if (result>data[index1]) {
result = data[index1];
}
}
return result;
}
int Min(int data[],int index1,int index2){
int midIndex = index1;
while (data[index1]>=data[index2]) {
if (index2-index1==1) {
midIndex=index2;
break;
}
midIndex = (index2+index1)/2;
if (data[index2]==data[index1]&&data[index2]==data[midIndex]) {
return MinInorder(data,index1,index2);
}
if (data[index1]<=data[midIndex]) {
index1=midIndex;
}else if (data[index2]>=data[midIndex]){
index2 = midIndex;
}
}
return data[midIndex];
}
int main()
{
int m;
while (scanf("%d",&m)!=EOF) {
int data[m];
for (int i=0; i<m; i++) {
scanf("%d",&data[i]);
}
if (m>0) {
printf("%d\n",Min(data,0,m-1));
}
}
return 0;
}
题目1387:斐波那契数列(题目1388:跳台阶、题目1390:矩形覆盖(后两题的初始值为1和2),不再贴)
别用递归就行,代码如下:
#include <cstdio>
#include <string>
using namespace std;
long long getFBNQ(int n){
if (n==0) {
return 0;
}else if(n==1){
return 1;
}
long long number1(0),number2(1),result;
long long index=2;
while (index++<=n) {
result = number1 + number2;
number1 = number2;
number2 = result;
}
return result;
}
int main()
{
int num;
while (scanf("%d",&num)!=EOF) {
printf("%lld\n",getFBNQ(num));
}
return 0;
}
题目1389:变态跳台阶
找完规律后,发现这道题最简单了,代码如下:
#include <cstdio>
#include <math.h>
using namespace std;
long long getFBNQ(int n){
if (n>0) {
return pow(2,n-1);
}else{
return 0;
}
// if (n==1) {
// return 1;
// }else if(n==2){
// return 2;
// }
// long long data[50],result;
// data[0]=1,data[1]=2;
// long long index=2;
// while (index<n) {
// result=0;
// for (int i=0; i<index; i++) {
// result+=data[i];
// }
// data[index]=result+1;
// index++;
// }
// return result+1;
}
int main()
{
int num;
while (scanf("%d",&num)!=EOF) {
printf("%lld\n",getFBNQ(num));
}
return 0;
}
题目1513:二进制中1的个数
利用一个数与这个数减1后的数相与,去掉最后一个1的特性,代码如下:
#include <cstdio>
#include <math.h>
using namespace std;
char numberOf1(int number){
char count=0;
while (number) {
count++;
number=number&(number-1);
}
return count;
}
int main()
{
int num,data;
scanf("%d",&num);
for (int i=0; i<num; i++) {
scanf("%d",&data);
printf("%d\n",numberOf1(data));
}
return 0;
}
题目1514:数值的整数次方
注意次数为负的情况及浮点等于的判断,代码如下:
#include <cstdio>
using namespace std;
double pow(double base,int exponent){
if (exponent==0) {
return 1;
}else if(exponent==1){
return base;
}
double result=pow( base, exponent>>1);
result *= result;
if (exponent&1) {
result*=base;
}
return result;
}
bool equle0(double base){
if (base<0.0000001&&base>-0.0000001) {
return true;
}
return false;
}
void powOfDouble(double base,int exponent){
if (equle0(base)) {
if (exponent<0) {
printf("INF\n");
}else{
printf("%.2ef\n",0.0);
}
return ;
}
double result = pow(base,exponent>0?exponent:-exponent);
printf("%.2ef\n",exponent>0?result:1.0/result);
}
int main()
{
int num,exponent;
double base;
scanf("%d",&num);
for (int i=0; i<num; i++) {
scanf("%lf %d",&base,&exponent);
powOfDouble(base,exponent);
}
return 0;
}
题目1515:打印1到最大的N位数
这个要求比书中降低了,代码如下:
#include <cstdio>
#include <math.h>
//#include <iostream.h>
using namespace std;
int main()
{
int num,data;
scanf("%d",&num);
data=pow(10,num);
for (int i=1; i<data; i++) {
printf("%d\n",i);
//cout<<i<<endl;
}
return 0;
}
题目1516:调整数组顺序使奇数位于偶数前面
偶数和偶数之间的相对位置不变比较麻烦,最后只能增加了O(n)的空间,以空间换取时间,代码如下:
#include <cstdio>
using namespace std;
int main()
{
int num,countOfOdd=0;
scanf("%d",&num);
int data[num],data1[num];
for (int i=0; i<num; i++) {
scanf("%d",&data[i]);
if (data[i]&1) {
countOfOdd ++ ;
}
}
int index=0;
for (int i=0; i<num; i++){
if (data[i]&1){
data1[index++]=data[i];
}else{
data1[countOfOdd++]=data[i];
}
}
printf("%d",data1[0]);
for (int i=1; i<num; i++){
printf(" %d",data1[i]);
}
return 0;
}
题目1517:链表中倒数第k个结点
用前后两个指针,注意边界判断,代码如下:
#include <cstdio>
using namespace std;
struct Node {
int val;
Node *next;
Node(int x) : val(x), next(NULL) {}
};
int main()
{
int n,k,val;
Node *head;
while (scanf("%d%d",&n,&k)!=EOF) {
scanf("%d",&val);
head = new Node(val);
Node *node = head;
for (int i=1; i<n; i++) {
scanf("%d",&val);
Node *nodeNew = new Node(val);
node->next=nodeNew;
node = nodeNew;
}
if (k>n||k<=0) {
printf("NULL\n");
continue;
}else{
node = head;
for (int i=0; i<k-1; i++) {
node = node->next;
}
while (node->next!=NULL) {
node = node->next;
head = head->next;
}
printf("%d\n",head->val);
}
}
return 0;
}
题目1518:反转链表
两种思路,一种是重新起一个链表,每遍历一个结点,将此结点插到前面结点的前面,另一种方法是修改链表的指针指向,实现反转,下面的代码实现的是前者:
#include <cstdio>
//#include <iostream.h>
using namespace std;
struct Node {
int val;
Node *next;
Node(int x) : val(x), next(NULL) {}
};
void revertList(Node **head){
Node *pHead = (*head)->next;
Node *nextNode;
(*head)->next=NULL;
while (pHead!=NULL) {
nextNode=pHead->next;
pHead->next = *head;
*head = pHead;
pHead = nextNode;
}
}
int main()
{
int n,val;
while (scanf("%d",&n)!=EOF) {
if (n==0) {
printf("NULL\n");
continue;
}
scanf("%d",&val);
Node *head = new Node(val);
Node *node=head;
for (int i=1; i<n; i++) {
scanf("%d",&val);
Node *tmpNode = new Node(val);
node->next=tmpNode;
node=tmpNode;
}
revertList(&head);
node = head;
if (node!=NULL) {
printf("%d",node->val);
node=node->next;
}
while (node!=NULL) {
printf(" %d",node->val);
node=node->next;
}
printf("\n");
}
return 0;
}
题目1519:合并两个排序的链表
思路当然是比较每个链表的最前面元素,注意为NULL的情况,可用递归,也可用循环,代码如下:
递归:
#include <cstdio>
//#include <iostream.h>
using namespace std;
struct Node {
int val;
Node *next;
Node(int x) : val(x), next(NULL) {}
};
Node* Merge(Node* pHead1, Node* pHead2)
{
if(pHead1 == NULL)
return pHead2;
else if(pHead2 == NULL)
return pHead1;
Node* pMergedHead = NULL;
if(pHead1->val < pHead2->val)
{
pMergedHead = pHead1;
pMergedHead->next = Merge(pHead1->next, pHead2);
}
else
{
pMergedHead = pHead2;
pMergedHead->next = Merge(pHead1, pHead2->next);
}
return pMergedHead;
}
int main()
{
int m,n,val;
while (scanf("%d%d",&m,&n)!=EOF) {
if (n<=0&&m<=0) {
printf("NULL\n");
continue;
}
Node *head1=NULL, *head2=NULL,*node=NULL;
if (m>0)
{
scanf("%d",&val);
head1 = new Node(val);
node=head1;
for (int i=1; i<m; i++) {
scanf("%d",&val);
Node *tmpNode = new Node(val);
node->next=tmpNode;
node=tmpNode;
}
}
if (n>0)
{
scanf("%d",&val);
head2 = new Node(val);
node=head2;
for (int i=1; i<n; i++) {
scanf("%d",&val);
Node *tmpNode = new Node(val);
node->next=tmpNode;
node=tmpNode;
}
}
node = Merge(head1,head2);
if (node!=NULL) {
printf("%d",node->val);
node=node->next;
}
while (node!=NULL) {
printf(" %d",node->val);
node=node->next;
}
printf("\n");
}
return 0;
}
循环:
#include <cstdio>
//#include <iostream.h>
using namespace std;
struct Node {
int val;
Node *next;
Node(int x) : val(x), next(NULL) {}
};
void MergeLortList(Node **head,Node *head1,Node *head2){
if (head1==NULL)
{
*head = head2;
return;
}else if (head2==NULL)
{
*head = head1;
return;
}
Node *p1=head1,*p2=head2,*p3;
if (p1->val<=p2->val)
{
*head=p1;
p1=p1->next;
}else
{
*head=p2;
p2=p2->next;
}
p3=*head;
while (p1!=NULL&&p2!=NULL) {
if (p1->val<=p2->val)
{
p3->next=p1;
p3=p1;
p1=p1->next;
}else
{
p3->next=p2;
p3=p2;
p2=p2->next;
}
}
if (p1==NULL)
{
p3->next=p2;
}else
{
p3->next=p1;
}
}
int main()
{
int m,n,val;
while (scanf("%d%d",&m,&n)!=EOF) {
if (n<=0&&m<=0) {
printf("NULL\n");
continue;
}
Node *head1=NULL, *head2=NULL,*node=NULL;
if (m>0)
{
scanf("%d",&val);
head1 = new Node(val);
node=head1;
for (int i=1; i<m; i++) {
scanf("%d",&val);
Node *tmpNode = new Node(val);
node->next=tmpNode;
node=tmpNode;
}
}
if (n>0)
{
scanf("%d",&val);
head2 = new Node(val);
node=head2;
for (int i=1; i<n; i++) {
scanf("%d",&val);
Node *tmpNode = new Node(val);
node->next=tmpNode;
node=tmpNode;
}
}
Node *head;
MergeLortList(&head,head1,head2);
node = head;
if (node!=NULL) {
printf("%d",node->val);
node=node->next;
}
while (node!=NULL) {
printf(" %d",node->val);
node=node->next;
}
printf("\n");
}
return 0;
}
题目1520:树的子结构
前序遍历,递归判断,代码如下:
#include <cstdio>
//#include <iostream.h>
using namespace std;
struct BinaryTreeNode
{
int m_nValue;
BinaryTreeNode* m_pLeft;
BinaryTreeNode* m_pRight;
void setValue(int val){
this->m_nValue=val;
m_pLeft=m_pRight=NULL;
}
};
void constructTree(int m,BinaryTreeNode tree[]){
int val,childIndex;
if (m>0)
{
for(int i=0;i<m;i++){
scanf("%d",&val);
tree[i].setValue(val);
}
for(int i=0;i<m;i++){
scanf("%d",&val);
if (val>=1)
{
scanf("%d",&childIndex);
tree[i].m_pLeft=&tree[childIndex-1];
if (val==2)
{
scanf("%d",&childIndex);
tree[i].m_pRight=&tree[childIndex-1];
}
}
}
}
}
bool HasSubtreeCore(BinaryTreeNode* pRoot1, BinaryTreeNode* pRoot2);
bool DoesTree1HaveTree2(BinaryTreeNode* pRoot1, BinaryTreeNode* pRoot2);
bool HasSubtree(BinaryTreeNode* pRoot1, BinaryTreeNode* pRoot2)
{
bool result = false;
if(pRoot1 != NULL && pRoot2 != NULL)
{
if(pRoot1->m_nValue == pRoot2->m_nValue)
result = DoesTree1HaveTree2(pRoot1, pRoot2);
if(!result)
result = HasSubtree(pRoot1->m_pLeft, pRoot2);
if(!result)
result = HasSubtree(pRoot1->m_pRight, pRoot2);
}
return result;
}
bool DoesTree1HaveTree2(BinaryTreeNode* pRoot1, BinaryTreeNode* pRoot2)
{
if(pRoot2 == NULL)
return true;
if(pRoot1 == NULL)
return false;
if(pRoot1->m_nValue != pRoot2->m_nValue)
return false;
return DoesTree1HaveTree2(pRoot1->m_pLeft, pRoot2->m_pLeft) &&
DoesTree1HaveTree2(pRoot1->m_pRight, pRoot2->m_pRight);
}
int main()
{
int m,n,val,childIndex;
BinaryTreeNode tree1[1000], tree2[1000];
while (scanf("%d%d",&m,&n)!=EOF) {
constructTree(m,tree1);
constructTree(n,tree2);
if (n<=0||m<=0) {
printf("NO\n");
continue;
}
if(HasSubtree(tree1, tree2))
printf("YES\n");
else
printf("NO\n");
}
return 0;
}
题目1521:二叉树的镜像
找规律,前序遍历,分别交换左右结点即可,代码如下:
#include <cstdio>
//#include <iostream.h>
using namespace std;
int treeNodeNumbers;
struct BinaryTreeNode
{
int m_nValue;
BinaryTreeNode* m_pLeft;
BinaryTreeNode* m_pRight;
void setValue(int val){
this->m_nValue=val;
m_pLeft=m_pRight=NULL;
}
};
void constructTree(int m,BinaryTreeNode tree[]){
int val,childIndex;
if (m>0)
{
for(int i=0;i<m;i++){
scanf("%d",&val);
tree[i].setValue(val);
}
for(int i=0;i<m;i++){
scanf("\n%c",&val);
if (val=='d'||val=='l'||val=='r')
{
scanf("%d",&childIndex);
if (val=='l'||val=='d')
{
tree[i].m_pLeft=&tree[childIndex-1];
if (val=='d')
{
scanf("%d",&childIndex);
tree[i].m_pRight=&tree[childIndex-1];
}
}else
{
tree[i].m_pRight=&tree[childIndex-1];
}
}
}
}
}
void MirrorIteratively(BinaryTreeNode* pRoot)
{
if(pRoot == NULL||(pRoot->m_pLeft==NULL&&pRoot->m_pRight==NULL))
return;
BinaryTreeNode* pTmpTree;
pTmpTree = pRoot->m_pLeft;
pRoot->m_pLeft = pRoot->m_pRight;
pRoot->m_pRight = pTmpTree;
if (pRoot->m_pLeft!=NULL)
{
MirrorIteratively(pRoot->m_pLeft);
}
if (pRoot->m_pRight!=NULL)
{
MirrorIteratively(pRoot->m_pRight);
}
}
void PrintTree(BinaryTreeNode* pRoot)
{
if(pRoot == NULL)
return;
if (treeNodeNumbers-->1)
printf("%d ",pRoot->m_nValue);
else
printf("%d",pRoot->m_nValue);
if (pRoot->m_pLeft!=NULL)
PrintTree(pRoot->m_pLeft);
if (pRoot->m_pRight!=NULL)
PrintTree(pRoot->m_pRight);
}
int main()
{
int m,n,val,childIndex;
BinaryTreeNode tree[1000];
while (scanf("%d",&m)!=EOF) {
if (m<=0)
{
printf("NULL\n");
continue;
}
constructTree(m,tree);
MirrorIteratively(tree);
treeNodeNumbers = m;
PrintTree(tree);
}
return 0;
}
题目1391:顺时针打印矩阵
各种情况的考虑,代码如下:
#include <cstdio>
//#include <iostream.h>
using namespace std;
void printValue(int val);
int numbers[1000][1000];
void PrintMatrixInCircle( int columns, int rows){
if(numbers == NULL || columns <= 0 || rows <= 0)
return;
int start=0;
while (columns > start * 2 && rows > start * 2)
{
int endX = columns - 1 - start;
int endY = rows - 1 - start;
//从左到右打印
for(int i = start; i <= endX; ++i)
{
printValue(numbers[start][i]);
}
//从上到下
if(start < endY)
{
for(int i = start + 1; i <= endY; ++i)
{
printValue(numbers[i][endX]);
}
}
//从右到左
if(start < endX && start < endY)
{
for(int i = endX - 1; i >= start; --i)
{
printValue(numbers[endY][i]);
}
}
// 从下到上
if(start < endX && start < endY - 1)
{
for(int i = endY - 1; i >= start + 1; --i)
{
printValue(numbers[i][start]);
}
}
++start;
}
}
void printValue(int val){
printf("%d ",val);
}
int main()
{
int m,n;
while (scanf("%d%d",&m,&n)!=EOF) {
for(int i=0;i<m;i++){
for (int j = 0; j < n; j++)
{
scanf("%d",&numbers[i][j]);
}
}
PrintMatrixInCircle(n,m);
printf("\n");
}
return 0;
}
题目1522:包含min函数的栈
使用一个辅助栈,记录当前的min,代码如下:
#include <cstdio>
#include <stack>
using namespace std;
void printValue(int val){
printf("%d\n",val);
}
void printMinInstack(int m){
int val;
stack<int> st,stMin;
char c;
for(int i=0;i<m;i++){
scanf("\n%c",&c);
if (c=='s')
{
scanf("%d",&val);
if (!stMin.empty()&&val>stMin.top()) {
stMin.push(stMin.top());
}else{
stMin.push(val);
}
st.push(val);
printValue(stMin.top());
}else{
if (stMin.empty()) {
printf("NULL\n");
}else{
stMin.pop();
st.pop();
if (!stMin.empty()){
printValue(stMin.top());
}else{
printf("NULL\n");
}
}
}
}
}
int main()
{
int m;
while (scanf("%d",&m)!=EOF) {
printMinInstack(m);
}
return 0;
}
题目1366:栈的压入、弹出序列
判断压入序列的当前操作数据是否等于当前出栈数据,是则弹出,否则继续压入,如果所有数据都压入了,出栈序列还有数据,则不是正确的弹出序列,代码如下:
#include <cstdio>
#include <stack>
using namespace std;
bool isPopList(const int *pushList,const int *popList,const int n){
bool sign = true;
stack<int> pushSt;
int pushIndex=0,popIndex=0;
while (popIndex<n) {
if (!pushSt.empty()) {
if (pushSt.top()==popList[popIndex]) {
pushSt.pop();
popIndex++;
}else if(pushIndex<n){
pushSt.push(pushList[pushIndex++]);
}else{
sign = false;
break;
}
}else if(pushIndex<n){
pushSt.push(pushList[pushIndex++]);
}else{
sign = false;
break;
}
}
return sign;
}
int main()
{
int n;
while (scanf("%d",&n)!=EOF&&n>0) {
int list1[n],list2[n];
for (int i=0; i<n; i++) {
scanf("%d",&list1[i]);
}
for (int i=0; i<n; i++) {
scanf("%d",&list2[i]);
}
if(isPopList(list1,list2,n)){
printf("Yes\n");
}else{
printf("No\n");
}
}
return 0;
}
题目1523:从上往下打印二叉树
使用队列,代码如下:
#include <cstdio>
#include <queue>
using namespace std;
int treeNodeNumbers;
struct BinaryTreeNode
{
int m_nValue;
BinaryTreeNode* m_pLeft;
BinaryTreeNode* m_pRight;
void setValue(int val){
this->m_nValue=val;
m_pLeft=m_pRight=NULL;
}
};
void constructTree(int m,BinaryTreeNode tree[]){
int val,childIndex;
char c;
if (m>0)
{
for(int i=0;i<m;i++){
scanf("%d",&val);
tree[i].setValue(val);
}
for(int i=0;i<m;i++){
scanf("\n%c",&c);
if (c=='d'||c=='l'||c=='r')
{
scanf("%d",&childIndex);
if (c=='l'||c=='d')
{
tree[i].m_pLeft=&tree[childIndex-1];
if (c=='d')
{
scanf("%d",&childIndex);
tree[i].m_pRight=&tree[childIndex-1];
}
}else
{
tree[i].m_pRight=&tree[childIndex-1];
}
}
}
}
}
void PrintValue(int val){
if ((treeNodeNumbers--)>1)
printf("%d ",val);
else
printf("%d",val);
}
void PrintTree(BinaryTreeNode* pRoot)
{
if(pRoot == NULL)
return;
BinaryTreeNode* pHead = pRoot;
queue<BinaryTreeNode*> q;
q.push(pHead);
while (q.size()) {
PrintValue(q.front()->m_nValue);
pHead=q.front();
q.pop();
if (pHead->m_pLeft!=NULL) {
q.push(pHead->m_pLeft);
}
if (pHead->m_pRight!=NULL) {
q.push(pHead->m_pRight);
}
}
}
int main()
{
int m;
BinaryTreeNode tree[1000];
while (scanf("%d",&m)!=EOF) {
constructTree(m,tree);
treeNodeNumbers = m;
PrintTree(tree);
}
return 0;
}
题目1367:二叉搜索树的后序遍历序列
后序遍历最后一个是根,根前面的小于根,后面的大于根,根据这个特点,使用递归,可以写出代码如下:
#include <cstdio>
using namespace std;
bool isSortTree(const int* data,int length ){
if (data==NULL||length<=0) {
return false;
}
int root = data[length-1];
int i=0;
//找到开始大于根结点的位置
for (; i<length-1; i++) {
if (data[i]>root) {
break;
}
}
for (int j=i; j<length-1; j++) {
if (data[j]<root) {
return false;
}
}
bool left=true;
if (i>0) {
left=isSortTree(data, i);
}
bool right=true;
if (length-1>i) {
right=isSortTree(data+i, length-i-1);
}
return left&&right;
}
int main()
{
int m;
int tree[10000];
while (scanf("%d",&m)!=EOF) {
for (int i=0; i<m; i++) {
scanf("%d",&tree[i]);
}
if (isSortTree(tree,m)) {
printf("Yes\n");
}else{
printf("No\n");
}
}
return 0;
}
题目1368:二叉树中和为某一值的路径
前序遍历,遍历的时候分别记录当前的和及路径,如果是叶子结点则判断是否等于要找的和,否则减去此结点的值,从路径中删除,继续下一个结点,代码如下:
#include <iostream>
#include <vector>
using namespace std;
typedef struct {
int val;
int left;
int right;
} node;
void find(const vector<node> &vec, const int &target, int idx,vector<int> &path,int &cnt) {
const node &cur = vec[idx];
//如果当前已经是叶子结点,且找到了和,则打印路径
if (cnt + cur.val == target && cur.left == -2 && cur.right == -2) {
cout << "A path is found:";
for (vector<int>::const_iterator iter = path.begin();
iter != path.end(); ++iter) {
cout << " " << *iter + 1;
}
cout << " " << idx + 1 << endl;
} else {
cnt += cur.val;
path.push_back(idx);
//确保字典顺序
if (cur.left != -2 && cur.right != -2) {
if (cur.left < cur.right) {
find(vec, target, cur.left,path,cnt);
find(vec, target, cur.right,path,cnt);
} else {
find(vec, target, cur.right,path,cnt);
find(vec, target, cur.left,path,cnt);
}
}else if (cur.left != -2) {
find(vec, target, cur.left,path,cnt);
}else if (cur.right != -2){
find(vec, target, cur.right,path,cnt);
}
// this node is done
path.pop_back();
cnt -= cur.val;
}
}
int main(void) {
int cnt;
int target, i;
node n;
vector<int> path;
while (cin >> cnt) {
vector<node> vec;
cin >> target;
for (i = 0; i < cnt; ++i) {
cin >> n.val >> n.left >> n.right;
--n.left;
--n.right;
vec.push_back(n);
}
cout << "result:" << endl;
path.clear();
int currentSum = 0;
find(vec, target, 0,path,currentSum);
}
}