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=0,T1=1,T2=1,递推公式Tn+3=Tn+Tn+1+Tn+2,给定数字n,求第n项
- 解题思路:正常前向计算就行,注意不要反向递归,否则计算量太大。
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) (0,0), 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 a−z, 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 1≤X≤2M,任意一人取完石头后更新 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)