文章目录
leetcode的周赛的题目越来越实用,也希望能不断提升
本次的四道题目总结如下:
Defanging an IP Address
题意:对ip地址中的”.” 转化为”[.]” 且给定的字符串ip是有效,扫描一遍即可
class Solution(object):
def defangIPaddr(self, address):
"""
:type address: str
:rtype: str
"""
ans = ""
for add in address:
if add == '.':
ans += "[.]"
else:
ans += add
return ans
Corporate Flight Bookings
题意:给出多条区间的加和操作,统计最后每个位置上的值
直接使用线段树解决了,线段树会面临区间的update和query,不过这个没有query,有点大材小用了
#define ll long long
#define lson l, mid, rt << 1
#define rson mid + 1, r, rt << 1 | 1
const int MAXN = 2e4 + 10;
ll sum[MAXN << 2];
ll add[MAXN << 2];
void push_up(int rt){//向上更新
sum[rt] = sum[rt << 1] + sum[rt << 1 | 1];
}
void push_down(int rt, int m){
if(add[rt]){//若有标记,则将标记向下移动一层
add[rt << 1] += add[rt];
add[rt << 1 | 1] += add[rt];
sum[rt << 1] += (m - (m >> 1)) * add[rt];
sum[rt << 1 | 1] += (m >> 1) * add[rt];
add[rt] = 0;//取消本层标记
}
}
void build(int l, int r, int rt){//建树
add[rt] = 0;
if(l == r){
sum[rt] = 0;
//scanf("%lld", &sum[rt]);
return;
}
int mid = (l + r) >> 1;
build(lson);
build(rson);
push_up(rt);//向上更新
}
void update(int L, int R, ll key, int l, int r, int rt){//区间更新
if(L <= l && R >= r){
sum[rt] += (r - l + 1) * key;
add[rt] += key;
return;
}
push_down(rt, r - l + 1);//向下更新
int mid = (l + r) >> 1;
if(L <= mid) update(L, R, key, lson);
if(R > mid) update(L, R, key, rson);
push_up(rt);//向上更新
}
ll query(int L, int R, int l, int r, int rt){//区间求和
if(L <= l && R >= r) return sum[rt];
push_down(rt, r - l + 1);//向下更新
int mid = (l + r) >> 1;
ll ans = 0;
if(L <= mid) ans += query(L, R, lson);
if(R > mid) ans += query(L, R, rson);
return ans;
}
class Solution {
public:
vector<int> corpFlightBookings(vector<vector<int>>& bookings, int n) {
vector<int> ans;
build(1,n,1);
int m = bookings.size();
for(int idx = 0; idx < m; idx++){
int x = bookings[idx][0];
int y = bookings[idx][1];
int z = bookings[idx][2];
update(x, y, z, 1, n, 1);
}
for(int idx = 1; idx <= n; idx++){
int tmp = query(idx, idx, 1, n, 1);
ans.push_back(tmp);
}
return ans;
}
};
学习别人的解法,发现可以使用左加右减标记的方法,区间的开始位置加上指定值,区间结束的下个位置减去指定值,从左到右累加即可,本质上记录变化趋势
class Solution(object):
def corpFlightBookings(self, bookings, n):
"""
:type bookings: List[List[int]]
:type n: int
:rtype: List[int]
"""
ans = []
change = [0 for idx in range(0, n + 2)]
print(change)
for booking in bookings:
change[booking[0]] += booking[2]
change[booking[1] + 1] -= booking[2]
res = 0
for idx in range(1, n + 1):
res += change[idx]
ans.append(res)
return ans[0:n]
Delete Nodes And Return Forest
题意:给定一个节点值各不相同的二叉树,删除树里面指定的结点,返回删除节点后的森林
使用递归解决就可以,注意里面根节点的情况
class Solution(object):
def delNodes(self, root, to_delete):
"""
:type root: TreeNode
:type to_delete: List[int]
:rtype: List[TreeNode]
"""
ans = []
if root == None:
return ans
ans.append(root)
def find(tree, value):
if tree == None:
return None
if tree.left != None and tree.left.val == value:
if tree.left.left != None:
ans.append(tree.left.left)
if tree.left.right != None:
ans.append(tree.left.right)
tree.left = None
return tree
if tree.right != None and tree.right.val == value:
if tree.right.left != None:
ans.append(tree.right.left)
if tree.right.right != None:
ans.append(tree.right.right)
tree.right = None
return tree
if tree.left != None:
find(tree.left, value)
if tree.right != None:
find(tree.right, value)
def remove_value(value):
for tree in ans:
#print(tree)
if tree!= None and tree.val == value:
tmp = tree
if tmp != None:
if tmp.left != None:
ans.append(tmp.left)
if tmp.right != None:
ans.append(tmp.right)
roots.append(tmp)
else:
tmp = find(tree, value)
roots = []
for value in to_delete:
remove_value(value)
#print("ans:{}".format(ans))
ss = set()
for root in roots:
ans.remove(root)
for tmp in ans:
ss.add(tmp)
return list(ss)
学习别人的递归,递归的优雅写法要学习,优化两个点:
如果是根节点,需要标记
对于to_delete的过程
class Solution(object):
ans = []
def delNodes(self, root, to_delete):
"""
:type root: TreeNode
:type to_delete: List[int]
:rtype: List[TreeNode]
"""
to_delete_set = ()
for value in to_delete:
to_delete_set.add(value)
self.ans = []
def dfs(root, is_root):
if root == None:
return
if to_delete_set.find(root.val) != to_delete_set.end():
dfs(root.left, 1)
dfs(root.right, 1)
root = None
else:
if is_root == 1:
self.ans.append(root)
dfs(root.left, 0)
dfs(root.right, 0)
dfs(root, 1)
return self.ans