本文章的所有题目信息都来源于leetcode
如有侵权请联系我删掉!
时间:2022-11-24
今天的每日一题是:795. 区间子数组个数
给你一个整数数组 nums 和两个整数:left 及 right 。找出 nums 中连续、非空且其中最大元素在范围 [left, right] 内的子数组,并返回满足条件的子数组的个数。
生成的测试用例保证结果符合 32-bit 整数范围。
示例 1:
输入:nums = [2,1,4,3], left = 2, right = 3
输出:3
解释:满足条件的三个子数组:[2], [2, 1], [3]
示例 2:
输入:nums = [2,9,2,5,6], left = 2, right = 8
输出:7
方法一:双指针法:首先我们将数组中的数分为三部分:1.小于left;2.大于等于left并且小于等于right;3.大于right这三种,为了满足题意我们的子数组必须满足不存在3的情况下至少有一个情况2。我们遍历整个数组以此时的位置为右边界,每当出现情况2时我们更新一个变量last_1,该变量表示上一个情况2出现的位置,每当出现情况3时我们更新一个变量last_2并且将last_1置为-1(因为在last_2左边的数都不满足条件了),该变量表示上一个情况3出现的位置。当没有情况2 出现的时候说明此时以i为右边界的情况中不存在满足条件的情况,继续拓展右边界。当有情况2,无情况3的时候,说明左边界可以在[0,i]中任选。当有情况2,有情况3的时候,说明我们只能在[last_1,last_2]之间选择左边界才能满足条件。
方法二(来自题解):计数法:根据方法一的结论,我们求出子数组必须满足不存在3的情况下至少有一个情况2的个数。所以,我们可以先求出只包含 0 或 1 的子区间数目,再减去只包括 0 的子区间数目。我们使用了一个辅助函数用来计算数组 nums 中所有元素小于等于 lower 的子数组数目。
双指针法:
class Solution {
public:int numSubarrayBoundedMax(vector& nums, int left, int right) {int n=nums.size();int ans=0;for(int i=0;iif(nums[i]=left&&nums[i]<=right)nums[i]=1;else if(nums[i]>right)nums[i]=2;}int last_1=-1;int last_2=-1;for(int i=0;iif(nums[i]==1)last_1=i;else if(nums[i]==2){last_1=-1;last_2=i;}if(last_1!=-1)ans+=last_1-last_2;}return ans;}
};
计数法:
class Solution {
public:int numSubarrayBoundedMax(vector& nums, int left, int right) {return count(nums, right) - count(nums, left - 1);}int count(vector& nums, int lower) {int res = 0, cur = 0;for (auto x : nums) {cur = x <= lower ? cur + 1 : 0;res += cur;}return res;}
};
简单的模拟题,需要考虑一些情况,但没有特别复杂的情况
98. 验证二叉搜索树
给你一个二叉树的根节点 root ,判断其是否是一个有效的二叉搜索树。
有效 二叉搜索树定义如下:
节点的左子树只包含 小于 当前节点的数。
节点的右子树只包含 大于 当前节点的数。
所有左子树和右子树自身必须也是二叉搜索树。
示例 1:
输入:root = [2,1,3]
输出:true
示例 2:
输入:root = [5,1,4,null,null,3,6]
输出:false
解释:根节点的值是 5 ,但是右子节点的值是 4 。
根据搜索树的性质,我们通过中序遍历的方法得到一个数组,这个数组在基于搜索树的性质上一定是一个严格升序数组,所以我们基于此判定即可,同理可写出递归和递推。
递归:
/*** 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:vector arr;bool isValidBST(TreeNode* root) {travel(root);int n=arr.size();for(int i=1;iif(arr[i]<=arr[i-1])return false;}return true;}void travel(TreeNode* root){if(root==nullptr)return;travel(root->left);arr.push_back(root->val);travel(root->right);}
};
递推:
class Solution {
public:bool isValidBST(TreeNode* root) {stack stack;long long inorder = (long long)INT_MIN - 1;while (!stack.empty() || root != nullptr) {while (root != nullptr) {stack.push(root);root = root -> left;}root = stack.top();stack.pop();// 如果中序遍历得到的节点的值小于等于前一个 inorder,说明不是二叉搜索树if (root -> val <= inorder) {return false;}inorder = root -> val;root = root -> right;}return true;}
};
巩固了搜索树和中序遍历的知识