day4 DFS后序传值的递归模拟与四对顺序的值传递

var fib = function(n) {
    const dp = [0,1] //注意其他位置都为undefined
    const dfs = (i) => {
        if(dp[i] !== undefined) return dp[i]
        return dp[i] = dfs(i-1) + dfs(i-2)
    }
    return dfs(n)
};

var fib = function(n) {
    const dp = [0,1]
    const dfs = (i) => {
        const stack = [[i,0]] //代表代码扩展了几次,可以用来推断目前执行到哪一行
        const returnVal = []
        while(stack.length){
            //执行栈顶的函数
            const [i,vis] = stack[stack.length-1]
            
            //执行到if(dp[i] !== undefined) 
            if(dp[i] !== undefined){
                stack.pop()
                returnVal[i] = dp[i]
            }
          
            //执行到dfs(i-1)
            else if(vis == 0){
                stack[stack.length-1][1]++ 
                stack.push([i-1,0])
            }
          
            //执行到dfs(i-2)
            else if(vis == 1){
                stack[stack.length-1][1]++
                stack.push([i-2,0])
            }
          
            else if(vis == 2){
               stack.pop()
               dp[i] = returnVal[i-1] + returnVal[i-2]
               returnVal[i] = dp[i]
            }
        }
    }
    dfs(n)
    return dp[n]
};

class Node{
    constructor(val){
        this.val = val 
        this.prevs = [] //前驱节点
        this.nexts = [] //后驱节点
    }
}

var fib = function(n) {
    if(n === 0 || n === 1) return n
    const dp = [new Node(0),new Node(1)]
    const topo = []
    let cnt = 0 
    const dfs = (i,nxt) => {
        if(dp[i] !== undefined){
            dp[i].nexts.push(nxt)
            return dp[i].val 
        } 
        dp[i] = new Node()
        dp[i].nexts.push(nxt)  //先序 * 邻接 → 后驱节点
        cnt++                  //先序 * 访问 → 节点个数
        dp[i] = new Node(dfs(i-1,dp[i]) + dfs(i-2,dp[i])) //后序*邻接 → FN传递
        topo.push(i) //后序*访问 → 拓扑排序
        return dp[i].val
    }
    return dfs(n,null)
};

var minimumScore = function(nums, edges) {
    //1、建图
    const n = nums.length
    const graph = new Array(n).fill(0).map(()=>[])
    for(let [x,y] of edges){
        graph[x].push(y)
        graph[y].push(x)
    }

    //2、父子
    const begin = new Array(n).fill(0) //
    const end = new Array(n).fill(0)   //
    const xor = nums
    let timestamp = 0 
    const dfs = (cur,pre) => {
        begin[cur] = timestamp++ //先序 * 访问:timestamp  
        for(let next of graph[cur]){
            if(pre === next) continue 
            dfs(next,cur)  //先序 * 邻接:cur
            xor[cur] ^= xor[next] //后序 * 邻接:xor[cur]
        }
        end[cur] = timestamp //后序 * 访问  = timestamp是前面的最大值
    }
    dfs(0,-1) //将0作为根节点进行处理
    
    //判断x是否为y的祖先节点
    const isAncestor = (x,y)=> begin[x] < begin[y] && end[y] <= end[x]  
     
    //3、检验:枚举需要独立的两颗子树是什么
    //1 ^ 2 ^ 3 ^ 1
    let res = Infinity
    let tree1 = 0
    let xor1,xor2,xor3
    for(let tree2 = 1; tree2 < n-1; tree2++){
        for(let tree3 = tree2 + 1; tree3 < n; tree3++){
            //tree2是tree3的祖先
            if(isAncestor(tree2,tree3)){
                xor1 = xor[tree1] ^ xor[tree2] //删除tree2
                xor2 = xor[tree2] ^ xor[tree3] //删除tree3
                xor3 = xor[tree3]           
            }
            //tree3是tree2的祖先
            else if(isAncestor(tree3,tree2)){
                xor1 = xor[tree1] ^ xor[tree3] //删除tree3
                xor2 = xor[tree2]  
                xor3 = xor[tree3] ^ xor[tree2] //删除tree2
            }
            else{
                xor1 = xor[tree1] ^ xor[tree2] ^ xor[tree3] //删除tree2 + 删除tree3
                xor2 = xor[tree2]  
                xor3 = xor[tree3]
            }
            res = Math.min(res,Math.max(xor1,xor2,xor3) - Math.min(xor1,xor2,xor3)    )
        }
    }
    return res 
};

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值