一路繁花似锦绣前程
失败的越多,成功才越有价值

导航

 

十一、算法-排序和搜索

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
};
posted on 2022-07-02 00:29  一路繁花似锦绣前程  阅读(30)  评论(0编辑  收藏  举报