leetcode 常用的工具函数及技巧

常用类型

list

  • 删除指定元素

    .remove(item)
    

    若列表内有多个 item,则只删除一个item

dict

  • 合并

    s1.update(s2)
    

set

  • 初始化
    s = set()

  • 包含某个元素
    a in s

  • 删除某个元素

    1. remove(item) 若set 不包含 item,删除会报错
    2. discard(item) 若set 不包含 item,删除不报错
  • 合并
    s1.update(s2)
  • & 交集; | 并集;

st = []

# 压栈
st.append()

# 出栈
top = st.pop()

# 栈顶
st[-1]

字符串

判断某个字符串是否全是数字

2496. 数组中字符串的最大值

is_digital = all(ch.isdigit() for ch in s)

条件

for else & while else

当 while 循环正常执行完的情况下,执行 else 输出,如果 while 循环中执行了跳出循环的语句,比如 break ,将不执 行 else 代码块的内容。

for else 与 while else 类似

v = 7
data = 4
while v >= 7:
    if data == 3:
        break
    v -= 1

else:
    print("data predict error")

leetcode 常用方法

状态压缩

  • 全集

    1 << n - 1
    

s 表示状态
x 表示选取第几个元素,从 0开始

  • add or del
    def set_add_del(s, x):
    	return s ^ (1 << x)
    
  • contain
    def set_contain(s, x):
    	return s >> x & 1
    

数组

创建二维数组

形为 n * m 的二维数组

dp = [[0] * m for i in range(n)]
棋盘方向
  • 越界检测

    def check(x, y):
        if x < 0 or x >= n or y < 0 or y >= m:
            return False
        return True
    
  • 8 个方向数组

    directions = [
                (0, 1), (0, -1),
                (1, 0), (-1, 0),
                (1, 1), (-1, -1),
                (-1, 1), (1, -1)
            ]
    
  • 双重for循环

    for i in range(-1,2):
        for j in range(-1,2):
            if i == 0 and j == 0:
                continue
    

动态规划

从后往前

392. 判断子序列

这一题动态规划的代码值得研读

class Solution:
    def isSubsequence(self, s: str, t: str) -> bool:
        """
        if not s:
            return True
        if not t:
            return False
        """
        t_len = len(t)
        dp = [[-1] * 26 for i in range(t_len + 1)]

        get_char = lambda x: chr(ord('a') + x)
        get_ord = lambda ch: ord(ch) - ord('a')
        
        for i in range(t_len - 1, -1, -1):
            for j in range(26):
                cur_char = get_char(j)
                if t[i] == cur_char:
                    # i + 1 ?
                    dp[i][j] = i + 1
                else:
                    dp[i][j] = dp[i + 1][j]
        
        pre = 0
        for idx, ch in enumerate(s):
            if dp[pre][get_ord(ch)] == -1:
                return False
            pre = dp[pre][get_ord(ch)]
        return True

dp[i][j] 表示从t[i]往后遇到的第一个字母chr(ord('a')+j)的位置

简单理解,把dp数组视作一颗树

dp 形为 (t_len + 1) x 26 ,前面要多留出一层做 根(root)

dp[0][:] 表示根

dp[i][:] 0 < i < t_len,只有一个值指向下层,其他值都是0。

dp[t_len][:] 的值全为 -1

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

jieshenai

为了遇见更好的文章

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值