From cff22a841efd672b4ff9452361bcbb5e4e8b9ac9 Mon Sep 17 00:00:00 2001 From: youngyangyang04 <826123027@qq.com> Date: Sat, 22 Aug 2020 20:42:48 +0800 Subject: [PATCH] Update --- README.md | 6 ++- problems/0001.两数之和.md | 1 - problems/0051.N皇后.md | 88 +++++++++++++++++++++++++++++++++ problems/0454.四数相加II.md | 41 ++++++++++++--- 4 files changed, 127 insertions(+), 9 deletions(-) create mode 100644 problems/0051.N皇后.md diff --git a/README.md b/README.md index b93b9bb1..991fa034 100644 --- a/README.md +++ b/README.md @@ -353,11 +353,13 @@ int countNodes(TreeNode* root) { |[0040.组合总和II](https://github.com/youngyangyang04/leetcode/blob/master/problems/0040.组合总和II.md) |数组/回溯 |中等| **回溯**| |[0046.全排列](https://github.com/youngyangyang04/leetcode/blob/master/problems/0046.全排列.md) |回溯|中等| **回溯**| |[0047.全排列II](https://github.com/youngyangyang04/leetcode/blob/master/problems/0047.全排列II.md) |回溯|中等| **回溯**| +|[0051.N皇后](https://github.com/youngyangyang04/leetcode/blob/master/problems/0051.N皇后.md) |回溯|中等| **回溯**| |[0053.最大子序和](https://github.com/youngyangyang04/leetcode/blob/master/problems/0053.最大子序和.md) |数组 |简单|**暴力** **贪心** 动态规划 分治| |[0059.螺旋矩阵II](https://github.com/youngyangyang04/leetcode/blob/master/problems/0059.螺旋矩阵II.md) |数组 |中等|**模拟**| |[0077.组合](https://github.com/youngyangyang04/leetcode/blob/master/problems/0077.组合.md) |回溯 |中等|**回溯**| |[0078.子集](https://github.com/youngyangyang04/leetcode/blob/master/problems/0078.子集.md) |回溯/数组 |中等|**回溯**| |[0083.删除排序链表中的重复元素](https://github.com/youngyangyang04/leetcode/blob/master/problems/0083.删除排序链表中的重复元素.md) |链表 |简单|**模拟**| +|[0090.子集II](https://github.com/youngyangyang04/leetcode/blob/master/problems/0090.子集II.md) |回溯/数组 |中等|**回溯**| |[0093.复原IP地址](https://github.com/youngyangyang04/leetcode/blob/master/problems/0093.复原IP地址) |回溯 |中等|**回溯**| |[0094.二叉树的中序遍历](https://github.com/youngyangyang04/leetcode/blob/master/problems/0094.二叉树的中序遍历.md) |树 |中等|**递归** **迭代/栈**| |[0098.验证二叉搜索树](https://github.com/youngyangyang04/leetcode/blob/master/problems/0098.验证二叉搜索树.md) |树 |中等|**递归**| @@ -414,7 +416,9 @@ int countNodes(TreeNode* root) { 大家好,我是程序员Carl,ACM区域赛铜牌获得者,哈工大计算机硕士毕业,先后在腾讯和百度从事后端技术研发,CSDN博客专家。对算法和C++后端技术有一定的见解,利用工作之余重新刷leetcode。 -我的微信: +**加我的微信,备注:组队刷题**, 拉你进刷题群,每天一道经典题目分析,而且题目不是孤立的,每一道题目之间都是有关系的,都是由浅入深一脉相承的,所以学习效果最好是每篇连续着看,也许之前你会某些知识点,但是一直没有把知识点串起来,这里每天一篇文章就会帮你把知识点串起来。 + +我也花了不少精力来整理我的题解,而且我不会发广告,纯自己学习和分享。 欢迎你的加入! diff --git a/problems/0001.两数之和.md b/problems/0001.两数之和.md index 624cd6bc..91332d09 100644 --- a/problems/0001.两数之和.md +++ b/problems/0001.两数之和.md @@ -54,7 +54,6 @@ public: auto iter = map.find(target - nums[i]); if(iter != map.end()) { return {iter->second, i}; - break; } map.insert(nums[i], i); } diff --git a/problems/0051.N皇后.md b/problems/0051.N皇后.md new file mode 100644 index 00000000..ca28c5de --- /dev/null +++ b/problems/0051.N皇后.md @@ -0,0 +1,88 @@ + +# 题目链接 + +https://leetcode-cn.com/problems/n-queens/ + +# 第51题. N皇后 +n 皇后问题研究的是如何将 n 个皇后放置在 n×n 的棋盘上,并且使皇后彼此之间不能相互攻击。 + +上图为 8 皇后问题的一种解法。 +![51n皇后](https://img-blog.csdnimg.cn/20200821152118456.png) + +给定一个整数 n,返回所有不同的 n 皇后问题的解决方案。 + +每一种解法包含一个明确的 n 皇后问题的棋子放置方案,该方案中 'Q' 和 '.' 分别代表了皇后和空位。 + +示例: + +输入: 4 +输出: [ + [".Q..", // 解法 1 + "...Q", + "Q...", + "..Q."], + + ["..Q.", // 解法 2 + "Q...", + "...Q", + ".Q.."] +] +解释: 4 皇后问题存在两个不同的解法。 + +提示: + +> 皇后,是国际象棋中的棋子,意味着国王的妻子。皇后只做一件事,那就是“吃子”。当她遇见可以吃的棋子时,就迅速冲上去吃掉棋子。当然,她横、竖、斜都可走一到七步,可进可退。(引用自 百度百科 - 皇后 ) + + +# 思路 + +# C++代码 + +``` +class Solution { +private: +void backtracking(int n, int row, vector& chessboard, vector>& result) { + if (row == n) { + result.push_back(chessboard); + return; + } + for (int col = 0; col < n; col++) { + if (isValid(row, col, chessboard, n)) { + chessboard[row][col] = 'Q'; + backtracking(n, row + 1, chessboard, result); + chessboard[row][col] = '.'; + } + } +} +bool isValid(int row, int col, vector& chessboard, int n) { + int count = 0; + // 检查列 + for (int i = 0; i < row; i++) { // 这是一个剪枝 + if (chessboard[i][col] == 'Q') { + return false; + } + } + // 检查 45度角是否有皇后 + for (int i = row - 1, j = col - 1; i >=0 && j >= 0; i--, j--) { + if (chessboard[i][j] == 'Q') { + return false; + } + } + // 检查 135度角是否有皇后 + for(int i = row - 1, j = col + 1; i >= 0 && j < n; i--, j++) { + if (chessboard[i][j] == 'Q') { + return false; + } + } + return true; +} +public: + vector> solveNQueens(int n) { + std::vector chessboard(n, std::string(n, '.')); + vector> result; + + backtracking(n, 0, chessboard, result); + return result; + } +}; +``` diff --git a/problems/0454.四数相加II.md b/problems/0454.四数相加II.md index af10a130..bbacbf6e 100644 --- a/problems/0454.四数相加II.md +++ b/problems/0454.四数相加II.md @@ -1,23 +1,50 @@ -## 题目地址 +# 题目地址 https://leetcode-cn.com/problems/4sum-ii/ -## 思路 +> 需要哈希的地方都能找到map的身影 + +# 第454题.四数相加II + +给定四个包含整数的数组列表 A , B , C , D ,计算有多少个元组 (i, j, k, l) ,使得 A[i] + B[j] + C[k] + D[l] = 0。 + +为了使问题简单化,所有的 A, B, C, D 具有相同的长度 N,且 0 ≤ N ≤ 500 。所有整数的范围在 -2^28 到 2^28 - 1 之间,最终结果不会超过 2^31 - 1 。 + +**例如:** + +输入: +A = [ 1, 2] +B = [-2,-1] +C = [-1, 2] +D = [ 0, 2] + +输出: +2 + +**解释:** +两个元组如下: +1. (0, 0, 0, 1) -> A[0] + B[0] + C[0] + D[1] = 1 + (-2) + (-1) + 2 = 0 +2. (1, 1, 0, 0) -> A[1] + B[1] + C[0] + D[0] = 2 + (-1) + (-1) + 0 = 0 + + +# 思路 本题咋眼一看好像和[第18题. 四数之和](https://github.com/youngyangyang04/leetcode/blob/master/problems/0018.四数之和.md),[第15题.三数之和](https://github.com/youngyangyang04/leetcode/blob/master/problems/0015.三数之和.md)差不多,其实差很多。 -**本题是使用哈希法的经典题目,而[第18题. 四数之和](https://github.com/youngyangyang04/leetcode/blob/master/problems/0018.四数之和.md),[第15题.三数之和](https://github.com/youngyangyang04/leetcode/blob/master/problems/0015.三数之和.md) 并不合适使用哈希法**,因为使用哈希的方法在不超时的情况下做到对结果去重很困难。 +**本题是使用哈希法的经典题目,而[第18题. 四数之和](https://github.com/youngyangyang04/leetcode/blob/master/problems/0018.四数之和.md),[第15题.三数之和](https://github.com/youngyangyang04/leetcode/blob/master/problems/0015.三数之和.md) 并不合适使用哈希法**,因为三数之和和四数之和这两道题目使用哈希法在不超时的情况下做到对结果去重是很困难的,很有多细节需要处理。 -**而这道题目相当于说不用考虑重复元素,是四个独立的数组,所以相对于题目18. 四数之和,题目15.三数之和,还是简单了不少!** +**而这道题目是四个独立的数组,只要找到A[i] + B[j] + C[k] + D[l] = 0就可以,不用考虑有重复的四个元素相加等于0的情况,所以相对于题目18. 四数之和,题目15.三数之和,还是简单了不少!** -解题步骤: +如果本题想难度升级:就是给出一个数组(而不是四个数组),在这里找出四个元素相加等于0,答案中不可以包含重复的四元组,大家可以思考一下,后续的文章我也会讲到的。 + +本题解题步骤: 1. 首先定义 一个unordered_map,key放a和b两数之和,value 放a和b两数之和出现的次数。 2. 遍历大A和大B数组,统计两个数组元素之和,和出现的次数,放到map中。 3. 定义int变量count,用来统计a+b+c+d = 0 出现的次数。 4. 在遍历大C和大D数组,找到如果 0-(c+d) 在map中出现过的话,就用count把map中key对应的value也就是出现次数统计出来。 -5. 最后返回我们的统计值 count 就可以了 +5. 最后返回统计值 count 就可以了 -## C++代码 +# C++代码 ``` class Solution {