算法杂记(三)

177 阅读3分钟

「这是我参与2022首次更文挑战的第10天,活动详情查看:2022首次更文挑战

全排列

题目信息

解法一

递归回溯法

这里先定义一个set(用来保存一个一个结果,并且用来判断元素有无在里面)和一个res(结果集)。然后从第一个数开始,不收集重复的,然后递归,直到set长度一样,或者循环走完,返回。

举个例子:[1,2,3]进行全排列

第一层dfs函数 i = 0 set=[1]
第二层dfs函数 i = 0 set = [1] set里面有1,跳过
第二层dfs函数 i = 1 set = [1,2]
第三层dfs函数 i = 0 set = [1,2],set里面有1,跳过
第三层dfs函数 i = 1 set = [1,2],set里面有2,跳过
第三层dfs函数 i = 2 set = [1,2,3]
第四层dfs函数 set长度和nums长度一样,set转数组进结果集,返回上一层
第三层dfs函数 i = 2 set = [1,2],3被删掉了,循环结束,函数结束返回上一层
第二层dfs函数 i = 1 set = [1],2被删掉了
第二层dfs函数 i = 2 set = [1,3]
第三层dfs函数 i = 0 set = [1,2],set里面有1,跳过
第三层dfs函数 i = 1 set = [1,3,2]
第四层dfs函数 set长度和nums长度一样,set转数组进结果集,返回上一层
第三层dfs函数 i = 1 set = [1,3],2被删掉了
第三层dfs函数 i = 2 set = [1,3],set里有3,跳过,此时循环结束,函数结束返回上一层
var permute = function(nums) {
    let set = new Set()
    let res = []
    function dfs(){
        if(set.size === nums.length){
            res.push(Array.from(set))
            return
        }
        for(let i = 0;i < nums.length;i++){
            if(set.has(nums[i])) continue
            set.add(nums[i])
            dfs()
            set.delete(nums[i])
        }
    }
    dfs()
    return res
};

最大子序和

题目信息

解法一

递归:

这里其实也算是动态规划,因为这里我们有一个公式 f(i)=max(f(i-1) + nums[i],nums[i]) ,就是说求f(i)的最大,其实是取决f(i-1) + nums[i] 和 nums[i]的大小,我们希望得到一个最大的。得到当前最大后和之前保存的最长子序和进行比较,得到一个心得最长子序和。

var maxSubArray = function(nums) {
    let maxSum = nums[0]
    let pre = 0
    function dp(i){
        if(i === 0){
            return nums[0]
        } 
        pre = Math.max(dp(i - 1) + nums[i],nums[i])
        maxSum = Math.max(pre,maxSum)
        return pre
    }
    dp(nums.length-1)
    return maxSum
};

解法二

动态规划:

与上面同理,只是从前面开始了,直到遍历后面,保存两个值,一个是maxSum,即当前的最长子序和,一个是(i-1)位的最长子序和,当前(i)位的最长子序和也就是上一位的最长子序和加上当前的nums[i],与nums[i]做一个对比,我们希望得到比较大的那一个,之后再与保存的已知的最长子序和进行比较,得到最新的maxSum。

var maxSubArray = function(nums) {
    let maxSum = nums[0]
    let pre = 0
    for(let i = 0;i < nums.length;i++){
        pre = Math.max(pre + nums[i] , nums[i])
        maxSum = Math.max(pre,maxSum)
    }
    return maxSum
};