前言:算法世界的“段子手”修炼记
大家好,我是一个在LeetCode江湖里摸爬滚打的前端选手。你以为算法只有枯燥的代码和复杂的公式?错!其实每一道题背后都有一段“江湖传说”。今天就带你用最幽默的方式,解锁排序三剑客(冒泡、选择、插入)和TwoSum的算法奥义,让你笑着把算法学明白!
一、排序三剑客:谁才是江湖最快刀?
1. 冒泡排序:算法界的“搓澡工”
冒泡排序的精髓就是“比大小,换位置”,就像搓澡一样,一遍一遍把最大的搓到最后。
function bubbleSort(arr){
const len = arr.length
for (let i = 0; i < len - 1; i++){
for (let j = 0; j < len - i - 1; j++){
if (arr[j] > arr[j + 1]){
[arr[j], arr[j + 1]] = [arr[j + 1], arr[j]]
}
}
}
return arr
}
console.log(bubbleSort([5, 3, 2, 4, 1]));
技术点:双重for循环,内层负责“搓澡”,外层负责“轮数”,每轮把最大值送到最后。
幽默点评:冒泡排序的效率就像老大爷搓澡,慢工出细活,O(n²)的时间复杂度,适合小数组“搓一搓”。
2. 选择排序:算法界的“选美大赛”
选择排序每轮都选出“最美”的(最小的)站到队首,剩下的继续选,直到全队“颜值”有序。
function selectionSort(arr){
const len = arr.length
let minIndex = 0
for (let i = 0; i< len; i++){
minIndex = i
const currentMin = getMin(minIndex, len - 1, arr)
if (currentMin !== minIndex) {
[arr[minIndex],arr[currentMin]] = [arr[currentMin],arr[minIndex]]
}
}
return arr
}
function getMin(i, j, arr){
let min = Infinity, o = 0
for (let k = i; k <= j; k++){
if(arr[k] < min){
min = arr[k]
o = k
}
}
return o
}
console.log(selectionSort([5, 3, 2, 4, 1]));
技术点:每轮找最小值,和当前位置交换,O(n²)时间复杂度。
幽默点评:选美大赛,冠军轮流上台,效率依然感人,适合“颜值控”程序员。
3. 插入排序:算法界的“插队高手”
插入排序像极了食堂排队,后来的同学总想插到合适的位置。
function insertionSort(arr) {
for (let i = 1; i < arr.length; i++) {
let key = arr[i]
let j = i - 1
while (j >= 0 && arr[j] > key) {
arr[j + 1] = arr[j]
j--
}
arr[j + 1] = key
}
return arr
}
console.log(insertionSort([5, 3, 2, 4, 1]));
技术点:外层遍历,内层“倒着”找插入点,O(n²)时间复杂度,但对近乎有序的数组很友好。
幽默点评:插队有风险,排序需谨慎。插入排序在“快餐店”表现最佳!
二、TwoSum:算法界的“神雕侠侣”
1. 暴力解法:双指针“左拥右抱”
var twoSum = function(nums, target) {
for (let i = 0; i < nums.length; i++) {
let left = nums[i]
for (let j = i + 1; j < nums.length; j++) {
let right = nums[j]
if (left + right === target) {
return [i, j]
}
}
}
}
console.log(twoSum([2,7,11,15], 9)) // [0, 1]
技术点:双重for循环,O(n²)时间复杂度,简单粗暴。
幽默点评:左手牵右手,暴力出奇迹。适合“初恋型”程序员,简单直接。
2. 哈希表解法:空间换时间的“速配神器”
var twoSum = function(nums, target) {
let diffs = {}
for (let i = 0; i < nums.length; i++) {
let item = target - nums[i]
if (diffs[item] != undefined && diffs[item] != i) {
return [diffs[item], i]
}
diffs[nums[i]] = i;
}
}
console.log(twoSum([2,7,11,15], 9)) // [0, 1]
技术点:用哈希表存储已遍历的数字,查找target-nums[i]是否出现过,O(n)时间复杂度。
幽默点评:速配神器上线,单身狗也能一秒脱单!空间换时间,效率飞起。
三、JS数组骚操作:排序只是“开胃菜”
const arr = [3, 5, 7, 2, 1, {b: -2}, {a: -1}]
arr.sort(function(a,b){
return b - a
})
console.log(arr)
技术点:sort方法自定义比较函数,JS数组的灵活性让你“为所欲为”。
幽默点评:JS数组就像川菜,花样百出,辣得你直呼过瘾!
四、复杂度分析:时间和空间的“爱恨情仇”
- 时间复杂度:O(1)、O(n)、O(n²)……算法的“速度表”
- 空间复杂度:O(1)、O(n)……算法的“内存账单”
幽默点评:时间和空间就像“前任”和“现任”,总要权衡取舍,不能全都要!
五、面试官的灵魂拷问
- “你能手写冒泡/选择/插入排序吗?”
- “TwoSum你会几种解法?”
- “时间复杂度怎么算?”
答题锦囊:代码要会写,原理要会讲,复杂度要会算,幽默要加分!
六、总结:算法江湖,笑着闯!
算法不是枯燥的刷题,而是有趣的“江湖修炼”。排序三剑客和TwoSum只是开始,更多的算法故事等你来解锁。下次再遇到算法题,别忘了带上你的幽默感,笑着把题做完!
项目源码已开源,欢迎点赞、收藏、评论,和我一起用段子学算法,快乐刷题!