diff --git "a/\345\205\245\351\227\250\357\274\210Java\357\274\211/\345\212\233\346\211\243\347\273\217\345\205\270\347\256\227\346\263\225.md" "b/\345\205\245\351\227\250/\345\212\233\346\211\243\347\273\217\345\205\270\347\256\227\346\263\225\357\274\210Java\357\274\211.md" similarity index 99% rename from "\345\205\245\351\227\250\357\274\210Java\357\274\211/\345\212\233\346\211\243\347\273\217\345\205\270\347\256\227\346\263\225.md" rename to "\345\205\245\351\227\250/\345\212\233\346\211\243\347\273\217\345\205\270\347\256\227\346\263\225\357\274\210Java\357\274\211.md" index eba2ef5..2910104 100644 --- "a/\345\205\245\351\227\250\357\274\210Java\357\274\211/\345\212\233\346\211\243\347\273\217\345\205\270\347\256\227\346\263\225.md" +++ "b/\345\205\245\351\227\250/\345\212\233\346\211\243\347\273\217\345\205\270\347\256\227\346\263\225\357\274\210Java\357\274\211.md" @@ -540,6 +540,12 @@ public static int[] heapSort(int[] array) { } ``` +#### 桶排序 + +```java + +``` + ### 链表 #### 头插法 diff --git "a/\345\205\245\351\227\250/\347\273\217\345\205\270\347\256\227\346\263\225TS\345\256\236\347\216\260.md" "b/\345\205\245\351\227\250/\347\273\217\345\205\270\347\256\227\346\263\225TS\345\256\236\347\216\260.md" new file mode 100644 index 0000000..db68628 --- /dev/null +++ "b/\345\205\245\351\227\250/\347\273\217\345\205\270\347\256\227\346\263\225TS\345\256\236\347\216\260.md" @@ -0,0 +1,144 @@ +[TOC] + +### 排序算法 + +| 算法 | 稳定 | 原地排序 | 时间复杂度 | 空间复杂度 | 备注 | +| :--------------: | :--: | :------: | :--------------------------: | :--------: | :----------------------: | +| 冒泡排序 | yes | yes | N^2^ | 1 | | +| 选择排序 | no | yes | N2 | 1 | | +| 插入排序 | yes | yes | N \~ N2 | 1 | 时间复杂度和初始顺序有关 | +| 希尔排序 | no | yes | N 的若干倍乘于递增序列的长度 | 1 | | +| 快速排序 | no | yes | NlogN | logN | | +| 三向切分快速排序 | no | yes | N \~ NlogN | logN | 适用于有大量重复主键 | +| 归并排序 | yes | no | NlogN | N | | +| 堆排序 | no | yes | NlogN | 1 | | + +#### 选择排序 + +```tsx +const selectSort = function (nums: number[]) { + const len = nums.length + for (let i = 0; i < len; i++) { + let min = i + for (let j = i + 1; j < len; j++) { + if (nums[j] < nums[min]) { + min = j + } + } + ;[nums[i], nums[min]] = [nums[min], nums[i]] + } + return nums +} +``` + +#### 冒泡排序 + +```tsx +const bubbleSort = function (arrs: number[]) { + const len = arrs.length + let isSortFlag = false // 如果排好序只需遍历一遍 + for (let i = len - 1; i > 0 && !isSortFlag; i--) { + isSortFlag = true + for (let j = 0; j < i; j++) { + if (arrs[j] > arrs[j + 1]) { + isSortFlag = false + ;[arrs[j], arrs[j + 1]] = [arrs[j + 1], arrs[j]] + } + } + } + return arrs +} +``` + +#### 插入排序 + +```tsx +const insertSort = function (nums: number[]) { + const len = nums.length + for (let i = 1; i < len; i++) { + for (let j = i; j > 0; j--) { + if (nums[j] < nums[j - 1]) { + ;[nums[j], nums[j - 1]] = [nums[j - 1], nums[j]] + } + } + } + return nums +} +``` + +#### 希尔排序 + +```tsx +const shellSort = (nums: number[]) => { + const len = nums.length + let h = len >> 1 + while (h >= 1) { + for (let i = h; i < len; i++) { + for (let j = i; j >= h && nums[j] < nums[j - h]; j -= h) { + [nums[j], nums[j - h]] = [nums[j - h], nums[j]] + } + } + h >>= 1 + } +} +``` + +#### 归并排序 + +```tsx +const mergeSort = (nums: number[], left: number, right: number) => { + if (left === right) return [nums[left]] + const mid = left + ((right - left) >> 1) + const leftArray = mergeSort(nums, left, mid) + const rightArray = mergeSort(nums, mid + 1, right) + const newArray: number[] = new Array(leftArray.length + rightArray.length) + let i = 0, j = 0, k = 0 + while (i < leftArray.length && j < rightArray.length) { + newArray[k++] = leftArray[i] < rightArray[j] ? leftArray[i++] : rightArray[j++] + } + while (i < leftArray.length) { + newArray[k++] = leftArray[i++] + } + while (j < rightArray.length) { + newArray[k++] = rightArray[j++] + } + return newArray +} +``` + +#### 快速排序 + +```tsx +const quickSort = (nums: number[], start: number, end: number) => { + let left = start + let right = end + const pivot = nums[start] + while (left < right) { + while (left < right && nums[right] > pivot) { + right-- + } + while (left < right && nums[left] < pivot) { + left++ + } + if (nums[left] === nums[right] && left < right) { + left++ + } else { + [nums[left], nums[right]] = [nums[right], nums[left]] + } + } + if (start < left - 1) { + quickSort(nums, start, left - 1) + } + if (right + 1 < end) { + quickSort(nums, right + 1, end) + } + return nums +} +``` + +#### 堆排序 + +```java + +``` + diff --git "a/\345\205\245\351\227\250\357\274\210Java\357\274\211/\347\273\217\345\205\270\347\256\227\346\263\225TS\345\256\236\347\216\260.md" "b/\345\205\245\351\227\250\357\274\210Java\357\274\211/\347\273\217\345\205\270\347\256\227\346\263\225TS\345\256\236\347\216\260.md" deleted file mode 100644 index 149f021..0000000 --- "a/\345\205\245\351\227\250\357\274\210Java\357\274\211/\347\273\217\345\205\270\347\256\227\346\263\225TS\345\256\236\347\216\260.md" +++ /dev/null @@ -1,55 +0,0 @@ -### 排序算法 - -| 算法 | 稳定 | 原地排序 | 时间复杂度 | 空间复杂度 | 备注 | -| :--------------: | :--: | :------: | :--------------------------: | :--------: | :----------------------: | -| 冒泡排序 | yes | yes | N^2^ | 1 | | -| 选择排序 | no | yes | N2 | 1 | | -| 插入排序 | yes | yes | N \~ N2 | 1 | 时间复杂度和初始顺序有关 | -| 希尔排序 | no | yes | N 的若干倍乘于递增序列的长度 | 1 | | -| 快速排序 | no | yes | NlogN | logN | | -| 三向切分快速排序 | no | yes | N \~ NlogN | logN | 适用于有大量重复主键 | -| 归并排序 | yes | no | NlogN | N | | -| 堆排序 | no | yes | NlogN | 1 | | - -#### 选择排序 - -```java - -``` - -#### 冒泡排序 - -```java - -``` - -#### 插入排序 - -```java - -``` - -#### 希尔排序 - -```java - -``` - -#### 归并排序 - -```java - -``` - -#### 快速排序 - -```java - -``` - -#### 堆排序 - -```java - -``` - diff --git "a/\345\237\272\347\241\200\347\256\227\346\263\225\347\257\207/\345\212\250\346\200\201\350\247\204\345\210\222.md" "b/\345\237\272\347\241\200\347\256\227\346\263\225\347\257\207/\345\212\250\346\200\201\350\247\204\345\210\222.md" index 6a7ca77..ac55938 100644 --- "a/\345\237\272\347\241\200\347\256\227\346\263\225\347\257\207/\345\212\250\346\200\201\350\247\204\345\210\222.md" +++ "b/\345\237\272\347\241\200\347\256\227\346\263\225\347\257\207/\345\212\250\346\200\201\350\247\204\345\210\222.md" @@ -79,7 +79,7 @@ console.log(minimumTotal(tringle)); //11 `f(i,j)=min(f(i+1,j),f(i+1,j+1))+triangle[i][j]` -```js +```tsx var minimumTotal = function(tringle){ let row = tringle.length; let dp = new Array(row+1).fill(0); @@ -90,6 +90,20 @@ var minimumTotal = function(tringle){ } return dp[0]; } + +function minimumTotal(triangle: number[][]): number { // 时间、空间复杂度O(n2) + const len = triangle.length + const ans: number[][] = new Array(len).fill(0).map(() => new Array(len).fill(0)) + ans[0][0] = triangle[0][0] + for (let i = 1; i < len; i++) { + ans[i][0] = ans[i - 1][0] + triangle[i][0] + for (let j = 1; j < triangle[i].length; j++) { + ans[i][j] = Math.min(ans[i - 1][j], ans[i - 1][j - 1]) + triangle[i][j] + } + ans[i][i] = ans[i - 1][i - 1] + triangle[i][i] + } + return Math.min(...ans[len - 1]) +}; ``` ## 递归和动规关系 @@ -104,7 +118,7 @@ Function(x) { } ``` -动态规划:是一种解决问题的思想,大规模问题的结果,是由小规模问 题的结果运算得来的。动态规划可用递归来实现(Memorization Search) +动态规划:是一种解决问题的思想,大规模问题的结果,是由小规模问题的结果运算得来的。动态规划可用递归来实现(Memorization Search)。 ## 使用场景 @@ -127,7 +141,7 @@ Function(x) { 2. 方程 Function - 状态之间的联系,怎么通过小的状态,来算大的状态 3. 初始化 Intialization - - 最极限的小状态是什么, 起点 + - 最极限的小状态是什么, 起点 4. 答案 Answer - 最大的那个状态是什么,终点 @@ -299,14 +313,6 @@ function jump(nums: number[]): number { //从前往后推 给你一个字符串 `s`,请你将 `s` 分割成一些子串,使每个子串都是回文。返回符合要求的 最少分割次数 。 -```tsx - -``` - -##### [300. 最长递增子序列](https://leetcode-cn.com/problems/longest-increasing-subsequence/) - -给你一个整数数组 `nums` ,找到其中最长严格递增子序列的长度。 - ##### [300. 最长递增子序列](https://leetcode-cn.com/problems/longest-increasing-subsequence/) 给你一个整数数组 nums ,找到其中最长严格递增子序列的长度。 diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204\347\257\207/\344\272\214\345\217\211\346\240\221.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204\347\257\207/\344\272\214\345\217\211\346\240\221.md" index cd7e2f5..961f54b 100644 --- "a/\346\225\260\346\215\256\347\273\223\346\236\204\347\257\207/\344\272\214\345\217\211\346\240\221.md" +++ "b/\346\225\260\346\215\256\347\273\223\346\236\204\347\257\207/\344\272\214\345\217\211\346\240\221.md" @@ -2,24 +2,35 @@ ### 二叉树遍历 -**前序遍历**:**先访问根节点**,再前序遍历左子树,再前序遍历右子树 **中序遍历**:先中序遍历左子树,**再访问根节点**,再中序遍历右子树 **后序遍历**:先后序遍历左子树,再后序遍历右子树,**再访问根节点**。 +**前序遍历**:**先访问根节点**,再前序遍历左子树,再前序遍历右子树。**中序遍历**:先中序遍历左子树,**再访问根节点**,再中序遍历右子树。**后序遍历**:先后序遍历左子树,再后序遍历右子树,**再访问根节点**。 注意点: - 以根访问顺序决定是什么遍历 - 左子树都是优先右子树 -##### 树结构 +#### 树结构 -```js +```tsx function TreeNode(val){ this.val = val; this.left = null; this.right = null; } + +class TreeNode { // es6 + ts + val: any + left: TreeNode | null + right: TreeNode | null + constructor(val: any){ + this.val = val + this.left = null + this.right = null + } +} ``` -##### 根据数组构建二叉树 +#### 根据数组构建二叉树 ```js const buildTreeByArray = function (array, index) { @@ -44,7 +55,7 @@ const arr = [1,2,3,null,4,5,null,null,null,6,7]; let root = binaryTree(arr); ``` -##### 前序递归 +#### 前序递归 ```js function preOrder(root) { @@ -57,7 +68,7 @@ function preOrder(root) { } ``` -##### 前序非递归 +#### 前序非递归 ```js const preOrderTraversal = function (root) { @@ -81,7 +92,7 @@ const preOrderTraversal = function (root) { } ``` -##### 中序递归 +#### 中序递归 ```js function inOrder(root){ @@ -94,7 +105,7 @@ function inOrder(root){ } ``` -##### 中序非递归 +#### 中序非递归 ```js const inOrderTraversal = function(root){ @@ -117,7 +128,7 @@ const inOrderTraversal = function(root){ } ``` -##### 后序递归 +#### 后序递归 ```js function postOrder(root){ @@ -130,7 +141,7 @@ function postOrder(root){ } ``` -##### 后序非递归 +#### 后序非递归 ```js const postOrderTraversal = function(root){ //翻转非递归 后序遍历 @@ -154,7 +165,7 @@ const postOrderTraversal = function(root){ //翻转非递归 后序遍历 } ``` -##### 深度搜索 +#### 深度搜索DFS ```js const dfsUpToDown = function(root){ //递归,从上到下 @@ -194,7 +205,7 @@ const divideAndConquer = function(node){ //分治法 } ``` -##### 广度搜索 +#### 广度搜索BFS ```js const bfs = function(root){