欢迎您访问 最编程 本站为您分享编程语言代码,编程技术文章!
您现在的位置是: 首页

Leetcode:0051-0060 问题一览

最编程 2024-10-05 07:11:03
...

Leetcode: 0051-0060题速览

本文材料来自于LeetCode solutions in any programming language | 多种编程语言实现 LeetCode、《剑指 Offer(第 2 版)》、《程序员面试金典(第 6 版)》题解

遵从开源协议为知识共享 版权归属-相同方式共享 4.0 国际 公共许可证

研一在读备战就业,制此集合便于空闲时间浏览,有任何疑惑问题欢迎讨论,共同进步

目录

  • Leetcode: 0051-0060题速览
    • [51. N 皇后](https://leetcode.cn/problems/n-queens)
      • 题目描述
      • 解法
        • 方法一:DFS(回溯)
          • Python3
          • Java
          • C++
    • [52. N 皇后 II](https://leetcode.cn/problems/n-queens-ii)
      • 题目描述
      • 解法
        • 方法一:回溯
          • Python3
          • Java
          • C++
    • [53. 最大子数组和](https://leetcode.cn/problems/maximum-subarray)
      • 题目描述
      • 解法
        • 方法一:动态规划
          • Python3
          • Java
          • C++
    • [54. 螺旋矩阵](https://leetcode.cn/problems/spiral-matrix)
      • 题目描述
      • 解法
        • 方法一:模拟
          • Python3
          • Java
          • C++
    • [55. 跳跃游戏](https://leetcode.cn/problems/jump-game)
      • 题目描述
      • 解法
        • 方法一:贪心
          • Python3
          • Java
          • C++
    • [56. 合并区间](https://leetcode.cn/problems/merge-intervals)
      • 题目描述
      • 解法
        • 方法一:排序 + 一次遍历
          • Python3
          • Java
          • C++
    • [57. 插入区间](https://leetcode.cn/problems/insert-interval)
      • 题目描述
      • 解法
        • 方法一:排序 + 区间合并
          • Python3
          • Java
          • C++
    • [58. 最后一个单词的长度](https://leetcode.cn/problems/length-of-last-word)
      • 题目描述
      • 解法
        • 方法一:逆向遍历 + 双指针
          • Python3
          • Java
          • C++
    • [59. 螺旋矩阵 II](https://leetcode.cn/problems/spiral-matrix-ii)
      • 题目描述
      • 解法
        • 方法一:模拟
          • Python3
          • Java
          • C++
    • [60. 排列序列](https://leetcode.cn/problems/permutation-sequence)
      • 题目描述
      • 解法
        • 方法一:枚举
          • Python3
          • Java
          • C++

51. N 皇后

题目描述

按照国际象棋的规则,皇后可以攻击与之处在同一行或同一列或同一斜线上的棋子。

n 皇后问题 研究的是如何将 n 个皇后放置在 n×n 的棋盘上,并且使皇后彼此之间不能相互攻击。

给你一个整数 n ,返回所有不同的 n 皇后问题 的解决方案。

每一种解法包含一个不同的 n 皇后问题 的棋子放置方案,该方案中 'Q''.' 分别代表了皇后和空位。

 

示例 1:

国际象棋

输入:n = 4
输出:[[“.Q…”,“…Q”,“Q…”,“…Q.”],[“…Q.”,“Q…”,“…Q”,“.Q…”]]
解释:如上图所示,4 皇后问题存在两个不同的解法。

示例 2:

输入:n = 1
输出:[[“Q”]]

 

提示:

  • 1 <= n <= 9

难度:困难

标签:数组,回溯

解法

方法一:DFS(回溯)

我们定义三个数组 c o l col col, d g dg dg u d g udg udg,分别表示列、正对角线和反对角线上的是否有皇后,如果位置 ( i , j ) (i, j) (i,j) 有皇后,那么 c o l [ j ] col[j] col[j], d g [ i + j ] dg[i + j] dg[i+j] u d g [ n − i + j ] udg[n - i + j] udg[ni+j] 都为 1 1 1。另外,我们用一个数组 g g g 记录当前棋盘的状态,初始时 g g g 中的所有元素都是 '.'

接下来,我们定义一个函数 d f s ( i ) dfs(i) dfs(i),表示从第 i i i 行开始放置皇后。

d f s ( i ) dfs(i) dfs(i) 中,如果 i = n i=n i=n,说明我们已经完成了所有皇后的放置,我们将当前 g g g 放入答案数组中,递归结束。

否则,我们枚举当前行的每一列 j j j,如果位置 ( i , j ) (i, j) (i,j) 没有皇后,即 c o l [ j ] col[j] col[j], d g [ i + j ] dg[i + j] dg[i+j] u d g [ n − i + j ] udg[n - i + j] udg[ni+j] 都为 0 0 0,那么我们可以放置皇后,即把 g [ i ] [ j ] g[i][j] g[i][j] 改为 'Q',并将 c o l [ j ] col[j] col[j], d g [ i + j ] dg[i + j] dg[i+j] u d g [ n − i + j ] udg[n - i + j] udg[ni+j] 都置为 1 1 1,然后继续搜索下一行,即调用 d f s ( i + 1 ) dfs(i + 1) dfs(i+1),递归结束后,我们需要将 g [ i ] [ j ] g[i][j] g[i][j] 改回 '.' 并将 c o l [ j ] col[j] col[j], d g [ i + j ] dg[i + j] dg[i+j] u d g [ n − i + j ] udg[n - i + j] udg[ni+j] 都置为 0 0 0

在主函数中,我们调用 d f s ( 0 ) dfs(0) dfs(0) 开始递归,最后返回答案数组即可。

时间复杂度 ( n 2 × n ! ) (n^2 \times n!) (n2×n!),空间复杂度 O ( n ) O(n) O(n)。其中 n n n 是题目给定的整数。

Python3
class Solution:
    def solveNQueens(self, n: int) -> List[List[str]]:
        def dfs(i: int):
            if i == n:
                ans.append(["".join(row) for row in g])
                return
            for j in range(n):
                if col[j] + dg[i + j] + udg[n - i + j] == 0:
                    g[i][j] = "Q"
                    col[j] = dg[i + j] = udg[n - i + j] = 1
                    dfs(i + 1)
                    col[j] = dg[i + j] = udg[n - i + j] = 0
                    g[i][j] = "."

        ans = []
        g = [["."] * n for _ in range(n)]
        col = [0] * n
        dg = [0] * (n << 1)
        udg = [0] * (n << 1)
        dfs(0)
        return ans
Java
class Solution {
    private List<List<String>> ans = new ArrayList<>();
    private int[] col;
    private int[] dg;
    private int[] udg;
    private String[][] g;
    private int n;

    public List<List<String>> solveNQueens(int n) {
        this.n = n;
        col = new int[n];
        dg = new int[n << 1];
        udg = new int[n << 1];
        g = new String[n][n];
        for (int i = 0; i < n; ++i) {
            Arrays.fill(g[i], ".");
        }
        dfs(0);
        return ans;
    }

    private void dfs(int i) {
        if (i == n) {
            List<String> t = new ArrayList<>();
            for (int j = 0; j < n; ++j) {
                t.add(String.join("", g[j]));
            }
            ans.add(t);
            return;
        }
        for (int j = 0; j < n; ++j) {
            if (col[j] + dg[i + j] + udg[n - i + j] == 0) {
                g[i][j] = "Q";
                col[j] = dg[i + j] = udg[n - i + j] = 1;
                dfs(i + 1);
                col[j] = dg[i + j] = udg[n - i + j] = 0;
                g[i][j] = ".";
            }
        }
    }
}
C++
class Solution {
public:
    vector<vector<string>> solveNQueens(int n) {
        vector<int> col(n);
        vector<int> dg(n << 1);
        vector<int> udg(n << 1);
        vector<vector<string>> ans;
        vector<string> t(n, string(n, '.'));
        function<void(int)> dfs = [&](int i) -> void {
            if (i == n) {
                ans.push_back(t);
                return;
            }
            for (int j = 0; j < n; ++j) {
                if (col[j] + dg[i + j] + udg[n - i + j] == 0) {
                    t[i][j] = 'Q';
                    col[j] = dg[i + j] = udg[n - i + j] = 1;
                    dfs(i + 1);
                    col[j] = dg[i + j] = udg[n - i + j] = 0;
                    t[i][j] = '.';
                }
            }
        };
        dfs(0);
        return ans;
    }
};

52. N 皇后 II

题目描述

n 皇后问题 研究的是如何将 n 个皇后放置在 n × n 的棋盘上,并且使皇后彼此之间不能相互攻击。

给你一个整数 n ,返回 n 皇后问题 不同的解决方案的数量。

 

示例 1:

国际象棋

输入:n = 4
输出:2
解释:如上图所示,4 皇后问题存在两个不同的解法。

示例 2:

输入:n = 1
输出:1

 

提示:

  • 1 <= n <= 9

难度:困难

标签:回溯

解法

方法一:回溯

我们设计一个函数 d f s ( i ) dfs(i) dfs(i),表示从第 i i i 行开始搜索,搜索到的结果累加到答案中。

在第 i i i 行,我们枚举第 i i i 行的每一列,如果当前列不与前面已经放置的皇后发生冲突,那么我们就可以放置一个皇后,然后继续搜索下一行,即调用 d f s ( i + 1 ) dfs(i + 1) dfs(i+1)

如果发生冲突,那么我们就跳过当前列,继续枚举下一列。

判断是否发生冲突,我们需要用三个数组分别记录每一列、每一条正对角线、每一条反对角线是否已经放置了皇后。

具体地,我们用 c o l s cols cols 数组记录每一列是否已经放置了皇后,用 d g dg dg 数组记录每一条正对角线是否已经放置了皇后,用 u d g udg udg 数组记录每一条反对角线是否已经放置了皇后。

时间复杂度 O ( n ! ) O(n!)