From 976df4af9d4b68997e8c24d822ea53738584eb08 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=AE=B5=E5=90=95=E6=AC=A3?= <2316636696@qq.com> Date: Mon, 26 Aug 2024 00:08:27 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E7=AE=97=E6=B3=95-=E6=8E=92=E5=BA=8F?= =?UTF-8?q?=E4=B8=8E=E5=8F=8C=E6=8C=87=E9=92=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...16\345\217\214\346\214\207\351\222\210.md" | 208 ++++++++++++++++++ 1 file changed, 208 insertions(+) create mode 100644 "source/_posts/\347\256\227\346\263\225-\346\216\222\345\272\217\344\270\216\345\217\214\346\214\207\351\222\210.md" diff --git "a/source/_posts/\347\256\227\346\263\225-\346\216\222\345\272\217\344\270\216\345\217\214\346\214\207\351\222\210.md" "b/source/_posts/\347\256\227\346\263\225-\346\216\222\345\272\217\344\270\216\345\217\214\346\214\207\351\222\210.md" new file mode 100644 index 0000000..394e2e1 --- /dev/null +++ "b/source/_posts/\347\256\227\346\263\225-\346\216\222\345\272\217\344\270\216\345\217\214\346\214\207\351\222\210.md" @@ -0,0 +1,208 @@ +--- +title: 算法-排序与双指针 +date: 2024-08-23 21:52:10 +categories: + - 数据结构与算法 +tags: + - js + - 算法 +cover: https://assets.leetcode.cn/aliyun-lc-upload/uploaded_files/2021/03/73c9f099-abbe-4d94-853f-f8abffd459cd/leetcode.png +--- + +## 排序 + +O(n^2)的排序算法:冒泡,选择,插入 +O(nlogn)的排序算法:快排,归并 +O(n)的排序算法:桶排序,计数排序,基数排序 + +### 冒泡排序 +1.第一轮,相邻的两个两两比较,把最小的冒泡到第1个 +2.第二轮,相邻的两个两两比较,把第二小的冒泡到第2个 +3.重复len-1轮 + +```js +function bubbleSort(arr) { + for (let i = 0; i < arr.length - 1; i++) { + for (let j = arr.length - 1; j > i; j--) { + if (arr[j - 1] > arr[j]) { + [arr[j - 1], arr[j]] = [arr[j], arr[j - 1]] + } + } + } +} +``` + +或者反过来想,把最大的冒泡到最后面 +```js +function bubbleSort(arr) { + for (let i = arr.length - 1; i > 1; i--) { + for (let j = 0; j < i; j++) { + if (arr[j] > arr[j + 1]) { + [arr[j + 1], arr[j]] = [arr[j], arr[j + 1]] + } + } + } +} +``` + +### 选择排序 +1.第一轮,选取最小的放到第1个 +2.第二轮,选取第二小的放到第2个 +3.重复len-1轮 + +```js +function selectSort(arr) { + for(let i=0;i= 0) { + if (arr[j] > currentVal) { + arr[j + 1] = arr[j] + j-- + } else { + break; + } + } + arr[j + 1] = currentVal + } +} +``` + +### 快速排序 +1.从数组中选取一个作为pivot,把小于等于pivot的移到左边,把大于pivot的移到右边 +2.继续快速排序左边的和右边的 + +```js +// 非原地排序版本 +function quickSort(arr) { + + if(arr.length <= 1) return arr; + + const pivotIndex = Math.floor(Math.random(0, arr.length)); + const pivot = arr[pivotIndex]; + + let left = arr.filter((item,index)=>item<=pivot && index!==pivotIndex); + let right = arr.filter((item)=>item>pivot); + + return [...quickSort(left), pivot, ...quickSort(right)] +} +``` + +```js +// 原地排序版本 +function quickSort(arr) { + + function q(arr, low, high) { + + if(high-low<=0) return; + + const pivotIndex = low + Math.floor(Math.random(0, high+1)); + const pivot = arr[pivotIndex]; + + let i=low,j=high + while(true) { + while(arr[i]<=pivot) { + i++ + } + + while(arr[j]>pivot) { + j-- + } + + if(i>=j) break; + + [arr[i], arr[j]] = [arr[j], arr[i]] + i++ + j-- + } + // 把pivot放到合适的位置上 + [arr[pivotIndex] , arr[j]] = [arr[j], arr[pivotIndex]] + + q(arr, low, j - 1) + q(arr, j + 1, high) + } + + q(arr, 0 ,arr.length - 1) +} +``` + +### 归并排序 +1.排序左边的,排序右边的 +2.合并两个有序数组 + +```js +function mergeSort(arr) { + if (arr.length <= 1) return arr; + + let mid = (arr.length >> 1) - 1; // 这里不减一的话数组长度为2时会无限递归 + + const left = mergeSort(arr.slice(0, mid + 1)) + const right = mergeSort(arr.slice(mid + 1)) + + function merge(arr1, arr2) { + let res = [] + let i = 0, j = 0 + + while (i < arr1.length && j < arr2.length) { + if (arr1[i] < arr2[j]) { + res.push(arr1[i++]) + } else { + res.push(arr2[j++]) + } + } + + if (i < arr1.length) { + res = res.concat(arr1.slice(i)) + } + if (j < arr2.length) { + res = res.concat(arr2.slice(j)) + } + + return res; + } + + return merge(left, right) +} +``` + +### 桶排序 +按照一定的算法分为n个桶,使数字能较为均匀的分布到n个桶中。 +如第1个桶放小于10的,第2个桶放10~20的 +然后对每个桶进行排序,最后按顺序合并每个桶得到最终的结果。 + +### 计数排序 +计数排序时特殊的桶排序。 +比如说分数是0~100分,那么就分101个桶。 + +### 基数排序 +只能排序非负整数。 +比如说十进制的数,先按个位数排序,再按十位数排序。 + +## 双指针 + +1. 环形链表:https://leetcode.cn/problems/linked-list-cycle-ii/description/ + 两个指针,一个指针一次前进1,一个指针1次前进2;如果有环,这两个指针一定会相遇 +2. 返回arr的最长无重复子数组的长度:https://leetcode.cn/problems/longest-substring-without-repeating-characters/description/ +3. 最长上升子序列: https://leetcode.cn/problems/longest-increasing-subsequence/description/ +4. 盛水最多的容器: https://leetcode.cn/problems/container-with-most-water/description/ +5. 三数之和:https://leetcode.cn/problems/3sum/description/ \ No newline at end of file