wy的leetcode刷题记录_Day51

wy的leetcode刷题记录_Day51

声明

本文章的所有题目信息都来源于leetcode
如有侵权请联系我删掉!
时间:2022-11-24

前言

目录

  • wy的leetcode刷题记录_Day51
    • 声明
    • 前言
    • 795. 区间子数组个数
      • 题目介绍
      • 思路
      • 代码
      • 收获
    • 98. 验证二叉搜索树
      • 题目介绍
      • 思路
      • 代码
      • 收获

795. 区间子数组个数

今天的每日一题是: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<int>& nums, int left, int right) {
        int n=nums.size();
        int ans=0;
        for(int i=0;i<n;i++)
        {
            if(nums[i]<left)
                nums[i]=0;
            else if(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;i<n;i++)
        {
            if(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<int>& nums, int left, int right) {
        return count(nums, right) - count(nums, left - 1);
    }

    int count(vector<int>& nums, int lower) {
        int res = 0, cur = 0;
        for (auto x : nums) {
            cur = x <= lower ? cur + 1 : 0;
            res += cur;
        }
        return res;
    }
};


收获

简单的模拟题,需要考虑一些情况,但没有特别复杂的情况

98. 验证二叉搜索树

98. 验证二叉搜索树

题目介绍

给你一个二叉树的根节点 root ,判断其是否是一个有效的二叉搜索树。

有效 二叉搜索树定义如下:

节点的左子树只包含 小于 当前节点的数。
节点的右子树只包含 大于 当前节点的数。
所有左子树和右子树自身必须也是二叉搜索树。

示例 1:
wy的leetcode刷题记录_Day51_第1张图片
输入:root = [2,1,3]
输出:true

示例 2:
wy的leetcode刷题记录_Day51_第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<int> arr;
    bool isValidBST(TreeNode* root) {
        travel(root);
        int n=arr.size();
        for(int i=1;i<n;i++)
        {
            if(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<TreeNode*> 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;
    }
};

收获

巩固了搜索树和中序遍历的知识

你可能感兴趣的:(Leetcode刷题记录,C语言,leetcode,算法,数据结构)