LeetCode刷题日常:排序三剑客和TwoSum的爆笑算法江湖

146 阅读4分钟

前言:算法世界的“段子手”修炼记

大家好,我是一个在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只是开始,更多的算法故事等你来解锁。下次再遇到算法题,别忘了带上你的幽默感,笑着把题做完!


项目源码已开源,欢迎点赞、收藏、评论,和我一起用段子学算法,快乐刷题!