当前位置: 首页 > news >正文

【综合算法学习】(第十二篇)

目录

N皇后(hard)

题目解析

讲解算法原理

编写代码

有效的数独(medium)

题目解析

讲解算法原理

编写代码


N皇后(hard)

题目解析

1.题目链接:. - 力扣(LeetCode)

2.题目描述

按照国际象棋的规则,皇后可以攻击与之处在同⼀⾏或同⼀列或同⼀斜线上的棋⼦。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

讲解算法原理

解法:
算法思路:

⾸先,我们在第⼀⾏放置第⼀个皇后,然后遍历棋盘的第⼆⾏,在可⾏的位置放置第⼆个皇后,然后再遍历第三⾏,在可⾏的位置放置第三个皇后,以此类推,直到放置了n个皇后为⽌。
我们需要⽤⼀个数组来记录每⼀⾏放置的皇后的列数。在每⼀⾏中,我们尝试放置⼀个皇后,并检查是否会和前⾯已经放置的皇后冲突。如果没有冲突,我们就继续递归地放置下⼀⾏的皇后,直到所有的皇后都放置完毕,然后把这个⽅案记录下来。
在检查皇后是否冲突时,我们可以⽤⼀个数组来记录每⼀列是否已经放置了皇后,并检查当前要放置的皇后是否会和已经放置的皇后冲突。对于对⻆线,我们可以⽤两个数组来记录从左上⻆到右下⻆的每⼀条对⻆线上是否已经放置了皇后,以及从右上⻆到左下⻆的每⼀条对⻆线上是否已经放置了皇后。
• 对于对⻆线是否冲突的判断可以通过以下流程解决:
1. 从左上到右下:相同对⻆线的⾏列之差相同;
2. 从右上到左下:相同对⻆线的⾏列之和相同。
因此,我们需要创建⽤于存储解决⽅案的⼆维字符串数组 solutions ,⽤于存储每个皇后的位置的⼀维整数数组 queens ,以及⽤于记录每⼀列和对⻆线上是否已经有皇后的布尔型数组
columns 、 diagonals1 和 diagonals2 。
递归函数设计:voiddfs(vector<vector<string>>&solutions,vector<int>&queens,int&n,introw,vector<bool>&columns,vector<bool>&diagonals1,vector<bool>&diagonals2)
参数:row(当前需要处理的⾏数);
返回值:⽆;
函数作⽤:在当前⾏放⼊⼀个不发⽣冲突的皇后,查找所有可⾏的⽅案使得放置n个皇后后不发⽣冲突。
递归函数流程如下:
1. 结束条件:如果 row 等于 n ,则表⽰已经找到⼀组解决⽅案,此时将每个皇后的位置存储到字符串数组 board 中,并将 board 存储到 solutions 数组中,然后返回;

2. 枚举当前⾏的每⼀列,判断该列、两个对⻆线上是否已经有皇后:
a. 如果有皇后,则继续枚举下⼀列;
b. 否则,在该位置放置皇后,并将 columns 、 diagonals1 和 diagonals2 对应的位置
设为 true ,表⽰该列和对⻆线上已经有皇后:
i. 递归调⽤ dfs 函数,搜索下⼀⾏的皇后位置。如果该⽅案递归结束,则在回溯时需要将
columns 、 diagonals1 和 diagonals2 对应的位置设为 false ,然后继续枚举
下⼀列;

编写代码

c++算法代码:

class Solution
{bool checkCol[10], checkDig1[20], checkDig2[20];vector<vector<string>> ret;vector<string> path;int n;
public:vector<vector<string>> solveNQueens(int _n) {n = _n;path.resize(n);for(int i = 0; i < n; i++)path[i].append(n, '.');dfs(0);return ret;}void dfs(int row){if(row == n){ret.push_back(path);return;}for(int col = 0; col < n; col++) // 尝试在这⼀⾏放皇后{// 剪枝if(!checkCol[col] && !checkDig1[row - col + n] && !checkDig2[row + 
col]){path[row][col] = 'Q';checkCol[col] = checkDig1[row - col + n] = checkDig2[row + 
col] = true;dfs(row + 1);// 恢复现场path[row][col] = '.';checkCol[col] = checkDig1[row - col + n] = checkDig2[row + 
col] = false;}}}
};

java算法代码:

class Solution
{boolean[] checkCol, checkDig1, checkDig2;List<List<String>> ret;char[][] path;int n;public List<List<String>> solveNQueens(int _n) {n = _n;checkCol = new boolean[n];checkDig1 = new boolean[n * 2];checkDig2 = new boolean[n * 2];ret = new ArrayList<>();path = new char[n][n];for(int i = 0; i < n; i++)Arrays.fill(path[i], '.');dfs(0);return ret;}public void dfs(int row){if(row == n){// 添加结果List<String> tmp = new ArrayList<>();for(int i = 0; i < n; i++){tmp.add(new String(path[i]));}ret.add(new ArrayList<>(tmp));}for(int col = 0; col < n; col++){// 判断能不能放if(checkCol[col] == false && checkDig1[row - col + n] == false && 
checkDig2[row + col] == false){path[row][col] = 'Q';checkCol[col] = checkDig1[row - col + n] = checkDig2[row + 
col] = true;dfs(row + 1);// 恢复现场path[row][col] = '.';checkCol[col] = checkDig1[row - col + n] = checkDig2[row + 
col] = false;}}}
}

