leetcode contest-144


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

Maximum Nesting Depth of Two Valid Parentheses Strings

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值