leetcode第188场周赛20200510

1.用栈操作构建数组

在这里插入图片描述

思路:
遍历list数组,判断当前值是否在目标数组target中?若在,则仅入栈;反之,入栈➕出栈。(分别对应在返回数组中添加“Push”添加“Push”+“Pop”)。

class Solution(object):
    def buildArray(self, target, n):
        """
        :type target: List[int]
        :type n: int
        :rtype: List[str]
        """
        res, k, l = [], 0, len(target)
        for i in range(1,n+1):
            res.append("Push")
            if i not in target:
                res.append("Pop")
            else:
                k += 1
            if k == l:
                return res

2.形成两个异或相等数组的三元组数目

在这里插入图片描述

思路:基本的动态规划
dp[i][j] 表示从索引i到索引j的按位异或值。
遍历i,j,k的所有可能,当dp[i][j-1] == dp[j][k] 时,计数器加1。
要注意的是,i可以等于0,j必须大于ij可以等于k这个条件。

class Solution(object):
    def countTriplets(self, arr):
        """
        :type arr: List[int]
        :rtype: int
        """
        #i,j,k
        l = len(arr)
        dp = [[0 for i in range(l)] for j in range(l)]
        for i in range(l):
            for j in range(l):
                if i == j:
                    dp[i][j] = arr[i]
                elif i < j:
                    dp[i][j] = arr[j] ^ dp[i][j-1]
        cnt = 0
        #遍历i,j,k
        for i in range(l):
            for j in range(i+1,l):
                for k in range(j,l):
                    if dp[i][j-1] == dp[j][k]:
                        cnt += 1
        return cnt

3.收集树上所有苹果的最少时间

在这里插入图片描述

思路:

  1. 遍历树集合;
  2. 当树上有苹果时,遍历其根节点直到根节点的编号为0
  3. 当该路径是第一次时,花费时间增加2秒钟。
  4. 所有树遍历结束,返回花费的时间。

如何知道当前路径是第一次走的?

  • 存储每个树的根节点。则一条完整的路径是由k个子树到其根树的短路径组成。比如0-4是由4-11-0组成的。
  • 每次只需判断苹果树到根节点的路径上的短路径是否经过过。
class Solution(object):
    def minTime(self, n, edges, hasApple):
        """
        :type n: int
        :type edges: List[List[int]]
        :type hasApple: List[bool]
        :rtype: int
        """
        dic = {}
        l = len(edges)
        for i in range(l):
            dic[edges[i][1]] = edges[i][0]
        #编号为0的节点的根节点为空
        dic[0] = None
        cnt = 0
        ways = set()
        for i in range(n):
            if hasApple[i]:
                t = i
                #遍历当前节点的根节点直至到0节点
                while dic[t] != None:
                	#判断是否已经经过。
                    if (t,dic[t]) not in ways:
                        cnt += 2
                        ways.add((t,dic[t]))
                        t = dic[t]
                    else:
                        break
        return cnt

4.切披萨的方案数

在这里插入图片描述
思路:动态规划
比赛时卡了好久,当时是用的递归,遍历了所有可能情况,但这显然太慢了,解决不了问题。

  • 辅助cou_A,cou_A[i][j]代表披萨左上角的坐标为[i,j]时,当前披萨上的苹果数量。因为每次切完,得到的披萨是由一个点的及其右面和下面所有的点组成。这个点就是当前披萨最左上角的坐标。
  • 转移方程:cou_A[i][j] = cou_A[i+1][j+1] + cou_A[i+1][j] - cou_A[i+1][j+1] + cou_A[i][j+1] - cou_A[i+1][j+1] 及当前苹果数量等于其右下边苹果数量加上当前行右边的苹果数量,再加上当前列下边的苹果数量。若当前坐标下是苹果,则cou_A[i][j] += 1
  • 三维dp数组,dp[i][j][k]代表,经过k次切割得到左上角坐标为[i,j]的披萨的方案数。
  • dp[i][j][k]由两种方式得到,已经切k-1刀时,由其上边所有行横切一刀得到,或从其左边所有列竖切一刀得到。
  • dp[i][j][k]的初始值:dp[0][0][0] = 1,一刀都没切,得到一整块披萨的方案数为1。
  • 最后遍历dp[i][j][k],k=k-1时的方案数。
class Solution(object):
    def ways(self, pizza, k):
        """
        :type pizza: List[str]
        :type k: int
        :rtype: int
        """
        rows, cols = len(pizza), len(pizza[0])
        cou_A = [[0 for i in range(cols+1)] for j in range(rows+1)]
        i = rows-1
        while i >= 0:
            j = cols-1
            while j >= 0:
                cou_A[i][j] = cou_A[i+1][j+1] + cou_A[i][j+1] - cou_A[i+1][j+1] + cou_A[i+1][j] - cou_A[i+1][j+1]
                if pizza[i][j] == 'A':
                    cou_A[i][j] += 1
                j -= 1
            i -= 1

        #切k-1次
        dp = [[[0 for i in range(k)] for j in range(cols)] for t in range(rows)]
        dp[0][0][0] = 1
        cnt = 0
        for t in range(1,k):
            for i in range(rows):
                for j in range(cols):
                    x, y = 0, 0
                    if cou_A[i][j] > 0:
                        while x < i:
                            if cou_A[x][j] - cou_A[i][j] > 0:
                                dp[i][j][t] += dp[x][j][t-1]
                            x += 1
                        while y < j:
                            if cou_A[i][y] - cou_A[i][j] > 0:
                                dp[i][j][t] += dp[i][y][t-1]
                            y += 1
                        #print dp[i][j][t]
        for i in range(rows):
            for j in range(cols):
                cnt += dp[i][j][k-1]
        return cnt % (10**9+7)

5.周赛成绩

在这里插入图片描述
在这里插入图片描述
leetcode全国排名第一次进前1000哇…之前4道题全ak都没进过。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值