LeetCode笔记(滑动窗口找字串)

偷了两天懒,今天继续

96. 不同的二叉搜索树 - medium

在这里插入图片描述
动态规划求ans[n]分三种情况:

  1. 以1为root时,ans[n] = ans[n-1];(第一和最后一棵树)
  2. 以n为root时,ans[n] = ans[n-1];(第二和第三棵树)
  3. 以除了1和n为root时,则是左边至少有一个节点的树的数量*右边至少有一个节点的树的数量,的和,就是下面代码中那个for循环
//14.04
//14.22
class Solution {
    vector<int> ans;
    int helper(int n) {
        if(n <= 1) return 1;
        if(n == 2) return 2;
        if(ans[n] != -1) return ans[n];

        int tmp = n-1, sum = 0;		//这里的tmp是代表除了root意外还有多少个节点
        for(int i = 1; tmp-i >= 1; i++) {	//i是指左子树的节点数,
            sum += helper(i)*helper(tmp-i);	//tmp-i >= 1就是右子树至少有一个节点
        }
        ans[n] = helper(n-1)*2+sum;
        return ans[n];
    }
public:
    int numTrees(int n) {
        if(n <= 1) return 1;
        if(n == 2) return 2;

        ans.resize(n+1, -1);
        helper(n);

        return ans[n];	//其实直接返回helper(n)即可
    }
};

105. 从前序与中序遍历序列构造二叉树 - medium

在这里插入图片描述
这题重点在于如何通过那两个数组画出这棵树,之后就是套娃了,弄清楚如何去套娃即可

//14.51
//15.29
class Solution {
        void helper(TreeNode* &root, vector<int> & pre, vector<int> &ino, int l_pre, int r_pre, int l_ino, int r_ino) {
            if(l_ino > r_ino || l_pre > r_pre) return ;
            if(l_ino == r_ino) {
                root = new TreeNode(ino[l_ino]);
                return ;
            }

            int i = l_ino;
            for(; i <= r_ino; i++) {
                if(ino[i] == pre[l_pre]) break;
            }
            root = new TreeNode(ino[i]);
            int cnt_l = i-l_ino;
            int cnt_r = r_ino-i;
            if(cnt_l) helper(root->left, pre, ino, l_pre+1, r_pre-cnt_r, i-cnt_l, i-1);
            if(cnt_r) helper(root->right, pre, ino, r_pre-cnt_r+1, r_pre, i+1, r_ino);
        }
public:
    TreeNode* buildTree(vector<int>& pre, vector<int>& ino) {
        if(pre.empty()) return nullptr;
        
        TreeNode* root = nullptr;
        helper(root, pre, ino, 0, pre.size()-1, 0, pre.size()-1);
        return root;
    }
};

3. 无重复字符的最长子串** - medium

在这里插入图片描述
滑动窗口用queue

//15.59
//16.40
class Solution {
public:
    int lengthOfLongestSubstring(string s) {
        if(s.empty()) return 0;
        if(s.size() == 1) return 1;

        int check[1000] = {0};
        queue<char> tmp;
        int cnt = 1;
        tmp.push(s[0]);
        check[s[0]] = 1;
        for(int i = 1; i < s.size(); i++) {
            if(check[s[i]]) {
                cnt = cnt >= tmp.size()? cnt : tmp.size();
                while(tmp.front() != s[i]) {
                    check[tmp.front()] = 0;
                    tmp.pop();
                }
                tmp.pop();
            }
            check[s[i]] = 1;
            tmp.push(s[i]);
        }

        return cnt >= tmp.size()? cnt : tmp.size();
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值