本文已参与[新人创作礼]活动,一起开启掘金创作之路。
记录一下常用的排序
| 名称 | 时间复杂度 |
|---|---|
| 冒泡排序 | O(n^2) |
| 快速排序 | O(nlgn) |
冒泡排序
const bubbleSort = arr => {
const len = arr.length - 1;
for (let j = 0; j < len; j++) {
// 已经有j个最大值在最后面了,所以遍历的长度为len - j
for (let i = 0; i < len - j; i++) {
if (arr[i] > arr[i+1]) {
[arr[i], arr[i+1]] = [arr[i+1], arr[i]]
}
console.log(arr)
}
}
return arr
}
动图:
快速排序
思路:找第一个元素作为基准值,比我大的放在右边,比我小的放在左边,然后递归的进行调用。
const quickSort = arr => {
if (arr.length < 2) {
return arr
}
let flag = arr[0];
let left = [];
let right = []
for (let i = 1; i < arr.length; i++) {
if (arr[i] > flag) {
right.push(arr[i])
} else {
left.push(arr[i])
}
}
return quickSort(left).concat(flag,quickSort(right))
}
双指针法快速排序(原地快排)
这个方法的解释掘金里面很多,直接引用
function quick(arr,start,end){
let init = start
let flag = arr[init]
start++
while(start<=end){
while(arr[end]>flag){
end--
}
while(arr[start]<flag){
start++
}
// 引用的代码里面有bug,少了边界条件,部分数据不过
// [5,1,1,2,0,0] [3,1]
if (start==end){
break
}
if(start<end){
[arr[start],arr[end]] = [arr[end],arr[start]]
start++
end--
}
};
[arr[init],arr[start-1]] = [arr[start-1],arr[init]]
return start
}
function quickSort(arr,start,end,from){
if(start<end){
let index = quick(arr,start,end,from);
// quickSort(arr,start,index-1);也是同样的效果
// index-1包含了标志位,index-2不包含
quickSort(arr,start,index-2);
quickSort(arr,index,end);
}
return arr
}
另外一个方法写的也很好,容易理解,也引用上
var sortArray = function(nums) {
function quickSort(arr, begin, end) {
if (begin >= end) {
// 引用中这里有bug,如果[3]则不过
return arr
}
let temp = arr[begin];
let left = begin;
let right = end;
while(right > left) {
while(right > left && arr[right] >= temp) {
right--;
}
while(right > left && arr[left] <= temp) {
left++;
}
[arr[left], arr[right]] = [arr[right], arr[left]];
}
[arr[begin], arr[right]] = [arr[right], arr[begin]];
quickSort(arr, begin, right - 1);
quickSort(arr, right + 1, end);
return arr;
}
return quickSort(nums, 0, nums.length - 1)
};
力扣912-排序数组可验证各种情况
力扣15-三数之和
var threeSum = function(nums) {
// 0.直接返回
if (nums.length < 3) {
return []
}
nums.sort((a,b) => a - b)
let list = []
for (let i = 0; i < nums.length; i++) {
// 4.跳过重复的数据,否则结果数组里面会有重复
if(nums[i]===nums[i-1]){
continue
}
// 1.以i为基准,左侧指针和右侧指针都向中间移动
let left = i + 1;
let right = nums.length - 1;
// 2.判断三个数相加为0的情况
while(left < right) {
if(right === i) {
right--
}else if (nums[left] + nums[right] + nums[i] === 0) {
list.push([nums[left],nums[right],nums[i]])
// 3.继续找是否有其他符合情况
while(nums[left] === nums[left+1]) {
left++
}
left++
while(nums[right] === nums[right-1]) {
right--
}
right--
} else if (nums[left] + nums[right] + nums[i] > 0) {
right--
} else {
left++
}
}
}
return list;
};
const nums = [-1,0,1,2,-1,-4]
console.log(threeSum(nums))