左神算法笔记(持续更新)

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 打印二叉树的边界节点

在这里插入图片描述
在这里插入图片描述
【解答】
【思路】

  1. 先从上到下打印最左节点
  2. 先序遍历二叉树,打印那些不属于每一层最左或最右的节点,但同时又是叶节点的节点。
  3. 从下到上打印所有层总最右节点,但节点不能既是最左节点,又是最右节点。
/*
按照标准打印二叉树的边界节点
*/

#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 二叉树节点间的最大距离(微软面试题)

在这里插入图片描述

【思路】
最大距离有三种情况:

  1. h 左子树的最大距离
  2. h 右子树的最大距离
  3. 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

在这里插入图片描述

【题目思路】:

  1. 统计 5 的个数

【进阶题目思路】:

  1. 统计2 的个数

猜你喜欢

转载自blog.csdn.net/shaoye_csdn1/article/details/90601395