算法学习记录| 2023.X.XX| 章节DayX| 题目号.题目标题 & 题目号.题目标题
前言
108.将有序数组转换为二叉搜索树
题目链接
思路
寻找数组的分割点,然后以分割点为当前节点,递归左区间和右区间。
还需要平衡,那自然就是左右两边的数尽可能相等,那么分割点就取中间值即可。
对于取中间值需要注意有可能right是最大int,那么用(left + right)/ 2 就会越界,因此可以用如下
int mid = left + ((right - left) / 2);
代码1:递归
class Solution {
public:
TreeNode* traversal(vector<int>& nums, int left, int right){
if (left > right)
return NULL;
int mid = left + ((right - left) / 2);
TreeNode* node = new TreeNode(nums[mid]);
node -> left = traversal(nums, left, mid-1);
node -> right = traversal(nums, mid + 1, right);
return node;
}
TreeNode* sortedArrayToBST(vector<int>& nums) {
if (nums.empty())
return NULL;
int left = 0;
int right = nums.size() - 1;
return traversal(nums, left, right);
}
};
代码2:迭代
迭代法可以通过三个队列来模拟,一个队列放遍历的节点,一个队列放左区间下标,一个队列放右区间下标,模拟的就是不断分割的过程
关于处理左右区间的if后的条件怎么设置的?
class Solution {
public:
TreeNode* sortedArrayToBST(vector<int>& nums) {
if (nums.size() == 0)
return NULL;
TreeNode* root = new TreeNode(0); //初始化根结点
queue<TreeNode*> nodeQue; //存放遍历的节点
queue<int> leftQue; //存放左区间下标
queue<int> rightQue; //存放右区间下标
nodeQue.push(root); //根节点入队列
leftQue.push(0); //0为左区间下标初始位置
rightQue.push(nums.size() - 1); //nums.size() - 1为右区间下标初始位置
while (!nodeQue.empty()){
//取出三个队列里的元素
TreeNode* cur = nodeQue.front();
nodeQue.pop();
int left = leftQue.front();
leftQue.pop();
int right = rightQue.front();
rightQue.pop();
int mid = left + ((right - left) / 2);
cur->val = nums[mid]; //给中间节点赋值
if (left <= mid - 1){ //处理左区间
cur->left = new TreeNode(0); //同样初始化下一层根结点
nodeQue.push(cur->left);
leftQue.push(left);
rightQue.push(mid - 1);
}
if (right >= mid + 1) { //处理右区间
cur->right = new TreeNode(0);
nodeQue.push(cur->right);
leftQue.push(mid + 1);
rightQue.push(right);
}
}
return root;
}
};
总结
思路较为简单,注意点第一个是关于取mid值时的溢出问题,另一个是处理左右区间的判断条件。
迭代法中处理左右区间的条件自己第一次思考没太想出来,下次注意
538.把二叉搜索树转换为累加树
题目链接
思路
一开始容易忽略利用二叉搜索树的性质,直接累加节点地想非常麻烦,但是由于是二叉搜索树,因此按照题目要求的累加计算方式,就是转化为有序数组后,每个节点的值都替换为原来该值与之后所有值的和,也就是从后向前加。
正常情况使用前序遍历则得到从前往后的有序数组,那么从后往前就是右中左,也就是前序倒过来,接着按顺序累加即可
代码1:递归
class Solution {
public:
int sum = 0;
void traversal(TreeNode* cur){
if (cur == NULL)
return;
traversal(cur->right); //右
sum += cur->val; //中
cur->val = sum;
traversal(cur->left); //左
}
TreeNode* convertBST(TreeNode* root) {
traversal(root);
return root;
}
};
代码2:迭代
也就是中序模版题的改版
class Solution {
public:
int sum = 0;
TreeNode* convertBST(TreeNode* root) {
stack<TreeNode*> st; //用来处理节点上的元素
TreeNode* cur = root; //用来访问节点
while (cur != NULL || !st.empty()){
if (cur != NULL){
st.push(cur);
cur = cur->right; //右
}
else{
cur = st.top(); //中
st.pop();
sum += cur->val;
cur->val = sum;
cur = cur->left; //左
}
}
return root;
}
};