LeetCode 剑指 Offer II 树(下) 专题总结

《一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码》点击传送门,即可获取!

  • 左右子树也必须是二叉搜索树。

示例:

在这里插入图片描述

输入:root = [4,1,6,0,2,5,7,null,null,null,3,null,null,null,8]

输出:[30,36,21,36,35,26,15,null,null,null,33,null,null,null,8]

提示:

  • 树中的节点数介于 0104 之间。

  • 每个节点的值介于 -104104 之间。

  • 树中的所有值 互不相同 。

  • 给定的树为二叉搜索树。

思路:

遍历顺序:右 - 中 - 左 , ans记录当前遍历过的节点和,记得更新root->val

class Solution {

public:

TreeNode* convertBST(TreeNode* root) {

int ans = 0;

dfs(root, ans);

return root;

}

//右 - 中 - 左 遍历, ans记录和

void dfs(TreeNode* root, int& ans) {

if(root == nullptr) return ;

dfs(root->right, ans);

root->val += ans;

ans = root->val;

dfs(root->left, ans);

}

};

055. 二叉搜索树迭代器

=============================================================================

题目:

实现一个二叉搜索树迭代器类BSTIterator ,表示一个按中序遍历二叉搜索树(BST)的迭代器:

  • BSTIterator(TreeNode root) 初始化 BSTIterator 类的一个对象。BST 的根节点 root 会作为构造函数的一部分给出。指针应初始化为一个不存在于 BST 中的数字,且该数字小于 BST 中的任何元素。
  • boolean hasNext() 如果向指针右侧遍历存在数字,则返回 true ;否则返回 false
  • int next()将指针向右移动,然后返回指针处的数字。
注意,指针初始化为一个不存在于 `BST` 中的数字,所以对 `next()` 的首次调用将返回 `BST` 中的最小元素。

可以假设 next() 调用总是有效的,也就是说,当调用 next() 时,BST 的中序遍历中至少存在一个下一个数字。

示例:

在这里插入图片描述

输入

inputs = [“BSTIterator”, “next”, “next”, “hasNext”, “next”, “hasNext”, “next”, “hasNext”, “next”, “hasNext”]

inputs = [[[7, 3, 15, null, null, 9, 20]], [], [], [], [], [], [], [], [], []]

输出

[null, 3, 7, true, 9, true, 15, true, 20, false]

解释

BSTIterator bSTIterator = new BSTIterator([7, 3, 15, null, null, 9, 20]);

bSTIterator.next(); // 返回 3

bSTIterator.next(); // 返回 7

bSTIterator.hasNext(); // 返回 True

bSTIterator.next(); // 返回 9

bSTIterator.hasNext(); // 返回 True

bSTIterator.next(); // 返回 15

bSTIterator.hasNext(); // 返回 True

bSTIterator.next(); // 返回 20

bSTIterator.hasNext(); // 返回 False

提示:

  • 树中节点的数目在范围 [1, 105]

  • 0 <= Node.val <= 106

  • 最多调用 105hasNextnext 操作

思路:

将二叉搜索树中序遍历并存储到数组中,通过数组实现next()hasNext() 就简单多了

class BSTIterator {

private:

vector arr;

int index = 0;

//中序遍历并存储到数组中

void dfs(TreeNode* root) {

if(!root) return ;

dfs(root->left);

arr.push_back(root->val);

dfs(root->right);

}

public:

BSTIterator(TreeNode* root) {

dfs(root);

}

int next() {

return arr[index++];

}

bool hasNext() {

if(index < arr.size())

return true;

else

return false;

}

};

056. 二叉搜索树中两个节点之和

=================================================================================

题目:

给定一个二叉搜索树的 根节点 root 和一个整数 k , 请判断该二叉搜索树中是否存在两个节点它们的值之和等于 k 。假设二叉搜索树中节点的值均唯一。

示例:

输入: root = [8,6,10,5,7,9,11], k = 12

输出: true

解释: 节点 5 和节点 7 之和等于 12

提示:

  • 二叉树的节点个数的范围是 [1, 104].

  • -104 <= Node.val <= 104

  • root 为二叉搜索树

  • -105 <= k <= 105

思路:

将遍历过的值存储在 map 中,通过map[k - root->val]map中寻找答案

class Solution {

public:

bool ok = false;

unordered_map<int, int> map;

bool findTarget(TreeNode* root, int k) {

dfs(root, k);

return ok;

}

void dfs(TreeNode* root, int k) {

if(root == nullptr || ok) return ;

if(map[k - root->val]) {

ok = true;

return ;

}

map[root->val]++;

dfs(root->left, k);

dfs(root->right, k);

}

};

