当前位置:网站首页>The 17th day of the special assault version of the sword offer
The 17th day of the special assault version of the sword offer
2022-08-02 09:21:00 【hys__handsome】
容易想到 O ( N 2 ) O(N^2) O(N2)brute force traversal algorithm,本质上跟forDouble-loop brute force traversal is similar,That is, the skills required to implement the code are more and more novel.
class Solution {
public:
//保证rootEach node in each of the following paths is picked,There will be no unselected nodes in the middle of the path
int dfs(TreeNode *root, int targetSum) {
if(!root) return 0;
int cnt = 0;
if(root->val == targetSum) cnt++;
cnt += dfs(root->left, targetSum - root->val);
cnt += dfs(root->right, targetSum - root->val);
return cnt;
}
int pathSum(TreeNode* root, int targetSum) {
if(!root) return 0;
//选取root点
int ans = dfs(root,targetSum);
//不选root点
ans += pathSum(root->left, targetSum);
ans += pathSum(root->right, targetSum);
return ans;
}
};
仔细思考会发现,There is a lot of double counting here,You can use prefix sums to optimize into O ( N ) O(N) O(N) 时间复杂度,where the prefix and value are placedmap的键上,The value is the number,This eliminates the need to re-traverse the previous prefix sum,Strictly speaking, because it is usedmapThis results in an algorithmic complexity of O ( N ∗ l o g N ) O(N*logN) O(N∗logN).
class Solution {
private:
unordered_map<long long, int> prefix;
// int ans = 0;
public:
int dfs(TreeNode *root, long long sum, int targetSum) {
if(!root) return 0;
sum += root->val;
int ans = 0;
if(prefix.count(sum-targetSum)) {
//sum - x = targetSum,其中xIt is a prefix sum in front of it
ans += prefix[sum-targetSum];
}
prefix[sum]++;
ans += dfs(root->left, sum, targetSum);
ans += dfs(root->right, sum, targetSum);
prefix[sum]--; //回溯,Otherwise, the sum of the nodes of other branches will be used
return ans;
}
int pathSum(TreeNode* root, int targetSum) {
prefix[0] = 1; //什么都没选,when arootThe sum of the starting path nodes is equal to targetSum时会用到
return dfs(root, 0, targetSum);
}
};
Use post-order traversal+DP思想
- Post-order traversal is to first find the maximum value of the left and right subpaths
- DPThe idea is that the current stack frame will calculate the current node+Left subpath+Right subpath(This cannot be backtracked to the parent node,Because the path is not linear),No matter what you want to backtrack to the parent node to the current node、当前+Left subpath、当前+Right subpath,The final result is the global maximum path sum.
class Solution {
private:
int res = INT_MIN;
public:
int maxPathSum(TreeNode* root) {
maxGain(root);
return res;
}
int maxGain(TreeNode *root) {
if(root == nullptr) return 0;
int left = maxGain(root->left);
int right = maxGain(root->right);
res = max(res, root->val); //Consider both the left and right paths to be negative
res = max(res, root->val + left);
res = max(res, root->val + right);
res = max(res, root->val + left + right);
//Backtracking can only return the current node value 或 当前+左 或 当前+右
return max(max(root->val,root->val+left), root->val+right);
}
};
代码简化版,It is better not to select when left and right are negative values,就为0
class Solution {
private:
int res = INT_MIN;
public:
int maxPathSum(TreeNode* root) {
maxGain(root);
return res;
}
int maxGain(TreeNode *root) {
if(root == nullptr) return 0;
//It is better not to select when left and right are negative values,就为0
int left = max(0,maxGain(root->left));
int right = max(0,maxGain(root->right));
res = max(res, root->val + left + right);
//Backtracking can only return the current node value 或 当前+左 或 当前+右
return max(left,right) + root->val;
}
};
最容易想到的方法,Save the in-order traversal sequence first,Then specify the right node of each node in sequence order,This is equivalent to creating a linked list
class Solution {
public:
void inorder(vector<TreeNode*> &ls, TreeNode *root) {
if(!root) return;
inorder(ls,root->left);
ls.emplace_back(root);
inorder(ls,root->right);
}
TreeNode* increasingBST(TreeNode* root) {
vector<TreeNode*> ls;
inorder(ls,root);
auto head = new TreeNode(-1);
auto tmp = head;
for(auto cur: ls) {
cur->left = cur->right = nullptr;
tmp->right = cur;
tmp = cur;
}
return head->right;
}
};
Come up with a harder way,Change the direction of the node pointer while traversing.Grab the inorder traversal algorithm->Traversal order invariant features.Then follow the traversal order with a move pointer.(有个坑,Move pointers cannot be placed in function parameters,A global variable is required,Because of the recursive backtracking process,Moving the pointer is still the same as it was and didn't change)
class Solution {
private:
TreeNode *cur = nullptr;
public:
void inorder(TreeNode *root) {
if(!root) return;
inorder(root->left);
root->left = nullptr;
cur->right = root;
cur = cur->right;
inorder(root->right);
}
TreeNode* increasingBST(TreeNode* root) {
auto head = new TreeNode(-1);
cur = head;
inorder(root);
return head->right;
}
};
边栏推荐
- What is the function of the import command of the page directive in JSP?
- 动态规划每日一练(3)
- 每天花2小时恶补腾讯T8纯手打688页SSM框架和Redis,成功上岸美团
- 堪称神级的阿里巴巴“高并发”教程《基础+实战+源码+面试+架构》
- PyCharm usage tutorial (detailed version - graphic and text combination)
- 2022牛客暑期多校训练营4(ADHKLMN)
- 理解JS的三座大山
- 谈谈对Volatile的理解
- 百战RHCE(第四十六战:运维工程师必会技-Ansible学习1-基础知识讲解)
- ORBSLAM代码阅读
猜你喜欢
The god-level Alibaba "high concurrency" tutorial "basic + actual combat + source code + interview + architecture"
LeetCode第三题(Longest Substring Without Repeating Characters)三部曲之一:解题思路
Jetpack Compose 中的状态管理
你有了解过这些架构设计,架构知识体系吗?(架构书籍推荐)
中国发布丨滴滴因违反网络安全法等被罚80.26亿元!调查细节公布
曲折的tensorflow安装过程(Tensorflow 安装问题的解决)
PyCharm usage tutorial (detailed version - graphic and text combination)
自定义View实现波浪荡漾效果
AutoJs学习-存款计算器
HCIP笔记第十三天
随机推荐
Jenkins--部署--3.1--代码提交自动触发jenkins--方式1
Spend 2 hours a day to make up for Tencent T8, play 688 pages of SSM framework and Redis, and successfully land on Meituan
【技术分享】OSPFv3基本原理
LeetCode第三题(Longest Substring Without Repeating Characters)三部曲之一:解题思路
Talk about the understanding of Volatile
PyCharm usage tutorial (detailed version - graphic and text combination)
LeetCode第三题(Longest Substring Without Repeating Characters)三部曲之一:解题思路
RestTemlate源码分析及工具类设计
新起点丨MeterSphere开源持续测试平台v2.0发布
ABAP 和json转换的方法
The packet capture tool Charles modifies the Response step
Daily practice of dynamic programming (2)
node封装一个图片拼接插件
小程序云开发(十):渐变与动画
百数应用中心——选择一款适合企业的标准应用
主流监控系统工具选型及落地场景参考
[Concurrent programming] - Thread pool uses DiscardOldestPolicy strategy, DiscardPolicy strategy
Bigder:41/100生产bug有哪些分类
tf中tensor的大小输出
Openwrt_树莓派B+_Wifi中继