n 位格雷码序列是一个包含 2^n 个整数的序列,要求:每个整数在 0 到 2^n - 1 之间,第一个整数是 0,整数各不相同,相邻两个整数的二进制表示恰好只有一位不同,并且最后一个整数与第一个整数(首尾)也恰好只有一位不同。满足要求的序列不止一种,题目只要求返回任意一个。有一
给定一个可能包含重复元素的整数数组,返回它所有可能的子集(幂集),子集不能重复(`[1, 2]` 和 `[2, 1]` 只算一个,两个 2 各自被选中但内容相同的子集也只算一个)。这是第 78 题(无重复元素)的进阶,去重的办法和"组合总和 II"、"全排列 II"一脉相承:先排
把 A 到 Z 分别编码成 1 到 26,给定一个只含数字的字符串,问一共有多少种方式把它解码回字母序列。同一个字符串可能有多种拆法:`"226"` 可以拆成 `2, 2, 6`(BBF)、`22, 6`(VF)、`2, 26`(BZ)三种。字符 `0` 是麻烦的来源:它不能单独
给定一个链表和两个位置 left、right(从 1 开始计数,left ≤ right),只翻转从第 left 个到第 right 个结点这一段,其余部分保持原样。这是"反转链表"的区间版本。有一个很干净的做法叫头插法:用哑结点 `dummy` 处理 left 等于 1 的情形
给定一个只含数字的字符串,通过插入三个点把它切成四段,使每一段都是合法的 IP 地址段:数值在 0 到 255 之间,并且不能有前导 0(`0` 本身合法,`00`、`01` 不合法)。返回所有可能的合法 IP 地址。这是回溯的经典应用:依次切四段,每段试 1 到 3 个字符,检
给定一棵二叉树的根结点,返回它的中序遍历:先遍历左子树,再访问根结点,最后遍历右子树。递归写法只有三行,是每个人写的第一个树算法。但它有一个隐蔽的限制:递归深度等于树的高度,对于退化成链的树,深度可以是 n,在 Python 里默认递归上限 1000 层,树一深就会栈溢出。迭代写
给定整数 n,返回用 1 到 n 这 n 个数(每个用一次)组成的所有结构互不相同的二叉搜索树。二叉搜索树的性质决定了:如果选 `i` 当根,那么 1 到 i-1 只能在左子树,i+1 到 n 只能在右子树,并且左右子树各自又是一棵二叉搜索树,于是问题被分解成两个更小的、同类的问
给定整数 n,问用 1 到 n 这 n 个互不相同的数,能组成多少种结构不同的二叉搜索树。上一题(第 95 题)要把每一棵树都造出来,这一题只要数出个数,所以不需要真的建树。二叉搜索树的结构由"选谁当根"决定:如果选第 root 小的数当根,那么比它小的 root - 1 个数必
给定三个字符串 s1、s2、s3,判断 s3 是否由 s1 和 s2 交错组成:把 s1 和 s2 各自切成若干段,然后把这些段交替地排列,得到 s3;两个字符串内部的字符顺序都不能变。例如 s1 = `aabcc`、s2 = `dbbca` 可以交错成 `aadbbcbcac`
给定一棵二叉树,判断它是不是有效的二叉搜索树:任意结点的左子树里所有结点的值都严格小于它,右子树里所有结点的值都严格大于它,左右子树本身也都是二叉搜索树。这里最常见的错误是只检查结点与它的直接左右孩子的关系,但规则要求的是整个子树。正确的做法是递归时把"允许的范围"往下传:根结点
给定一棵二叉搜索树,其中恰好有两个结点的值被错误地交换了,要求在不改变树结构的情况下恢复它。关键观察:二叉搜索树的中序遍历是严格递增的。两个结点的值被交换后,中序序列里会出现"前一个比后一个大"的逆序对:如果被交换的两个结点在中序里不相邻,会有两个逆序对,需要交换的是第一个逆序对
给定两棵二叉树,判断它们是否相同:结构相同,并且对应位置的结点值也相同。递归的想法很自然:两棵树都是空,相同;一棵空另一棵不空,不同;两个根的值不同,不同;否则左子树和右子树都必须相同。这道题是二叉树递归里最简单的一题,有一个常见的想法值得实测:能不能只比较两棵树的中序遍历序列?