算法训练Day30|● 332.重新安排行程 ● 51. N皇后 ● 37. 解数独

简介: 算法训练Day30|● 332.重新安排行程 ● 51. N皇后 ● 37. 解数独

LeetCode:332.重新安排行程

1.思路

创建结果集res,用于存储路径path

对车程tickets的目的地依次进行排序,path收集首个机场JFK,标记数组used[]跟踪目的机场是否使用

backtracing()回溯

返回结果

2.代码实现

 1class Solution {
 2
 3    LinkedList<String> res; // 存放结果
 4    LinkedList<String> path = new LinkedList<>();  // 存放路径
 5
 6    public List<String> findItinerary(List<List<String>> tickets) {
 7        Collections.sort(tickets, (a, b) -> a.get(1).compareTo(b.get(1))); // 将票程目的机场进行排序,
 8        path.add("JFK"); // 起始机场"JFK"
 9        boolean[] used = new boolean[tickets.size()]; //标记数组:跟踪机票是否使用
10        backtracking((ArrayList) tickets, used); // 开始回溯过程  为什么进行强转?猜测是便于对ArrayList方法的调用?
11        return res; // 返回结果
12    }
13
14    public boolean backtracking(ArrayList<List<String>> tickets, boolean[] used) {
15        if (path.size() == tickets.size() + 1) { // 一个车程tickets两个节点,2车程3个机场节点
16            res = new LinkedList(path); // 将当前路径存储为结果
17            return true; // 表示成功完成回溯
18        }
19
20        for (int i = 0; i < tickets.size(); i++) {
21            if (!used[i] && tickets.get(i).get(0).equals(path.getLast())) { // 如果机票未使用且起始机场与路径中的最后一个机场匹配
22                path.add(tickets.get(i).get(1)); // 将目的机场加入路径中
23                used[i] = true; // 标记机票已使用
24
25                if (backtracking(tickets, used)) { // 递归探索下一张机票
26                    return true; // 如果找到有效的行程,返回true
27                }
28
29                used[i] = false; // 标记机票未使用,以便其他可能的路径使用
30                path.removeLast(); // 从路径中移除最后一个机场
31            }
32        }
33        return false; // 当前路径没有找到有效的行程
34    }
35}

LeetCode:51. N皇后

1.思路

二维数组中寻找符合条件的result,for循环横向遍历,backtracking()纵向遍历,直到输出结果或遍历结束.

二维系统中建立坐标系,模拟皇后位置写出排除"同行同列同45°的"的条件,用于筛选结果,建立坐标系的原点非常重要,决定了具体的实现细节.


2.代码实现

 1class Solution {
 2    List<List<String>> res = new ArrayList<>(); // 存储最终的结果
 3
 4    public List<List<String>> solveNQueens(int n) {
 5        char[][] chessboard = new char[n][n]; // 创建一个n*n的二维字符数组
 6        for (char[] c : chessboard) { 
 7            Arrays.fill(c, '.');
 8        }
 9        // for (int i = 0; i < chessboard.length; i++) {
10        //     for (int j = 0; j < chessboard[i].length; j++) {
11        // // 对二维数组的每个元素进行操作
12        //         chessboard[i][j] = '.';
13        // // 其他操作...
14        //     }
15        // }
16        backtracking(n, 0, chessboard);
17        return res;
18    }
19    public void backtracking(int n, int row, char[][] chessboard) {
20        if (row == n) {
21            res.add(Array2List(chessboard));
22            return;
23        }
24        for (int col = 0; col < n; col++) {
25            if (isValid(row, col, n, chessboard)) {
26                chessboard[row][col] = 'Q';
27                backtracking(n, row + 1, chessboard);
28                chessboard[row][col] = '.';
29            }
30        }
31    }
32
33    public List Array2List(char[][] chessboard) {
34        List<String> list = new ArrayList<>();
35        for (char[] c : chessboard) {
36            list.add(String.copyValueOf(c));
37        }
38        return list;
39    }
40
41    public boolean isValid(int row, int col, int n, char[][] chessboard) {
42        // 检查列
43        for (int i = 0; i < row; i++) {
44            if (chessboard[i][col] == 'Q') {
45                return false;
46            }
47        }
48        for (int i = row - 1, j = col - 1; i >= 0 && j >= 0; i--, j--) {
49            if (chessboard[i][j] == 'Q') {
50                return false;
51            }
52        }
53        // 检查135度对角线
54        for (int i = row -1, j = col + 1; i >= 0 && j <= n - 1; i--, j++) {
55            if (chessboard[i][j] == 'Q') {
56                return false;
57            }
58        }
59        return false;
60    }
61}

