代码随想录第十八天
530.二叉搜索树的最小绝对差
给你一个二叉搜索树的根节点 root
,返回 树中任意两不同节点值之间的最小差值 。
差值是一个正数,其数值等于两值之差的绝对值。
示例 1:
输入:root = [4,2,6,1,3]
输出:1
示例 2:
输入:root = [1,0,48,null,null,12,49]
输出:1
提示:
- 树中节点的数目范围是
[2, 104]
0 <= Node.val <= 105
思路:
因为是二叉搜索树,左节点<根节点<右节点,所以我们用中序遍历,使它变为一个有序数组,然后我们开始寻找它的最小值,我们设置一个变量,它为int所取范围的最大值,然后我们遍历数组,用后一位减去前一位,就是这一次循环的最小值,然后与之前的最小值进行比较,如果新的值小的话就换上新的值,最后返回的就是最小的值。
解答:
第一种方法
/*** Definition for a binary tree node.* struct TreeNode {* int val;* struct TreeNode *left;* struct TreeNode *right;* };*/
void travellevel(struct TreeNode* root,int* result,int* numsize)
{if(root == NULL){return;}travellevel(root->left,result,numsize);result[(*numsize)++] = root->val;travellevel(root->right,result,numsize);
}
int getMinimumDifference(struct TreeNode* root) {int* result = malloc(sizeof(int)*10000);int numsize = 0;travellevel(root,result,&numsize);int min = INT_MAX;for(int i = 1;i < numsize;i++){int result1 = result[i] - result[i-1];min = fmin(result1,min);}return min;
}
第二种方法
/*** Definition for a binary tree node.* struct TreeNode {* int val;* struct TreeNode *left;* struct TreeNode *right;* };*/
void travellevel(struct TreeNode* root,int* result,struct TreeNode** pre)
{if(root == NULL){return;}travellevel(root->left,result,pre);if(*pre != NULL){*result = fmin(*result,root->val-(*pre)->val);}*pre = root;travellevel(root->right,result,pre);
}
int getMinimumDifference(struct TreeNode* root) {struct TreeNode* pre = NULL;int result = INT_MAX;travellevel(root,&result,&pre);return result;
}
501.二叉搜索树中的众数
给你一个含重复值的二叉搜索树(BST)的根节点 root
,找出并返回 BST 中的所有 众数(即,出现频率最高的元素)。
如果树中有不止一个众数,可以按 任意顺序 返回。
假定 BST 满足如下定义:
- 结点左子树中所含节点的值 小于等于 当前节点的值
- 结点右子树中所含节点的值 大于等于 当前节点的值
- 左子树和右子树都是二叉搜索树
示例 1:
输入:root = [1,null,2,2]
输出:[2]
示例 2:
输入:root = [0]
输出:[0]
提示:
- 树中节点的数目在范围
[1, 104]
内 -105 <= Node.val <= 105
思路:
跟上一题的思路一样,把它们整理为一个有序的数组,然后我们使用一个数组来计算它们的次数,但是要注意这道题的节点值有可能会是负数,所以我们计算它的最大值和最小值,最大值为最后一个元素,最小值为第一个元素,然后我们计算出最大值到最小值相差的数值,因为有负数,所以我们用数组的每一个元素减去最小值的元素,来保证每一个数都为正数,后面就是单纯的处理数值个数的多少了,但是要注意的是后面把总数加入数组时要把值全部往左偏移为原本的大小。
解答:
/*** Definition for a binary tree node.* struct TreeNode {* int val;* struct TreeNode *left;* struct TreeNode *right;* };*/
/*** Note: The returned array must be malloced, assume caller calls free().*/
void travellevel(struct TreeNode* root,int* returnSize,int* result)
{if(root == NULL){return;}travellevel(root->left,returnSize,result);result[(*returnSize)++] = root->val;travellevel(root->right,returnSize,result);}
int* findMode(struct TreeNode* root, int* returnSize) {int* result = malloc(sizeof(int)*10000);int size = 0;*returnSize = 0;travellevel(root,&size,result);int minVal = result[0];int maxVal = result[size-1];int maxCount = 0;int range = maxVal - minVal + 1;int* stack = calloc(range,sizeof(int)); for (int i = 0; i < size; i++) {stack[result[i] - minVal]++; if (stack[result[i] - minVal] > maxCount) {maxCount = stack[result[i] - minVal];}}int modeCount = 0;for (int i = 0; i < range; i++) {if (stack[i] == maxCount) {modeCount++;}}int* modes = malloc(sizeof(int) * modeCount); for (int i = 0; i < range; i++) {if (stack[i] == maxCount) {modes[(*returnSize)++] = i + minVal; }}return modes;
}
236.二叉树的最近公共祖先
给定一个二叉树, 找到该树中两个指定节点的最近公共祖先。
百度百科中最近公共祖先的定义为:“对于有根树 T 的两个节点 p、q,最近公共祖先表示为一个节点 x,满足 x 是 p、q 的祖先且 x 的深度尽可能大(一个节点也可以是它自己的祖先)。”
示例 1:
输入:root = [3,5,1,6,2,0,8,null,null,7,4], p = 5, q = 1
输出:3
解释:节点 5 和节点 1 的最近公共祖先是节点 3 。
示例 2:
输入:root = [3,5,1,6,2,0,8,null,null,7,4], p = 5, q = 4
输出:5
解释:节点 5 和节点 4 的最近公共祖先是节点 5 。因为根据定义最近公共祖先节点可以为节点本身。
示例 3:
输入:root = [1,2], p = 1, q = 2
输出:1
提示:
- 树中节点数目在范围
[2, 105]
内。 -109 <= Node.val <= 109
- 所有
Node.val
互不相同
。 p != q
p
和q
均存在于给定的二叉树中。
思路:
这道题要求找离两个子节点最近的根节点,那么我们可以先找到一个返回条件,如果根节点本身就等于其中的一个子节点或者整个二叉树为空,那么就返回根节点,后面就从左右两个子节点进行递归,并找到相应的条件,就能很简单的返回相应的值。
解答:
/*** Definition for a binary tree node.* struct TreeNode {* int val;* struct TreeNode *left;* struct TreeNode *right;* };*/
struct TreeNode* lowestCommonAncestor(struct TreeNode* root, struct TreeNode* p, struct TreeNode* q) {if(root == p || root == q || root == NULL)return root;struct TreeNode* left = lowestCommonAncestor(root->left,p,q);struct TreeNode* right = lowestCommonAncestor(root->right,p,q);if(left != NULL && right != NULL)return root;else if(left == NULL && right != NULL)return right;else if(left != NULL && right == NULL)return left;else{return NULL;}
}
反思
今天的题并不是很难,第二道题花费的时间比较多,第三道题的思想比第一二道题要难想一点,但总体来说感觉跟昨天相差不大。