【LeetCode 337 & 329. memorization DFS】House Robber III

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
public:
//递归程序就是结构演绎,有点像dp,只要定义好每一次递归过程完成的是同一个目标,就能保证所有递归结束之后完成的效果是最终的目标
    int rob_naive(TreeNode* root) {// 返回当前节点开始的能够rob的最大值。
        if(root == NULL) return 0;//当前节点为空 0
        int val = 0;
        if(root -> left)//左孩子不空
            val += rob(root -> left -> left) + rob(root -> left -> right); //rob当前root 和 root 的孩子的孩子的能rob到的最大值。这里并不是rob孩子的孩子,而是孩子的孩子能rob的最大值就像这个递归结构每一次完成的目标一样。
        if(root -> right)
            val += rob(root -> right -> left) + rob(root -> right -> right);
        return max(val + root -> val, rob(root -> left) + rob(root -> right));
        //返回 rob(root, root‘s children ‘s children   or   root‘s children)
    }
    //看上面的方案(1330 ms):每一次我们都考虑了 root.left.left & root.left.right & root.right.left & root.right.right
                                    // root.left & root.right 这里在递归计算的时候还是会算到上面计算过的值。
                                    //所以给出一个考虑一步之后的优化记忆搜索。
    int rob(TreeNode* root){
        unordered_map<TreeNode*, int>mp;
        return robMemeryDFS(root, mp);
    }
    //考虑一步的记忆化搜索(16 ms): 快了接近100倍
    int robMemeryDFS(TreeNode* root, unordered_map<TreeNode*, int>&mp){
        if(root == NULL) return 0;
        if(mp[root]) return mp[root];
        int val = 0;
        if(root -> left)//左孩子不空
            val += robMemeryDFS(root -> left -> left, mp) + robMemeryDFS(root -> left -> right, mp);
        if(root -> right)
            val += robMemeryDFS(root -> right -> left, mp) + robMemeryDFS(root -> right -> right, mp);
        mp[root] = max(val + root -> val, robMemeryDFS(root -> left, mp) + robMemeryDFS(root -> right, mp));
        return mp[root];
    }
};

附加一道 同样使用记忆化搜索的题目 329. Longest Increasing Path in a Matrix

class Solution {
public:
    int dir[4][2] = {{1, 0}, {-1, 0}, {0, 1}, {0, -1}}, n, m;
    int dfs(int x, int y, vector<vector<int>>& matrix, vector<vector<int>>&steps){
        if(steps[x][y]) return steps[x][y];
        int maxSteps = 0; // record the longest path steps from (x, y)
        for(int i = 0; i < 4; i ++){
            int nx = dir[i][0] + x, ny = dir[i][1] + y, tmp = 0;
            if(nx >= 0 && ny >= 0 && nx < n && ny < m && matrix[nx][ny] > matrix[x][y]){
                maxSteps = max(maxSteps, dfs(nx, ny, matrix, steps));
            }
        }
        steps[x][y] = maxSteps + 1; // + 1 for cur(x, y)
        return steps[x][y];
    }
    int longestIncreasingPath(vector<vector<int>>& matrix) {
        if(matrix.size() == 0) return 0;
        n = matrix.size(), m = matrix[0].size();
        int ans = 0;
        vector<vector<int>>steps(n, vector<int>(m, 0));
        for(int i = 0; i < n; i ++)
            for(int j = 0; j < m; j ++)
                ans = max(ans, dfs(i, j, matrix, steps));
        return ans;
    }
};
时间: 2024-08-08 13:56:51

【LeetCode 337 & 329. memorization DFS】House Robber III的相关文章

【LeetCode】House Robber III(337)

1. Description The thief has found himself a new place for his thievery again. There is only one entrance to this area, called the "root." Besides the root, each house has one and only one parent house. After a tour, the smart thief realized tha

【LeetCode在线编程记录-1】字符串按单词反转

写在前面 LeetCode(地址:https://oj.leetcode.com/)是一个在线编程网站,题目经典,测试用例完备,共计157道算法类的题目.之后我会记录我的一些练习题目,有些答案是我自己原创的(说是原创,也很可能是之前在别的地方看到的而已),有些是从讨论区看到的,我都会明确标注出处. Reverse Words in a String Given an input string, reverse the string word by word. For example, Given

Codeforces 383C . Propagating tree【树状数组,dfs】

题目大意: 有一棵树,对这个树有两种操作:1:表示为(1 x val),在编号为x的节点上加上val,然后给x节点的每个儿子加上- val,再给每个儿子的儿子加上-(- val),一直加到没有儿子为止.2:表示为(2 x)查询x节点上的值. 做法: 由于每次修改操作修改的并不是一个值,而是很多值,那我们将该题抽象成区间修改,点查询的问题.那怎么抽象呢?可以明白的是,每次操作虽然有加有减,但是每次做加法操作,或者减法操作的都是同一部分数(也就是说,在某次加上同一个数的节点们,下次操作一定是加上或者

【LeetCode刷题Java版】Evaluate Reverse Polish Notation(计算逆波兰表达式)

Evaluate the value of an arithmetic expression in Reverse Polish Notation. Valid operators are +, -, *, /. Each operand may be an integer or another expression. Some examples: ["2", "1", "+", "3", "*"] -&g

【leetcode边做边学】二分查找应用

更多请关注我的HEXO博客:http://jasonding1354.github.io/ 简书主页:http://www.jianshu.com/users/2bd9b48f6ea8/latest_articles 二分查找 二分查找算法是一种在有序数组中查找某一特定元素的搜索算法.搜素过程从数组的中间元素开始,如果中间元素正好是要查找的元素,则搜索过程结束:如果某一特定元素大于或者小于中间元素,则在数组大于或小于中间元素的那一半中查找,而且跟开始一样从中间元素开始比较.如果在某一步骤数组 为

【LeetCode刷题Java版】Maximum Product Subarray

Find the contiguous subarray within an array (containing at least one number) which has the largest product. For example, given the array [2,3,-2,4], the contiguous subarray [2,3] has the largest product = 6. package com.liuhao.acm.leetcode; /** * @a

【LeetCode刷题Java版】Reverse Words in a String

Given an input string, reverse the string word by word. For example, Given s = "the sky is blue", return "blue is sky the". click to show clarification. Clarification: What constitutes a word? A sequence of non-space characters constit

【Leetcode 广搜、动态规划】01 矩阵(542)

题目 给定一个由 0 和 1 组成的矩阵,找出每个元素到最近的 0 的距离. 两个相邻元素间的距离为 1 . 示例 1: 输入: 0 0 0 0 1 0 0 0 0 输出: 0 0 0 0 1 0 0 0 0 示例 2: 输入: 0 0 0 0 1 0 1 1 1 输出: 0 0 0 0 1 0 1 2 1 注意: 给定矩阵的元素个数不超过 10000. 给定矩阵中至少有一个元素是 0. 矩阵中的元素只在四个方向上相邻: 上.下.左.右. 解答 也是一道搜索题.要找出每个非零数字和最近0的距离,

【LeetCode 36_哈希表】Valid Sudoku

1 //occupyed_1检查行是否占用 2 //occupyed_2检查列是否占用 3 //occupyed_3检查块是否占用 4 bool isValidSudoku(vector<vector<char>>& board) 5 { 6 int occupyed_1[9][9], occupyed_2[9][9], occupyed_3[9][9]; 7 for (int i = 0; i < 9; ++i) { 8 for (int j = 0; j <