LeetCode:37. 解数独

1.思路

两层for循环嵌套递归函数,外设一个行列及九宫格是否有效性判断的函数

2.代码实现

 1class Solution {
 2
 3    public void solveSudoku(char[][] board) {
 4        solveSudokuHelper(board);
 5    }
 6
 7    // 回溯函数
 8    public boolean solveSudokuHelper(char[][] board) {
 9        for (int i = 0; i < 9; i++) { // 遍历行
10            for (int j = 0; j < 9; j++) { // 遍历列
11                if (board[i][j] != '.') { // 跳过数字
12                    continue;
13                }
14                // 为空白处赋予数字字符
15                for (char k = '1'; k <= '9'; k++) {
16                    if (isValidSudoku(i, j, k, board)) { // 判断行列是否有效
17                        board[i][j] = k; // 有效则赋值
18                        if (solveSudokuHelper(board)) { // 找到一个符合条件的结果立刻返回true
19                            return true;
20                        }
21                        board[i][j] = '.'; // 无效则回溯,剪枝操作
22                    }
23                }
24
25                return false; // 如果该节点九个数都不满足要求,返回false
26            }
27        }
28        return true; // 最后找到返回true
29    }
30
31    public boolean isValidSudoku(int row, int col, char val, char[][] board) {
32        for (int i = 0; i < 9; i++) {
33            if (board[row][i] == val) {
34                return false;
35            }
36        }
37        for (int j = 0; j < 9; j++) {
38            if (board[j][col] == val) {
39                return false;
40            }
41        }
42        // 9宫格内去重
43        int startRow = (row / 3) * 3;
44        int startCol = (col / 3) * 3;
45        for (int i = startRow; i < startRow + 3; i++) {
46            for (int j = startCol; j < startCol + 3; j++) {
47                if (board[i][j] == val) {
48                    return false;
49                }
50            }
51        }
52        return true;
53    }
54}

总结

组合问题:for循环横向遍历,递归实现纵向遍历

分割问题

排列问题

解数独、N皇后问题

真难,先这样~


相关文章
|
6天前
|
算法 测试技术 C++
【动态规划】【中位数】【C++算法】1478. 安排邮筒
【动态规划】【中位数】【C++算法】1478. 安排邮筒
|
6天前
|
算法 测试技术 C#
【贪心算法】LeetCode2071:你可以安排的最多任务数目
【贪心算法】LeetCode2071:你可以安排的最多任务数目
|
6天前
|
算法 测试技术
【贪心算法】LeetCode2071:你可以安排的最多任务数目
【贪心算法】LeetCode2071:你可以安排的最多任务数目
|
算法
算法设计与分析/数据结构与算法实验2:循环赛安排问题
算法设计与分析/数据结构与算法实验2:循环赛安排问题
266 0
算法设计与分析/数据结构与算法实验2:循环赛安排问题
|
算法
秒懂算法 | 活动安排问题贪心算法
通过例子分析求解活动安排问题的最好贪心策略、展示按照贪心策略求解该问题的过程。
365 0
秒懂算法 | 活动安排问题贪心算法
|
算法
贪心算法——活动安排问题
贪心算法——活动安排问题
111 0
贪心算法——安排最大会议数量
贪心算法——安排最大会议数量
|
算法 搜索推荐
[leetcode/lintcode 题解] 算法面试真题详解:安排面试城市
[leetcode/lintcode 题解] 算法面试真题详解:安排面试城市
[leetcode/lintcode 题解]  算法面试真题详解:安排面试城市