057. 值和下标之差都在给定的范围内

===================================================================================

题目:

给你一个整数数组 nums 和两个整数 kt 。请你判断是否存在 两个不同下标 ij,使得 abs(nums[i] - nums[j]) <= t ,同时又满足 abs(i - j) <= k 。

如果存在则返回 true,不存在返回 false。

示例:

输入:nums = [1,2,3,1], k = 3, t = 0

输出:true

提示:

  • 0 <= nums.length <= 2 * 104

  • -231 <= nums[i] <= 231 - 1

  • 0 <= k <= 104

  • 0 <= t <= 231 - 1

思路:

用滑动窗窗口来约束一定在 k 内

abs(a - b) <= t 情况下, b肯定在[a-t, b+t] (t>0) 区间内

所以求出上限,下限,然后通过 lower_bound() 求出大于等于下限的数,再判断是否小于等于上限即可

class Solution {

public:

bool containsNearbyAlmostDuplicate(vector& nums, int k, int t) {

set set;

for (int i = 0; i < nums.size(); ++i) {

//下限

long lowerLimit = (long)nums[i] - t;

//上限

long upperLimit = (long)nums[i] + t;

//查找大于等于下限的数

auto it = set.lower_bound(lowerLimit);

if (it != set.end() && *it <= upperLimit) {

return true;

}

set.insert(nums[i]);

//滑动窗口

if (i >= k) {

set.erase(nums[i - k]);

}

}

return false;

}

};

058. 日程表

========================================================================

题目:

请实现一个 MyCalendar 类来存放你的日程安排。如果要添加的时间内没有其他安排,则可以存储这个新的日程安排。

MyCalendar 有一个 book(int start, int end)方法。它意味着在 start 到 end 时间内增加一个日程安排,注意,这里的时间是半开区间,即 [start, end), 实数 x 的范围为, start <= x < end。

当两个日程安排有一些时间上的交叉时(例如两个日程安排都在同一时间内),就会产生重复预订。

每次调用 MyCalendar.book方法时,如果可以将日程安排成功添加到日历中而不会导致重复预订,返回 true。否则,返回 false 并且不要将该日程安排添加到日历中。

请按照以下步骤调用 MyCalendar 类: MyCalendar cal = new MyCalendar(); MyCalendar.book(start, end)

示例:

输入:

[“MyCalendar”,“book”,“book”,“book”]

[[],[10,20],[15,25],[20,30]]

输出: [null,true,false,true]

解释:

MyCalendar myCalendar = new MyCalendar();

MyCalendar.book(10, 20); // returns true

MyCalendar.book(15, 25); // returns false ,第二个日程安排不能添加到日历中,因为时间 15 已经被第一个日程安排预定了

MyCalendar.book(20, 30); // returns true ,第三个日程安排可以添加到日历中,因为第一个日程安排并不包含时间 20

提示:

  • 每个测试用例,调用 MyCalendar.book 函数最多不超过 1000次。

  • 0 <= start < end <= 109

思路:

题目一堆废话,就是要判断区间是否交叉

要判断当前区间是否能够存入 map ,满足一下两个条件就可以

  • lower_bound() 求出大于等于start的数,这个数的start 要大于 插入数 的end

总结

对于面试,一定要有良好的心态,这位小伙伴面试美团的时候没有被前面阿里的面试影响到,发挥也很正常,也就能顺利拿下美团的offer。
小编还整理了大厂java程序员面试涉及到的绝大部分面试题及答案,希望能帮助到大家,

在这里插入图片描述

在这里插入图片描述

最后感谢大家的支持,希望小编整理的资料能够帮助到大家!也祝愿大家都能够升职加薪!
《一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码》点击传送门,即可获取!
9`

思路:

题目一堆废话,就是要判断区间是否交叉

要判断当前区间是否能够存入 map ,满足一下两个条件就可以

  • lower_bound() 求出大于等于start的数,这个数的start 要大于 插入数 的end

总结

对于面试,一定要有良好的心态,这位小伙伴面试美团的时候没有被前面阿里的面试影响到,发挥也很正常,也就能顺利拿下美团的offer。
小编还整理了大厂java程序员面试涉及到的绝大部分面试题及答案,希望能帮助到大家,

[外链图片转存中…(img-xl0cvbCl-1714702326750)]

[外链图片转存中…(img-0COdlCBO-1714702326750)]

最后感谢大家的支持,希望小编整理的资料能够帮助到大家!也祝愿大家都能够升职加薪!
《一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码》点击传送门,即可获取!

  • 27
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值