• 第二章、数据结构与算法


    十一、算法-排序和搜索

    1、排序和搜索简介
    /**
     * 一、排序和搜索是什么?
     *     - 排序:把某个乱序的数组变成升序或者降序的数组
     *     - 搜索:找出数组中某个元素的下标
     * 二、js中的排序和搜索
     *     - js中的排序:数组的sort方法
     *     - js中的搜索:数组的indexOf方法
     * 三、排序算法
     *     - 冒泡排序
     *     - 选择排序
     *     - 插入排序
     *     - 归并排序
     *     - 快速排序
     *     - ...
     * 四、搜索算法
     *     - 顺序搜索
     *     - 二分搜索
     *     - ...
     */
    
    2、javascript实现:冒泡排序
    Array.prototype.bubbleSort = function () {
        for (let i = 0; i < this.length - 1; i++) {
            for (let j = 0; j < this.length - 1 - i; j++) {
                if (this[j] > this[j + 1]) {
                    const temp = this[j]
                    this[j] = this[j + 1]
                    this[j + 1] = temp
                }
            }
        }
    }
    
    3、javascript实现:选择排序
    Array.prototype.selectionSort = function () {
        for (let i = 0; i < this.length - 1; i++) {
            let indexMin = i
            for (let j = i; j < this.length; j++) {
                if (this[j] < this[indexMin]) {
                    indexMin = j
                }
            }
            if (indexMin !== i) {
                const temp = this[i]
                this[i] = this[indexMin]
                this[indexMin] = temp
            }
        }
    }
    
    4、javascript实现:插入排序
    Array.prototype.insertionSort = function () {
        for (let i = 0; i < this.length; i++) {
            const temp = this[i]
            let j = i
            while (j > 0) {
                if (this[j - 1] > temp) {
                    this[j] = this[j - 1]
                } else {
                    break
                }
                j -= 1
            }
            this[j] = temp
        }
    }
    
    5、javascript实现:归并排序
    Array.prototype.mergeSort = function () {
        const rec = (arr) => {
            if (arr.length === 1) {
                return arr
            }
            const mid = Math.floor(arr.length / 2)
            const left = arr.slice(0, mid)
            const right = arr.slice(mid, arr.length)
            const orderLeft = rec(left)
            const orderRight = rec(right)
            const res = []
            while (orderLeft.length || orderRight.length) {
                if (orderLeft.length && orderRight.length) {
                    res.push(orderLeft[0] < orderRight[0] ? orderLeft.shift() : orderRight.shift())
                } else if (orderLeft.length) {
                    res.push(orderLeft.shift())
                } else if (orderRight.length) {
                    res.push(orderRight.shift())
                }
            }
            return res
        }
        const res = rec(this)
        res.forEach((n, i) => {
            this[i] = n
        })
    }
    
    6、javascript实现:快速排序
    Array.prototype.quickSort = function () {
        const rec = (arr) => {
            if (arr.length <= 1) {
                return arr
            }
            const left = []
            const right = []
            const mid = arr[0]
            for (let i = 1; i < arr.length; i++) {
                if (arr[i] < mid) {
                    left.push(arr[i])
                } else {
                    right.push(arr[i])
                }
            }
            return [...rec(left), mid, ...rec(right)]
        }
        const res = rec(this)
        res.forEach((n, i) => {
            this[i] = n
        })
    }
    
    7、javascript实现:顺序搜索
    Array.prototype.sequentialSearch = function (item) {
        for (let i = 0; i < this.length; i++) {
            if (this[i] === item) {
                return i
            }
        }
        return -1
    }
    
    8、javascript实现:二分搜索
    Array.prototype.binarySearch = function (item) {
        let low = 0
        let high = this.length - 1
        while (low <= high) {
            const mid = Math.floor((low + high) / 2)
            const element = this[mid]
            if (element < item) {
                low = mid + 1
            } else if (element > item) {
                high = mid - 1
            } else {
                return mid
            }
        }
        return -1
    }
    
    9、力扣解题(21. 合并两个有序链表)
    var mergeTwoLists = function (list1, list2) {
        const res = new ListNode(0)
        let p = res
        let p1 = list1
        let p2 = list2
        while (p1 && p2) {
            if (p1.val < p2.val) {
                p.next = p1
                p1 = p1.next
            } else {
                p.next = p2
                p2 = p2.next
            }
            p = p.next
        }
        if (p1) {
            p.next = p1
        }
        if (p2) {
            p.next = p2
        }
        return res.next
    };
    
    10、力扣解题(374. 猜数字大小)
    var guessNumber = function (n) {
        let low = 1
        let high = n
        while (low <= high) {
            const mid = Math.floor((low + high) / 2)
            const res = guess(mid)
            if (res === 0) {
                return mid
            } else if (res === 1) {
                low = mid + 1
            } else {
                high = mid - 1
            }
        }
    };
    

    十二、算法设计思想-分而治之

    1、分而治之简介
    /**
     * 一、分而治之是什么?
     *     - 分而治之是算法设计中的一种方法
     *     - 它将一个问题分成多个和原问题相似的小问题,递归解决小问题,再将结果合并以解决原来的问题
     * 二、场景一:归并排序
     *     - 分:把数组从中间一分为二
     *     - 解:递归地对两个子数组进行归并排序
     *     - 合:合并有序子数组
     * 三、场景二:快速排序
     *     - 分:选基准,按基准把数组分成两个子数组
     *     - 解:递归地对两个子数组进行快速排序
     *     - 合:对两个子数组进行合并
     */
    
    2、力扣解题(226. 翻转二叉树)
    var invertTree = function (root) {
        if (!root) {
            return null
        }
        return {
            val: root.val,
            left: invertTree(root.right),
            right: invertTree(root.left)
        }
    };
    
    3、力扣解题(100. 相同的树)
    var isSameTree = function (p, q) {
        if (!p && !q) return true
        if (
            p && q && p.val === q.val &&
            isSameTree(p.left, q.left) &&
            isSameTree(p.right, q.right)
        ) {
            return true
        }
        return false
    };
    
    4、力扣解题(101. 对称二叉树)
    var isSymmetric = function (root) {
        if (!root) return true
        const isMirror = (l, r) => {
            if (!l && !r) return true
            if (
                l && r && l.val === r.val &&
                isMirror(l.left, r.right) &&
                isMirror(l.right, r.left)
            ) {
                return true
            }
            return false
        }
        return isMirror(root.left, root.right)
    };
    

    十三、算法设计思想-动态规划

    1、动态规划简介
    /**
     * 一、动态规划是什么?
     *     - 动态规划是算法设计中的一种方法
     *     - 它将一个问题分解为相互重叠的子问题,通过反复求解子问题,来解决原来的问题
     * 二、动态规划的步骤
     *     - 定义子问题
     *     - 反复执行
     */
    
    2、力扣解题(70. 爬楼梯)
    var climbStairs = function (n) {
        if (n < 2) {
            return 1
        }
        let dp0 = 1
        let dp1 = 1
        for (let i = 2; i <= n; i++) {
            const temp = dp0
            dp0 = dp1
            dp1 = dp1 + temp
        }
        return dp1
    };
    
    3、力扣解题(198. 打家劫舍)
    var rob = function (nums) {
        if (nums.length === 0) {
            return 0
        }
        let dp0 = 0
        let dp1 = nums[0]
        for (let i = 2; i <= nums.length; i++) {
            const dp2 = Math.max(dp0 + nums[i - 1], dp1)
            dp0 = dp1
            dp1 = dp2
        }
        return dp1
    };
    

    十四、算法设计思想-贪心算法

    1、贪心算法简介
    /**
     * 一、贪心算法是什么?
     *     - 贪心算法是算法设计中的一种方法
     *     - 期盼通过每个阶段的局部最优选择,从而达到全局的最优
     *     - 结果不一定是最优
     */
    
    2、力扣解题(455. 分发饼干)
    var findContentChildren = function (g, s) {
        const sortFunc = function (a, b) {
            return a - b
        }
        g.sort(sortFunc)
        s.sort(sortFunc)
        let i = 0
        s.forEach(n => {
            if (n >= g[i]) {
                i += 1
            }
        })
        return i
    };
    
    3、力扣解题(122. 买卖股票的最佳时机 II)
    var maxProfit = function (prices) {
        let profit = 0
        for (let i = 1; i < prices.length; i++) {
            if (prices[i] > prices[i - 1]) {
                profit += prices[i] - prices[i - 1]
            }
        }
        return profit
    };
    

    十五、算法设计思想-回溯算法

    1、回溯算法简介
    /**
     * 一、回溯算法是什么?
     *     - 回溯算法是算法设计中的一种方法
     *     - 回溯算法是一种渐进式寻找并构建问题解决方式的策略
     *     - 回溯算法会先从一个可能的动作开始解决问题,如果不行,就回溯并选择另一个动作,直到将问题解决
     * 二、什么问题适合用回溯算法解决?
     *     - 有很多路
     *     - 这些路里,有死路,也有出路
     *     - 通常需要递归来模拟所有的路
     */
    
    2、力扣解题(46. 全排列)
    var permute = function (nums) {
        const res = []
        const backtrack = (path) => {
            if (path.length === nums.length) {
                res.push(path)
                return
            }
            nums.forEach(n => {
                if (path.includes(n)) {
                    return
                }
                backtrack(path.concat(n))
            })
        }
        backtrack([])
        return res
    };
    
    3、力扣解题(78. 子集)
    var subsets = function (nums) {
        const res = []
        const backtrack = (path, l, start) => {
            if (path.length === l) {
                res.push(path)
                return
            }
            for (let i = start; i < nums.length; i++) {
                backtrack(path.concat(nums[i]), l, i + 1)
            }
        }
        for (let i = 0; i <= nums.length; i++) {
            backtrack([], i, 0)
        }
        return res
    };
    
  • 相关阅读:
    [NOI2003]文本编辑器
    [TyvjP1413]费用流模板裸题
    POJ 3255 dijkstra次短路
    [TyvjP1474]二维线段树区间更新+查询
    [转]二分图的必须边
    匈牙利算法代码及理解
    jloi2013一些想法
    uva11987 并查集小技巧
    【水】tyvj1523 平面几何入门
    Tyvj1462 细节凸包
  • 原文地址:https://www.cnblogs.com/linding/p/16436306.html
Copyright © 2020-2023  润新知