Skip to content

Commit 83ca848

Browse files
committed
🎨 update: algorithm
1 parent 81632f0 commit 83ca848

32 files changed

+2044
-0
lines changed

docs/.vuepress/config.js

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,73 @@ module.exports = {
77
lastUpdated: 'Last Updated',
88
nav: [
99
{ text: '数据结构分类', link: '/dataStructure/' },
10+
{ text: '算法分类', link: '/algorithm/' },
1011
{ text: '博客', link: 'http://www.conardli.top/blog/article/' },
1112
{ text: 'github', link: 'https://github.com/ConardLi' },
1213
],
1314
sidebar: {
15+
'/algorithm/': [
16+
'/algorithm/',
17+
{
18+
title: '查找',
19+
children: [
20+
'/algorithm/查找/二维数组查找',
21+
'/algorithm/查找/旋转数组的最小数字',
22+
'/algorithm/查找/在排序数组中查找数字',
23+
]
24+
},
25+
{
26+
title: '递归和循环',
27+
children: [
28+
'/algorithm/递归和循环/斐波拉契数列',
29+
'/algorithm/递归和循环/跳台阶',
30+
'/algorithm/递归和循环/变态跳台阶',
31+
'/algorithm/递归和循环/矩形覆盖',
32+
]
33+
},
34+
{
35+
title: '分治',
36+
children: [
37+
'/algorithm/分治/数组中的逆序对',
38+
]
39+
},
40+
{
41+
title: '回溯算法',
42+
children: [
43+
'/algorithm/回溯算法/二叉树中和为某一值的路径',
44+
'/algorithm/回溯算法/字符串的排列',
45+
'/algorithm/回溯算法/和为sum的n个数',
46+
'/algorithm/回溯算法/矩阵中的路径',
47+
'/algorithm/回溯算法/机器人的运动范围',
48+
'/algorithm/回溯算法/N皇后问题',
49+
'/algorithm/回溯算法/N皇后问题2',
50+
]
51+
},
52+
{
53+
title: '排序',
54+
children: [
55+
'/algorithm/排序/插入排序',
56+
'/algorithm/排序/堆排序',
57+
'/algorithm/排序/归并排序',
58+
'/algorithm/排序/快速排序',
59+
'/algorithm/排序/冒泡排序',
60+
'/algorithm/排序/选择排序',
61+
]
62+
},
63+
{
64+
title: '数学运算',
65+
children: [
66+
'/algorithm/数学运算/1+2+3+...+n',
67+
'/algorithm/数学运算/不用加减乘除做加法',
68+
'/algorithm/数学运算/丑数',
69+
'/algorithm/数学运算/二进制中1的个数',
70+
'/algorithm/数学运算/数值的整数次方',
71+
'/algorithm/数学运算/数组中只出现一次的数字',
72+
'/algorithm/数学运算/整数中1出现的次数',
73+
'/algorithm/数学运算/字符串转换成整数',
74+
]
75+
},
76+
],
1477
'/dataStructure/': [
1578
'/dataStructure/',
1679
{

docs/algorithm/README.md

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
---
2+
{
3+
"title": "数据结构分类",
4+
}
5+
---
6+
7+
### 二叉树
8+
9+
- [二叉树的基本操作](./二叉树/二叉树的基本操作.md)⭐⭐
10+
- [二叉树的中序遍历](./二叉树/二叉树的中序遍历.md)⭐⭐
11+
- [二叉树的前序遍历](./二叉树/二叉树的前序遍历.md)⭐⭐
12+
- [二叉树的后序遍历](./二叉树/二叉树的后序遍历.md)⭐⭐
13+
- [重建二叉树](./二叉树/重建二叉树.md)⭐⭐
14+
- [求二叉树的遍历](./二叉树/重建二叉树.html/#求二叉树的遍历)⭐⭐
15+
- [对称的二叉树](./二叉树/对称的二叉树.md)⭐⭐
16+
- [二叉树的镜像](./二叉树/二叉树的镜像.md)⭐⭐
17+
- [二叉搜索树的第k个节点](./二叉树/二叉搜索树的第k个节点.md)⭐⭐
18+
- [二叉搜索树的后序遍历](./二叉树/二叉搜索树的后序遍历.md)⭐⭐
19+
- [二叉树的最大深度](./二叉树/二叉树的最大深度.md)⭐⭐
20+
- [二叉树的最小深度](./二叉树/二叉树的最小深度.md)⭐⭐
21+
- [平衡二叉树](./二叉树/平衡二叉树.md)⭐⭐
22+
- [不分行从上到下打印二叉树](./二叉树/从上到下打印二叉树.html/#题目1-不分行从上到下打印)⭐⭐
23+
- [把二叉树打印成多行](./二叉树/从上到下打印二叉树.html/#题目2-把二叉树打印成多行)⭐⭐
24+
- [二叉树中和为某一值的路径](./二叉树/二叉树中和为某一值的路径.md)⭐⭐⭐
25+
- [二叉搜索树与双向链表](./二叉树/二叉搜索树与双向链表.md)⭐⭐⭐
26+
- [按之字形顺序打印二叉树](./二叉树/从上到下打印二叉树.html/#题目3-按之字形顺序打印二叉树)⭐⭐⭐
27+
- [序列化二叉树](./二叉树/序列化二叉树.md)⭐⭐⭐
28+
- [二叉树的下一个节点](./二叉树/二叉树的下一个节点.md)⭐⭐⭐
29+
- [树的子结构](./二叉树/树的子结构.md)⭐⭐⭐
30+
31+
32+
###
33+
34+
- [堆的基本操作](./堆/堆的基本操作.md)⭐⭐⭐
35+
- [数据流中的中位数](./堆/数据流中的中位数.md)⭐⭐⭐
36+
- [最小的k个数](./堆/最小的k个数.md)⭐⭐⭐
Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
---
2+
{
3+
"title": "数组中的逆序对",
4+
}
5+
---
6+
7+
## 题目
8+
9+
10+
在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对。输入一个数组,求出这个数组中的逆序对的总数P。
11+
12+
## 思路
13+
14+
15+
使用暴力法:从第一个数开始,依次和后面每一个数字进行比较记录逆序对的个数,时间复杂度O(n<sup>2</sup>)
16+
17+
使用分治的细想:
18+
19+
若没了解过归并排序,建议先熟悉[归并排序](/算法分类/排序/归并排序.md)算法再来看本题。
20+
21+
直接将归并排序进行改进,把数据分成`N`个小数组。
22+
23+
合并数组 `left - mid` , `mid+1 - right`,合并时, 若`array[leftIndex] > array[rightIndex]` ,则比右边 `rightIndex-mid`个数大
24+
25+
`count += rightIndex-mid`
26+
27+
注意和归并排序的区别: 归并排序是合并数组数从小数开始,而本题是从大数开始。
28+
29+
时间复杂度`O(nlogn)`
30+
31+
空间复杂度`O(n)`
32+
33+
## 代码
34+
35+
36+
```js
37+
function InversePairs(data) {
38+
return mergeSort(data, 0, data.length - 1, []);
39+
}
40+
41+
function mergeSort(array, left, right, temp) {
42+
if (left < right) {
43+
const mid = parseInt((left + right) / 2);
44+
const l = mergeSort(array, left, mid, temp);
45+
const r = mergeSort(array, mid + 1, right, temp);
46+
const m = merge(array, left, right, mid, temp);
47+
return l + m + r;
48+
} else {
49+
return 0;
50+
}
51+
}
52+
53+
function merge(array, left, right, mid, temp) {
54+
let leftIndex = mid;
55+
let rightIndex = right;
56+
let tempIndex = right - left;
57+
let count = 0;
58+
while (leftIndex >= left && rightIndex > mid) {
59+
if (array[leftIndex] > array[rightIndex]) {
60+
count += (rightIndex - mid);
61+
temp[tempIndex--] = array[leftIndex--];
62+
} else {
63+
temp[tempIndex--] = array[rightIndex--];
64+
}
65+
}
66+
while (leftIndex >= left) {
67+
temp[tempIndex--] = array[leftIndex--];
68+
}
69+
while (rightIndex > mid) {
70+
temp[tempIndex--] = array[rightIndex--];
71+
}
72+
tempIndex = 0;
73+
for (let i = left; i <= right; i++) {
74+
array[i] = temp[tempIndex++];
75+
}
76+
return count;
77+
}
78+
```
79+
80+
81+
## 考察点
82+
83+
- 数组
84+
- 分治
Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
---
2+
{
3+
"title": "N皇后问题",
4+
}
5+
---
6+
7+
## 题目
8+
9+
n 皇后问题研究的是如何将 n 个皇后放置在 n×n 的棋盘上,并且使皇后彼此之间不能相互攻击。
10+
11+
![](https://assets.leetcode-cn.com/aliyun-lc-upload/uploads/2018/10/12/8-queens.png)
12+
13+
上图为 8 皇后问题的一种解法。
14+
15+
给定一个整数 n,返回所有不同的 n 皇后问题的解决方案。
16+
17+
18+
```js
19+
输入: 4
20+
输出: 2
21+
解释: 4 皇后问题存在如下两个不同的解法。
22+
[
23+
[".Q..", // 解法 1
24+
"...Q",
25+
"Q...",
26+
"..Q."],
27+
28+
["..Q.", // 解法 2
29+
"Q...",
30+
"...Q",
31+
".Q.."]
32+
]
33+
```
34+
35+
## 思路
36+
37+
回溯法:深度优先遍历(列数作为同级,行数作为深层)+ 剪枝
38+
- 递归深度达到最后一层:达到一个符合条件的解,向上回溯,想结果中添加当前的皇后位置列表
39+
- 循环所有同级向深层递归,将每一层皇后的位置进行记录
40+
- 当前位置在已放好皇后的攻击范围内:当前位置不能放置皇后
41+
- 没有命中上面的规则,说明当前位置可放置皇后,向更深层递归
42+
- 将结果进行可视化绘制
43+
44+
## 代码
45+
46+
```js
47+
var solveNQueens = function (n) {
48+
const cols = new Set();
49+
const left = new Set();
50+
const right = new Set();
51+
const result = []
52+
solveNQueensCore(0, n, cols, left, right, result, []);
53+
return draw(result, n);
54+
};
55+
56+
var solveNQueensCore = function (row, n, cols, left, right, result, temp) {
57+
if (row === n) {
58+
result.push([...temp]);
59+
temp = [];
60+
}
61+
for (let i = 0; i < n; i++) {
62+
if (!cols.has(i) && !right.has(row - i) && !left.has(row + i)) {
63+
cols.add(i);
64+
left.add(row + i);
65+
right.add(row - i);
66+
temp[row] = i;
67+
solveNQueensCore(row + 1, n, cols, left, right, result, temp);
68+
cols.delete(i);
69+
left.delete(row + i);
70+
right.delete(row - i);
71+
}
72+
}
73+
};
74+
75+
function draw(array, n) {
76+
const result = [];
77+
array.forEach(element => {
78+
const panel = [];
79+
element.forEach(index => {
80+
const temp = new Array(n).fill('.');
81+
temp[index] = 'Q';
82+
panel.push(temp.join(''));
83+
});
84+
result.push(panel);
85+
});
86+
return result;
87+
}
88+
```
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
---
2+
{
3+
"title": "N皇后问题2",
4+
}
5+
---
6+
7+
## 题目
8+
9+
n 皇后问题研究的是如何将 n 个皇后放置在 n×n 的棋盘上,并且使皇后彼此之间不能相互攻击。
10+
11+
![](https://assets.leetcode-cn.com/aliyun-lc-upload/uploads/2018/10/12/8-queens.png)
12+
13+
上图为 8 皇后问题的一种解法。
14+
15+
给定一个整数 n,返回 n 皇后不同的解决方案的数量。
16+
17+
```js
18+
输入: 4
19+
输出: 2
20+
解释: 4 皇后问题存在如下两个不同的解法。
21+
[
22+
[".Q..", // 解法 1
23+
"...Q",
24+
"Q...",
25+
"..Q."],
26+
27+
["..Q.", // 解法 2
28+
"Q...",
29+
"...Q",
30+
".Q.."]
31+
]
32+
```
33+
34+
## 思路
35+
36+
回溯法:深度优先遍历(列数作为同级,行数作为深层)+ 剪枝
37+
- 递归深度达到最后一层:达到一个符合条件的解,向上回溯,返回1
38+
- 循环所有同级向深层递归,并将每次递归的返回值累加
39+
- 当前位置在已放好皇后的攻击范围内:当前位置不能放置皇后
40+
- 没有命中上面的规则,说明当前位置可放置皇后,向更深层递归
41+
42+
## 代码
43+
44+
```js
45+
var totalNQueens = function (n) {
46+
const cols = new Set();
47+
const left = new Set();
48+
const right = new Set();
49+
return totalNQueensCore(0, n, cols, left, right);
50+
};
51+
52+
var totalNQueensCore = function (row, n, cols, left, right) {
53+
let result = 0;
54+
if (row === n) {
55+
return 1;
56+
}
57+
for (let i = 0; i < n; i++) {
58+
if (!cols.has(i) && !right.has(row - i) && !left.has(row + i)) {
59+
cols.add(i);
60+
left.add(row + i);
61+
right.add(row - i);
62+
63+
result += totalNQueensCore(row + 1, n, cols, left, right);
64+
cols.delete(i);
65+
left.delete(row + i);
66+
right.delete(row - i);
67+
}
68+
}
69+
return result;
70+
};
71+
```

0 commit comments

Comments
 (0)