目录
1.栈和队列
2.链表问题
3.二叉树问题
3.1 用 递归和非递归 方式实现 二叉树先序、中序和后序遍历 (C++)
#include "pch.h"
#include <iostream>
#include <stack>
using namespace std;
class Node {
public:
int value;
Node *left;
Node *right;
Node(int data):value(data) {
}
};
// 先序遍历 根 左 右
void preOrderRecur(Node *head) {
if (head == nullptr)
return;
cout << head->value;
preOrderRecur(head->left);
preOrderRecur(head->right);
}
// 中序遍历 左 根 右
void inOrderRecur(Node *head) {
if (head == nullptr)
return;
inOrderRecur(head->left);
cout << head->value;
inOrderRecur(head->right);
}
// 后序遍历 左 右 根
void posOrderRecur(Node *head)
{
if (head == nullptr)
return;
posOrderRecur(head->left);
posOrderRecur(head->right);
cout << head->value;
}
void preOrderUnRecur(Node* head) {
if (head != nullptr)
{
stack<Node*> stk;
stk.push(head);
while (!stk.empty())
{
head = stk.top();
stk.pop();
cout << head->value;
if (head->right != nullptr)
stk.push(head->right);
if (head->left != nullptr)
stk.push(head->left);
}
}
}
void inOrderUnRecur(Node* head) {
if (head != nullptr)
{
stack<Node*> stk;
while (!stk.empty() || head != nullptr)
{
if (head != nullptr)
{
stk.push(head);
head = head->left;
}
else
{
head = stk.top();
stk.pop();
cout << head->value;
head = head->right;
}
}
}
}
// 两个栈 s1 s2
void postOrderUnRecur(Node* head) {
if (head != nullptr)
{
stack<Node*> stk1;
stack<int> stk2;
stk1.push(head);
while (!stk1.empty())
{
head = stk1.top();
stk1.pop();
stk2.push(head->value);
if (head->left != nullptr)
{
stk1.push(head->left);
}
if (head->right != nullptr)
{
stk1.push(head->right);
}
}
while (!stk2.empty())
{
cout << stk2.top();
stk2.pop();
}
}
}
// 用一个栈
void postOrderUnRecur(Node* head) {
if (head != nullptr)
{
stack<Node* > stk;
Node* h; // 表示最近弹出并打印的节点
Node* c; // 表示 栈顶节点
stk.push(head);
h = head;
c = nullptr;
while (!stk.empty())
{
c = stk.top();
if (h != c->left && h != c->right && c->left != nullptr)
{
stk.push(c->left);
}
else if (c->right != nullptr && h != c->right)
stk.push(c->right);
else
{
cout << stk.top()->value;
stk.pop();
h = c;
}
}
}
}
3.2 打印二叉树的边界节点
【解答】
【思路】
- 先从上到下打印最左节点
- 先序遍历二叉树,打印那些不属于每一层最左或最右的节点,但同时又是叶节点的节点。
- 从下到上打印所有层总最右节点,但节点不能既是最左节点,又是最右节点。
/*
按照标准打印二叉树的边界节点
*/
#include "pch.h"
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;
class Node {
public:
int value;
Node* left;
Node* right;
Node(int data) :value(data) {
}
};
void printEdgeNode(Node* head) {
if (head == nullptr)
return;
int height = getHeight(head, 0);
/*Node** edgeMap = new Node[height][2]();*/
vector<vector<Node*> > edgeMap(height,vector<Node*>(2));
setEdgeMap(head, 0, edgeMap);
// 打印左边界
for (int i = 0; i != edgeMap.size(); i++)
{
cout << edgeMap[i][0]->value;
}
// 打印既不是左边界又不是右边界的叶子节点
printLeafNotInMap(head, 0, edgeMap);
// 打印右边界,但不是左边界的节点
for (int i = edgeMap.size() - 1; i != -1; i--)
{
if (edgeMap[i][0] != edgeMap[i][1])
{
cout << edgeMap[i][1]->value;
}
}
}
// 获取树的高度
int getHeight(Node* head,int l) {
if (head == nullptr)
return l;
return max(getHeight(head->left, l + 1), getHeight(head->right, l + 1));
}
// 初始化edgemap
void setEdgeMap(Node* h, int l, vector<vector<Node*> > edgeMap)
{
if (h = nullptr)
return;
edgeMap[l][0] = edgeMap[1][0] == nullptr ? h : edgeMap[l][0];
edgeMap[l][1] = h;
setEdgeMap(h->left, l + 1, edgeMap);
setEdgeMap(h->right, l + 1, edgeMap);
}
// 打印既不是左边界,又不是右边界的叶子节点
void printLeafNotInMap(Node* h,int l, vector<vector<Node*> > edgeMap) {
if (h = nullptr)
return;
if (h->left == nullptr && h->right == nullptr &&h != edgeMap[l][0] && h != edgeMap[l][1])
cout << h->value;
printLeafNotInMap(h->left, l + 1, edgeMap);
printLeafNotInMap(h->right, l + 1, edgeMap);
}
3.3 二叉树节点间的最大距离(微软面试题)
【思路】
最大距离有三种情况:
- h 左子树的最大距离
- h 右子树的最大距离
- h 左子树上离 h.left 最远的距离+1(h) + h右子树上离h.right最远的距离
#include <iostream>
#include <algorithm>
using namespace std;
class Node {
public:
int value;
Node* left;
Node* right;
Node(int data) :value(data) {
}
};
int maxDistance(Node *head)
{
int record = 0;
return postOrder(head,record);
}
int postOrder(Node* head, int& record)
{
if (head == nullptr) {
record = 0;
return 0;
}
int lmax = postOrder(head->left, record);
int maxfromLeft = record;
int rmax = postOrder(head->right, record);
int maxfromRight = record;
int curNodeMax = maxfromLeft + 1 + maxfromRight;
record = max(maxfromLeft,maxfromRight)+1;
return max(max(lmax, rmax), curNodeMax);
}
4.递归和动态规划
5.字符串问题
6.大数据和空间限制
7.位运算
8.数组和矩阵问题
9.其他题目
1. 一行代码求两个数的最大公约数
// 辗转相除法
int gcd(int m,int n) {
return n == 0 ? m : gcd(n, m%n);
}
2. 阶乘的两个问题
【题目】
给定一个非负整数N,返回N!结果的末尾的0的数量。
例如:3!= 6 output 为 0
5!= 120 output 为 1
1000000000! 末尾有个249999998个0,output 为249999998
【题目思路】:
- 统计 5 的个数
【进阶题目思路】:
- 统计2 的个数