目录
一、简要理解:
个人理解递归主要步骤:
- 找到最后的目的,分析出题目需要的结果是什么。
- 分出递归结束跟递归继续进行的条件
- 找到每次工作的共性,可以让函数在自己调用自己的情况下,改变其某些参数,最终达到递归最后的需求。
勇士想要进入地下n层去救公主(这就是递归的目的),但是不知道地下一共有多少层,每层有各种怪兽,每一层怪兽强度都会增加,必须打败前一层怪兽获得经验才能打败下一层,第n层的最强,勇士救出公主就需要找到公主就开始往上走,如果是怪兽就打败怪兽继续往下走(这就是递归结束跟递归继续进行的条件),但是勇士救出公主的前提是打败前n-1层的怪兽才能战胜第n层的怪兽,才能救出公主(所以勇士打怪兽可以用一个函数表示,函数唯一的不同就是勇士的经验跟怪兽的强度这就是函数改变的参数)。
上面知识让人更好理解递归是什么东西,但是我个人进行实际操作的时候,我是从结果往上推。具体我我通过简单题目来给大家讲解。
二、简单题目+分析
104. 二叉树的最大深度(题目来源:leetcode)
给定一个二叉树,找出其最大深度。
二叉树的深度为根节点到最远叶子节点的最长路径上的节点数。
说明: 叶子节点是指没有子节点的节点。
示例:
给定二叉树 [3,9,20,null,null,15,7],3
/ \
9 20
/ \
15 7
返回它的最大深度 3 。
1、分析目的:这道题的目的是找到最远路径的节点数。
2、递归结束条件:节点没有孩子节点就返回上一层。
3、工作的共性:每进入一层就计数加1,然后我们需要判断每个节点的左右节点大小,每个节点的值就是子节点大的值加一。
我做题的想法:递归从底部开始,从根部,比如上面的示例,最底部是15跟7,这两个的值都是1,然后第二层有9跟20,9的值是1,20的值是15跟7大的值加一,也就是二。那么3的值就是9跟20大的值加一,就是3.
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
* };
*/
class Solution {
public:
int maxDepth(TreeNode* root) {
//结束递归的条件
if(root == nullptr) return 0;
//得到子节点的值
int left = maxDepth(root->left);
int right = maxDepth(root->right);
//返回结果+1
if(left > right) return left + 1;
return right + 1;
}
};
110. 平衡二叉树(题目来源:leetcode)
给定一个二叉树,判断它是否是高度平衡的二叉树。
本题中,一棵高度平衡二叉树定义为:
一个二叉树每个节点 的左右两个子树的高度差的绝对值不超过 1 。
提示:
树中的节点数在范围 [0, 5000] 内
-104 <= Node.val <= 104
1、分析目的:这道题的目的是找到一个节点的左右子节点的深度相减的绝对值小于1就是false,反之就是true。
2、递归结束条件:节点没有孩子节点就返回上一层。
3、工作的共性:每进入一层就计数加1,然后我们需要判断每个节点的左右节点的深度相减的绝对值是否大于1。
我做题的想法:跟上题的递归是一样的,但是每次递归多了一次判断,如果节点的左右子节点深度相减绝对值大于1,那么就返回-1,如果左右节点有-1,那么就代表这个树已经是false的了,那就一直返回false。
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
* };
*/
class Solution {
public:
bool isBalanced(TreeNode* root) {
int result = Deep(root);
if(result == -1) return false;
return true;
}
int Deep(TreeNode* root){
if(root == nullptr) return 0;
int left = Deep(root->left);
int right = Deep(root->right);
//这里多加一个判断
if((left - right > 1) || (left - right < -1)||(left == -1) || (right == -1)) return -1;
if(left > right) return left + 1;
return right + 1;
}
};
面试题 17.12. BiNode(题目来源:leetcode)
二叉树数据结构TreeNode可用来表示单向链表(其中left置空,right为下一个链表节点)。实现一个方法,把二叉搜索树转换为单向链表,要求依然符合二叉搜索树的性质,转换操作应是原址的,也就是在原始的二叉搜索树上直接修改。
返回转换后的单向链表的头节点。
注意:本题相对原题稍作改动
示例:
输入: [4,2,5,1,3,null,6,0]
输出: [0,null,1,null,2,null,3,null,4,null,5,null,6]
提示:节点数量不会超过 100000。。
1、分析目的:这个题一看就是中序遍历,也就是找到最左边的子节点,然后当作新树的头节点。形成新树。
2、递归结束条件:节点没有孩子节点就返回上一层。
3、工作的共性:每一个有值的节点就插入到新树里面,而且新树的没有左子节点,只有右,新节点按照顺序直接插了新树的右子节点里面就好了。
我做题的想法:从最底下看,先找到最左边的子节点,插入当作树头,再找父节点,最后插父节点右边的树,然后递归回父节的父节点。
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
TreeNode* first = nullptr;
TreeNode* convertBiNode(TreeNode* root) {
TreeNode* pre = nullptr;
recursion(root,pre);
return first;
}
void recursion(TreeNode* root,TreeNode* &pre){
if(root == nullptr) return;
recursion(root->left,pre);
if(pre == nullptr){
pre = root;
first = root;
}
else{
pre->right = root;
root->left = nullptr;
pre = root;
}
recursion(root->right,pre);
}
};
三、其余简单题
这里大家可以自行补充考虑思想,回复到评论区,我只把一部分我感觉有代表性的题放上来。
563. 二叉树的坡度(题目来源:leetcode)
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
* };
*/
class Solution {
public:
int sum = 0;
int findTilt(TreeNode* root) {
sr(root);
return sum;
}
int sr(TreeNode* root){
if(root == nullptr) return 0;
int left = sr(root->left);
int right = sr(root->right);
if(left > right) sum += (left - right);
else sum += (right - left);
return root->val + left + right;
}
};
面试题 16.11. 跳水板(题目来源:leetcode)
class Solution {
public:
vector<int> result;
vector<int> divingBoard(int shorter, int longer, int k) {
if(k<=0) return result;
s(shorter,longer,k,k);
return result;
}
void s(int shorter, int longer, int n,int k){
if(n < 0) return;
int a = shorter * n + longer * (k - n);
result.push_back(a);
if(shorter == longer) return;
n = n - 1;
s(shorter,longer,n,k);
}
};
四、中等难度的题目
2. 两数相加(题目来源:leetcode)
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode() : val(0), next(nullptr) {}
* ListNode(int x) : val(x), next(nullptr) {}
* ListNode(int x, ListNode *next) : val(x), next(next) {}
* };
*/
class Solution {
public:
ListNode* k = new ListNode();
ListNode* zero = new ListNode(0);
ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {
ListNode* first = k;
count(l1,l2,0);
return first->next;
}
void count(ListNode* l1,ListNode* l2,int n){
if(l1 == nullptr && l2 == nullptr && n == 0) return ;
else if(l1 == nullptr && l2 == nullptr &&n != 0){
ListNode * node = new ListNode();
node->val = n;
k->next = node;
k = k->next;
return;
}
ListNode * node = new ListNode();
int a,b,c;
if(l1 == nullptr) l1 = zero;
a = l1->val;
if(l2 == nullptr) l2 = zero;
b = l2->val;
c = a+b+n;
int d,e;
d = c%10;
e = c/10;
node->val = d;
k->next = node;
k = k->next;
count(l1->next,l2->next,e);
}
};