Leetcode Weekly Contest 147

1.N-th Tribonacci Number
  • 题目描述: T 0 = 0 , T 1 = 1 , T 2 = 1 , 递 推 公 式 T n + 3 = T n + T n + 1 + T n + 2 , 给 定 数 字 n , 求 第 n 项 T_0 = 0, T_1 = 1,T_2 = 1, 递推公式T_{n+3}=T_{n} + T_{n+1} + T_{n+2},给定数字n,求第n项 T0=0T1=1T2=1Tn+3=Tn+Tn+1+Tn+2nn
  • 解题思路:正常前向计算就行,注意不要反向递归,否则计算量太大。
class Solution(object):
    def tribonacci(self, n):
        """
        :type n: int
        :rtype: int
        """
        t0, t1, t2 = 0, 1, 1
        if n == 0: return t0
        if n == 1: return t1
        if n == 2: return t2
        for i in range(n - 2):
            t0, t1, t2 = t1, t2, t0 + t1 + t2
            
        return t2
2.Alphabet Board Path
  • 题目描述:给定查询数组
board = ["abcde", 
		 "fghij", 
		 "klmno", 
		 "pqrst", 
		 "uvwxy", 
		 "z"]

初始位置为 ( 0 , 0 ) (0,0) 00 U / D / L / R U / D / L / R U/D/L/R 分别代表向 上 / 下 / 左 / 右 上 / 下 / 左 / 右 /// 前进一步, ! ! 代表保存当前位置的字符,要求给定一段字符串 t a r g e t target target, 按照查询数组依次获取 t a r g e t target target 的字符,并返回最小行走方案(可能存在多种,返回一种即可)。

  • 解题思路:建立 h a s h hash hash 表,键为 a − z a-z az h a s h hash hash 值为键的位置 ( x , y ) (x,y) (x,y),并根据 t a r g e t target target 中字符顺序依次与当前位置计算差值。唯一需要注意的点是目标字符是 z z z 时, 需要先向左走,再向下走。
class Solution(object):
    def alphabetBoardPath(self, target):
        """
        :type target: str
        :rtype: str
        """
        board = ["abcde", "fghij", "klmno", "pqrst", "uvwxy", "z"]
        _dict = {}
        for i in range(len(board)):
            for j in range(len(board[i])):
                    _dict[board[i][j]] = (i, j)
        
        curr = (0, 0)
        ans = ""
        for c in target:
            dst = _dict[c]
            U = max(0, curr[0] - dst[0])
            D = max(0, dst[0] - curr[0])
            L = max(0, curr[1] - dst[1])
            R = max(0, dst[1] - curr[1])
            ans += "U"*U + "D"*D + "L"*L + "R"*R 
            ans += "!"
            curr = dst
        return ans
3.Largest 1-Bordered Square
  • 题目描述:给定 2 维数组 g r i d grid grid,数组值均为 0 0 0 1 1 1,要求找出 g r i d grid grid 中边界均为 1 1 1 的最大的正方形,返回其面积。
  • 解题思路:由于确定正方形边界是否均为 1 1 1需要依次遍历正方形边界,为了减少成本,使得仅遍历一次各点, 因此建立两个 h a s h hash hash 数组分别代表当前点的上/左方连续 1 1 1的个数(包含当前点),再根据边长,从大到小依次遍历 g r i d grid grid 即可,每次只需计算正方形的左下/右上/右下角点对应的上或左 h a s h hash hash 值大于等于边长即可。
class Solution(object):
    def largest1BorderedSquare(self, grid):
        """
        :type grid: List[List[int]]
        :rtype: int
        """
        l1, l2 = len(grid), len(grid[0])
        top, left = [x[:] for x in grid], [x[:] for x in grid]
        
        for i in range(l1):
            for j in range(l2):
                if grid[i][j] and i > 0:
                    top[i][j] = top[i - 1][j] + 1
                if grid[i][j] and j > 0:
                    left[i][j] = left[i][j - 1] + 1
        
        for r in range(min(l1, l2), 0, -1):
            for i in range(l1 - r + 1):
                for j in range(l2 - r + 1):
                    if top[i + r - 1][j + r - 1] >= r and top[i + r - 1][j] >= r \
                        and left[i + r - 1][j + r - 1] >= r and left[i][j + r - 1] >= r:
                        return r * r
        return 0
4.Stone Game II
  • 题目描述:给定多堆石头 p i l e s = [ x 1 , x 2 , x 3 , . . . ] piles = [x_1, x_2, x_3, ...] piles=[x1,x2,x3,...],第 i i i 堆石头个数为 x i x_i xi,Alex 先取,Lee 后取。每次取的石头堆数不能超过 X X X 满足 1 ≤ X ≤ 2 M 1 \le X \le 2M 1X2M,任意一人取完石头后更新 M = m a x ( M , X ) M=max(M,X) M=max(M,X) M M M 的初始值为 1 1 1。要求返回 Alex 能拿到的最多的石头数。
  • 解题思路:动态规划+深搜。以当前可取堆数作为循环,依次计算结果并取最优。由于是双方博弈,因此当前循环的最优结果是(当前取堆中石头总数)与(剩余石头总数减去下一方取最优石头数目)之和。注意设定 b p bp bp 数组保存中间结果以减少运算量。
from collections import defaultdict
class Solution(object):
    def stoneGameII(self, piles):
        """
        :type piles: List[int]
        :rtype: int
        """
        bp = defaultdict(lambda:-1)
        def dfs(remains, M):
            if bp[(len(remains), M)] != -1: return bp[(len(remains), M)]
            if len(remains) <= 2*M: return sum(remains)
            
            ans = 0
            for X in range(1, 2*M + 1):
                ans = max(sum(remains[:X]) + sum(remains[X:]) - dfs(remains[X:], max(M, X)), ans)
            bp[(len(remains), M)] = ans
            return ans

        return dfs(piles, 1)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值