文章目錄
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