LeetCode Weekly Contest 36

16 篇文章 0 订阅
3 篇文章 0 订阅

链接

https://leetcode.com/contest/leetcode-weekly-contest-36/

题目

617. Merge Two Binary Trees

题意

合并两个二叉树。
操作如下:
树A和树B相应节点都有值,相加即可
如果一棵树的相应节点没有值,那么用另一个树的节点

思路

按照操作递归下去即可

代码

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
public:
    TreeNode* mergeTrees(TreeNode* t1, TreeNode* t2) {
        if (!t1) return t2;
        if (!t2) return t1;
        else {
            TreeNode* root = new TreeNode(t1->val + t2->val);
            root->left = mergeTrees(t1->left, t2->left);
            root->right = mergeTrees(t1->right, t2->right);
            return root;
        }
    }
};

604. Design Compressed String Iterator

题意

设计题,要求设计数据结构,对于一个压缩存储的字符串支持操作next()hasNext()
压缩存储的定义:L1e2t1C1o1d1e1可展开为LeetCode
next():求下一个字符
hasNext():是否还有下一个字符,没有的话返回' '

思路

只需要将压缩存储的字符串表示出来即可。
我设计的是一个vector<char, int> v,第一维char表示字符,第二维int表示这个字符有多少位。
然后用一个迭代器it指向v的首部。
具体操作见代码。

代码

#define PCI pair<char, int>
#define mp make_pair

class StringIterator {
private:
    vector<pair<char, int> > v;
    vector<pair<char, int>>::iterator it;

public:
    StringIterator(string cs) {
        int k = 1, x = 0;
        for (int i = 0; i < cs.size(); ) {
            char c = cs[i];
            while (cs[i + k] >= '0' && cs[i + k] <= '9' && i + k < cs.size()) {
                x *= 10;
                x += (cs[i + k] - '0');
                k++;
            }
            v.push_back(mp(c, x));
            x = 0;
            i += k;
            k = 1;
        }
        it = v.begin();
    }

    char next() {
        if (it == v.end()) return ' ';
        if ((*it).second) {
            (*it).second--;
            return (*it).first;
        } else {
            while ((*it).second == 0 && it < v.end()) {
                it++;
            }  
            return next();
        }
    }

    bool hasNext() {
        while ((*it).second == 0 && it < v.end()) {
            it++;
        }
        if (it == v.end()) return false;
        return true;
    }
};

/**
 * Your StringIterator object will be instantiated and called as such:
 * StringIterator obj = new StringIterator(compressedString);
 * char param_1 = obj.next();
 * bool param_2 = obj.hasNext();
 */

611. Valid Triangle Number

题意

给一个数组,判断这个数组内的数字能组成的三角形有多少个。

思路

先排序,然后枚举三角形最小的两条边 x y。对于第三条边 z :利用三角形两边之和小于第三边的性质,即z<x+y
所以二分查找一下 z 的值,找到小于z的有多少个,累计进结果即可。

代码

class Solution {
public:
    int triangleNumber(vector<int>& nums) {
        sort(nums.begin(), nums.end());
        if (nums.size() < 3) return 0;
        int i = 0, j = 1, ans = 0;
        for (int i = 0; i < nums.size() - 1; i++) {
            if (nums[i] == 0) continue;
            for (int j = i + 1; j < nums.size(); j++) {
                if (nums[j] == 0) continue;
                int z = nums[i] + nums[j];
                int pos = lower_bound(nums.begin(), nums.end(), z) - nums.begin();
                if (pos != nums.size()) {
                    while (nums[pos] >= z && pos > j) {
                        pos--;
                    }
                    ans += pos - j;
                } else {
                    ans += pos - j - 1;
                }
            } 
        }
        return ans;
    }
};

616. Add Bold Tag in String

题意

给一个字符串和字典dict,要求用<b></b>将字符串中在dict中出现的那些子字符串括起来。并且需要合并相邻和相互交错的<b></b>

思路

首先,我们需要知道dict中有哪些字符串在s中出现了,所以对于dict中的每个字符串用kmp搞一下。得到出现的位置后,用vis[]哪些地方有出现:将这段位置都置为1。
最后根据vis[]对结果添加括号即可。

代码

const int maxn = 1004;
int vis[maxn];

class Solution {
public: 
    void find(string T, string P, int* f) {
        int n = T.length(), m = P.length();
        getFail(P, f);
        int j = 0;
        for (int i = 0; i < n; i++) {
            while (j && P[j] != T[i]) j = f[j];
            if (P[j] == T[i]) j++;
            if (j == m) {
                int be = i - m + 1;
                int ed = be + m;
                for (int k = be; k < ed; k++) {
                    vis[k] = 1;
                }
            }
        }
    }

    void getFail(string P, int* f) {
        int m = P.length();
        f[0] = 0, f[1] = 0;
        for (int i =1; i < m; i++) {
            int j = f[i];
            while (j && P[i] != P[j]) j = f[j];
            f[i + 1] = P[i] == P[j] ? j + 1 : 0;
        }
    }

    string addBoldTag(string s, vector<string>& dict) {
        memset(vis, 0, sizeof(vis));
        for (auto p : dict) {
            int f[maxn];
            find(s, p, f);
        }
        string res = "", a = "<b>", b = "</b>";
        for (int i = 0; i < s.size();) {
            if (vis[i]) {
                res += a;
                while (vis[i]) {
                    res.push_back(s[i]);
                    i++;
                }
                 res += b;
            } else {
                res.push_back(s[i]);
                i++;
            }
        }
        return res;
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值