1. N皇后(Hard)
n 皇后问题研究的是如何将 n 个皇后放置在 n×n 的棋盘上,并且使皇后彼此之间不能相互攻击。
上图为 8 皇后问题的一种解法。
给定一个整数 n,返回所有不同的 n 皇后问题的解决方案。
每一种解法包含一个明确的 n 皇后问题的棋子放置方案,该方案中 'Q'
和 '.'
分别代表了皇后和空位。
示例:
解答:
思路:回溯算法
这个题很难,大一就觉得好难。。。
在建立算法之前,我们来考虑两个有用的细节。
一行只可能有一个皇后且一列也只可能有一个皇后。
这意味着没有必要再棋盘上考虑所有的方格。只需要按列循环即可。
对于所有的主对角线有 行号 + 列号 = 常数,对于所有的次对角线有 行号 - 列号 = 常数.
这可以让我们标记已经在攻击范围下的对角线并且检查一个方格 (行号, 列号) 是否处在攻击位置。
现在已经可以写回溯函数 backtrack(row = 0).
从第一个 row = 0 开始.
循环列并且试图在每个 column 中放置皇后.
- 如果方格 (row, column) 不在攻击范围内
- 在 (row, column) 方格上放置皇后。
- 排除对应行,列和两个对角线的位置。
- If 所有的行被考虑过,row == N
- 意味着我们找到了一个解
- Else
- 继续考虑接下来的皇后放置 backtrack(row + 1).
- 回溯:将在 (row, column) 方格的皇后移除.
- 如果方格 (row, column) 不在攻击范围内
思路二:DFS
八皇后问题可以推广为更一般的n皇后摆放问题:这时棋盘的大小变为n×n,而皇后个数也变成n。当且仅当n = 1或n ≥ 4时问题有解。
对于任意(x,y),如果要让新的点和它不能处于同一条横行、纵行或斜线上,则新点(p,q)必须要满足p+q != x+y 和p-q!= x-y, 前者针对左下右上斜线,后者针对左上右下斜线,两者同时都保证了不在同一条横行和纵行上。
代码中变量的含义:
- cols_lst: 每一行皇后的column位置组成的列表
- cur_row:目前正在判断的row的index
- xy_diff:所有x-y组成的列表
- xy_sum:所有x+y组成的列表
2. N皇后2(Hard)
n 皇后问题研究的是如何将 n 个皇后放置在 n×n 的棋盘上,并且使皇后彼此之间不能相互攻击。
上图为 8 皇后问题的一种解法。
给定一个整数 n,返回 n 皇后不同的解决方案的数量。
示例:
解答:
思路:
和上题完全一模一样,只是最后输出的时候,输出的是结果的长度。
3. 最大子序和(Easy)
给定一个整数数组 nums
,找到一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和。
示例:
进阶:
如果你已经实现复杂度为 O(n) 的解法,尝试使用更为精妙的分治法求解。
解答:
思路:
这道题很简单,动态规划,逐步更新局部最优解和全局最优解。
4. 螺旋矩阵(Medium)
给定一个包含 m x n 个元素的矩阵(m 行, n 列),请按照顺时针螺旋顺序,返回矩阵中的所有元素。
示例 1:
示例 2:
解答:
思路:
绘制螺旋轨迹路径,我们发现当路径超出界限或者进入之前访问过的单元格时,会顺时针旋转方向。
算法
假设数组有R 行 C 列,seen[r][c]表示第 r 行第 c 列的单元格之前已经被访问过了。当前所在位置为 (r, c),前进方向是 di。我们希望访问所有 R x C 个单元格。
当我们遍历整个矩阵,下一步候选移动位置是(next_r, next_c)。如果这个候选位置在矩阵范围内并且没有被访问过,那么它将会变成下一步移动的位置;否则,我们将前进方向顺时针旋转之后再计算下一步的移动位置。
5. 跳跃游戏(Medium)
给定一个非负整数数组,你最初位于数组的第一个位置。
数组中的每个元素代表你在该位置可以跳跃的最大长度。
判断你是否能够到达最后一个位置。
示例 1:
示例 2:
解答:
思路:
这个题很好想。
就是从后往前倒推,如果倒数第二个能到底倒数第一个位置,那么可以就去求是否可以达到倒数第二个位置。
就是反复往回推的过程。