链接
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
和
所以二分查找一下
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;
}
};