代码随想录训练营第31天|树形dp

56. 合并区间

class Solution {
public:
    vector<vector<int>> merge(vector<vector<int>>& intervals) {
        sort(intervals.begin(),intervals.end(),[](vector<int>& a, vector<int>& b){return a[0]<b[0];});
        vector<vector<int>> result;
        result.push_back(intervals[0]);
        for(int i=1;i<intervals.size();i++){
            if(intervals[i][0]>result.back()[1])
                result.push_back(intervals[i]);
            else{
                result.back()[1]=max(result.back()[1],intervals[i][1]);
            }
        }
        return result;
    }
};

按起点排序,依次处理,重叠区间进行合并。

738. 单调递增的数字 

class Solution {
public:
    int monotoneIncreasingDigits(int n) {
        string str_n=to_string(n);
        int idx=str_n.length();
        for(int i=str_n.length()-1; i>0; i--){
            if(str_n[i]<str_n[i-1]){
                str_n[i-1]--;
                idx=i;
            }
        }
        for(int i=idx; i<str_n.length(); i++){
            str_n[i]='9';
        }
        return stoi(str_n);
    }
};

贪心的思想:高位-1后,后续所有数字都可以置9,包括本来合法的数字。

968. 监控二叉树

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
 * };
 */
class Solution {
public:
    vector<int> minCamera(TreeNode* root){
        vector<int> dp(3,0);
        if(root==nullptr){
            dp[0]=INT_MAX/2;
            dp[2]=INT_MAX/2;
            return dp;
        }
        auto left=minCamera(root->left);
        auto right=minCamera(root->right);
        dp[0]=min({left[0],left[1],left[2]})+min({right[0],right[1],right[2]})+1;
        dp[1]=min(left[0]+min(right[0],right[1]),right[0]+min(left[0],left[1]));
        dp[2]=left[1]+right[1];
        return dp;
    }
    int minCameraCover(TreeNode* root) {
        auto res=minCamera(root);
        return min(res[0],res[1]);
    }
};

状态定义:

  • 状态0:当前节点安装相机的时候,需要的最少相机数
  • 状态1: 当前节点不安装相机,但是能被覆盖到的时候,需要的最少相机数
  • 状态2:当前节点不安装相机,也不能被覆盖到的时候,需要的最少相机数

转移方程:

  • dp[0]:当前节点安装,则子树可以随意发挥,即使子树的根没被覆盖,也可以被当前节点cover,所以取全部状态最小即可。
  • dp[1]:当前节点不安装,还要求覆盖,只有两种可能:左子树根装了或右子树根装了,以此向上覆盖到当前节点。当一个子树装了后,另一个子树可以在状态0、1中取最小,来保证自己全覆盖,因为此时当前节点无法向下覆盖子树。 
  • dp[2]:取左右子树的状态1,即满足子树被覆盖到,但因为都不安装相机,所以不会向上覆盖当前节点。
第二十二算法训练营主要涵盖了Leetcode题目中的三道题目,分别是Leetcode 28 "Find the Index of the First Occurrence in a String",Leetcode 977 "有序数组的平方",和Leetcode 209 "长度最小的子数组"。 首先是Leetcode 28题,题目要求在给定的字符串中找到第一个出现的字符的索引。思路是使用双指针来遍历字符串,一个指向字符串的开头,另一个指向字符串的结尾。通过比较两个指针所指向的字符是否相等来判断是否找到了第一个出现的字符。具体实现的代码如下: ```python def findIndex(self, s: str) -> int: left = 0 right = len(s) - 1 while left <= right: if s[left == s[right]: return left left += 1 right -= 1 return -1 ``` 接下来是Leetcode 977题,题目要求对给定的有序数组中的元素进行平方,并按照非递减的顺序返回结果。这里由于数组已经是有序的,所以可以使用双指针的方法来解决问题。一个指针指向数组的开头,另一个指针指向数组的末尾。通过比较两个指针所指向的元素的绝对值的大小来确定哪个元素的平方应该放在结果数组的末尾。具体实现的代码如下: ```python def sortedSquares(self, nums: List[int]) -> List[int]: left = 0 right = len(nums) - 1 ans = [] while left <= right: if abs(nums[left]) >= abs(nums[right]): ans.append(nums[left ** 2) left += 1 else: ans.append(nums[right ** 2) right -= 1 return ans[::-1] ``` 最后是Leetcode 209题,题目要求在给定的数组中找到长度最小的子数组,
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值