- 先刷二叉树
二叉树问题基本上在所有算法内是最容易培养框架思维的,大部分算法常考题目基本上是树的遍历问题。
PS.本笔记基于labuladong一书写的,相当于摘抄加点个人感悟
先说下面几段代码:
void traverse(TreeNode root){
//前序遍历
traverse(root.left);
//中序遍历
traverse(root.right);
//后序遍历
}
先不管代码逻辑,只看代码在框架结构中的作用是什么。
- 后序遍历
int one=INT_MAX;
int oneSideMax(TreeNode *root){
if(root==nullptr){
return 0;
int left=max(0,oneSideMax(root->left));
int right=max(0,oneSideMax(root->right));
//oneSide为一边最长的路径,遍历整个路径从root节点到Max
/****后序遍历*******/
one=max(one,left+right+root->val);
return max(left,right)+root->val;
/******************/
}
看出后序遍历。题目来自Leetcode 124 题目要求最大路径和,对于二叉树节点,先计算左子树和右子树的最大路径和,然后加上自己的值,这样就可以得出新的最大路径和了。
- 前序遍历
(这边先用Leetcode No.105作的示例)
TreeNode buildTree(int[] preorder,int preStart,int preEnd,
int[] inorder,int inStart,int inEnd,Map<Integer,Integer> inMap){
if(preStart>preEnd || inStart>inEnd) return null;
/*******前序遍历***********/
TreeNode root=new TreeNode(preorder[preStart]);
int inRoot=inMap.get(root.val);
int numsLeft=inRoot-inStart;
/*************************/
root.left=bulidTree(preorder,preStarrt+1,preStart+numsLeft,
inorder,inStart,inRoot+1,inMap);
root.right=bulidTree(preorder,preStart+numsLeft+1,preEnd,
inorder,inRoot+1,inEnd,inMap);
return root;
}
虽然看起来参数比较多,但是基本上都是为了控制数组索引而已。本质上就是一个前序遍历算法的大概框架,只要按照前面void traverse(TreeNode root)来判断框架结构就能轻松看出来的。
PS.刷Leetcode的题目时可以先开始多注意代码框架结构,寻找突破点。
- 中序遍历
(PS.引用Letcode No.99作为示例)
void traverse(TreNode* node){
if(!node) return;
traverse(node->left);
/********中序遍历********/
if(node->val<prev->val){
s=(s==NULL)? prev : s;
t=node;
}
prev=node;
/***********************/
traverse(node->prev);
}
从框架结构能看出,这就是中序遍历,对于一棵BTS中序遍历应该容易的。
总结:但凡涉及递归的问题,基本上可以算作是树的问题。数据结构的基本储存方式就是链式与顺序两种,操作就是增删查改,遍历方式为递归与迭代。刷题先从”树“分类开始刷可以效率较高地理解数据结构,对于后面的动态规划、回溯等问题会理解更加到位一点。
<前序遍历,后序遍历,中序遍历> (思路框架)