有效的数独(medium)

题目解析

1.题目链接:. - 力扣(LeetCode)

2.题目描述

请你判断⼀个9x9的数独是否有效。只需要根据以下规则,验证已经填⼊的数字是否有效即可。数字1-9在每⼀⾏只能出现⼀次。
数字1-9在每⼀列只能出现⼀次。
数字1-9在每⼀个以粗实线分隔的3x3宫内只能出现⼀次。(请参考⽰例图)
注意:⼀个有效的数独(部分已被填充)不⼀定是可解的。只需要根据以上规则,验证已经填⼊的数字是否有效即可。空⽩格⽤'.'表⽰。
⽰例1:


输⼊:
board=
[["5","3",".",".","7",".",".",".","."]
,["6",".",".","1","9","5",".",".","."]
,[".","9","8",".",".",".",".","6","."]
,["8",".",".",".","6",".",".",".","3"]
,["4",".",".","8",".","3",".",".","1"]
,["7",".",".",".","2",".",".",".","6"]
,[".","6",".",".",".",".","2","8","."]
,[".",".",".","4","1","9",".",".","5"]
,[".",".",".",".","8",".",".","7","9"]]
输出:true
⽰例2:
输⼊:
board=
[["8","3",".",".","7",".",".",".","."]
,["6",".",".","1","9","5",".",".","."]
,[".","9","8",".",".",".",".","6","."]
,["8",".",".",".","6",".",".",".","3"]
,["4",".",".","8",".","3",".",".","1"]
,["7",".",".",".","2",".",".",".","6"]
,[".","6",".",".",".",".","2","8","."]
,[".",".",".","4","1","9",".",".","5"]
,[".",".",".",".","8",".",".","7","9"]]
输出:false
解释:除了第⼀⾏的第⼀个数字从5改为8以外,空格内其他数字均与⽰例1相同。但由于位于左上⻆的3x3宫内有两个8存在,因此这个数独是⽆效的。
提⽰:
board.length==9
board[i].length==9
board[i][j]是⼀位数字(1-9)或者'.'

讲解算法原理

解法:
算法思路:

创建三个数组标记⾏、列以及 3*3 ⼩⽅格中是否出现 1~9 之间的数字即可。

编写代码

c++算法代码:

class Solution
{bool row[9][10];bool col[9][10];bool grid[3][3][10];
public:bool isValidSudoku(vector<vector<char>>& board) {for(int i = 0; i < 9; i++)for(int j = 0; j < 9; j++){if(board[i][j] != '.'){int num = board[i][j] - '0';// 是否是有效的if(row[i][num] || col[j][num] || grid[i / 3][j / 3][num])return false;row[i][num] = col[j][num] = grid[i / 3][j / 3][num] = true;}}return true;}
};

Java算法代码:

class Solution
{boolean[][] row, col;boolean[][][] grid;public boolean isValidSudoku(char[][] board) {row = new boolean[9][10];col = new boolean[9][10];grid = new boolean[3][3][10];for(int i = 0; i < 9; i++)for(int j = 0; j < 9; j++){if(board[i][j] != '.'){int num = board[i][j] - '0';// 是否有效if(row[i][num] || col[j][num] || grid[i / 3][j / 3][num]) return false;row[i][num] = col[j][num] = grid[i / 3][j / 3][num] = true;}}return true;}
}


http://www.mrgr.cn/news/62470.html

相关文章:

  • 发现少了GLIBCXX_3.4.20,解决方法是升级libstdc++
  • [进阶]java基础之集合(三)数据结构
  • 查询 linux 中是否出现OOM
  • Spring微服务学习笔记之Spring Cloud Alibaba远程服务调用实战
  • 通过不当变更导致 PostgreSQL 翻车的案例分析与防范
  • 客如云:大型业务报表的分区化改造提升性能|OceanBase 应用实践
  • LC946. 验证栈序列
  • 引导徒弟找到用java程序拉取钉钉考勤记录的方法
  • 最新EI会议论文投稿指南:10个热门学术会议推荐
  • Chrome浏览器音/视频无法自动播放
  • OpenCV自动滑块验证(Java版)
  • Spring Boot助力校园社团信息数字化管理
  • Python爬虫:在1688上“侦探游戏”获取店铺详情
  • 大厂面试真题-简单说说中台的架构设计
  • Python酷库之旅-第三方库Pandas(181)
  • NocoBase 本周更新汇总:提升表格区块渲染性能等
  • 炫酷!HTMLCSS 让五星评级单选按钮“活“起来
  • Spring Boot技术在校园社团管理中的高效应用
  • 微信小程序开发(教学笔记)——一、通过微信官方文档认识、学习小程序
  • 让卷积神经网络来辨识马和人
  • 三合一无线键鼠中射频芯片-PHY6233
  • clickhouse运维篇(二):多机器手动部署ck集群
  • 启航新征程|三维天地沈阳分公司办公楼开工启用
  • 农作物病害图像分割系统:深度学习检测
  • C/C++系列(2)重载各种玩法
  • Mac用户必备的任务管理软件!三款高效工具推荐