当前位置: 首页 > news >正文

院校机试刷题第二十一天|回顾代码随想录第十六天、

一、代码随想录第十六天

1.513找树左下角的值

递归和迭代(层序)都可解决

层序:找到最后一层的最后一个元素

递归:想要求当前节点为根节点的二叉树最左下角的节点的值,需要求左子树/右子树最左下角的节点,并且比较哪个更深,选择记录更深的那个。这种欲求自己,先求左右子树的解法都可以叫做递归法,需要确定自己本层的处理逻辑,以及左右子树分别的递归逻辑。

层序代码:

/*** 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:int findBottomLeftValue(TreeNode* root) {int result = 0;queue<TreeNode*> que;if(root != nullptr) {que.push(root);}while(!que.empty()) {int size = que.size();for(int i = 0; i < size; i++) {TreeNode* temp = que.front();que.pop();if(temp->left) que.push(temp->left);if(temp->right) que.push(temp->right);if(i == 0) {result = temp->val;}}}return result;}
};

2.112路径总和

这道题关键的一个点在于回溯,按照“中左右”的顺序遍历时,如果在遍历左或者右的时候出现满足的情况,那么就按照下图红线所示,一路返回true,而不进行任何操作,不用进行回溯;如果在遍历时没有出现满足的情况,那么就按照下图蓝色所示的进行回溯的操作,回溯操作表现为,在返回上一层的时候,目标数发生改变,去除掉下一层对目标数的操作,这种操作可以直接在递归函数的参数中进行相关的操作。

/*** 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:bool traverse(TreeNode* root, int targetSum) {if(root->left == nullptr && root->right == nullptr) {if(targetSum == 0) {return true;} else {return false;}}// 左if(root->left) {bool result1 = traverse(root->left, targetSum - (root->left->val));if(result1) return true;}// 右if(root->right) {bool result2 = traverse(root->right, targetSum - (root->right->val));if(result2) return true;}return false;}bool hasPathSum(TreeNode* root, int targetSum) {if(root == nullptr) return false;return traverse(root, targetSum - root->val);}
};

3.113路径总和II 

相比上一题,这个要求的是所有的路径,而不仅仅是true/false,那么就需要一个vector数组来记录路径,一个vector数组来记录所有路径。回溯修改为先将遍历到的节点加入到路径中,然后递归,然后回溯弹出节点。

/*** 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<vector<int>> result;vector<int> path;void traverse(TreeNode* cur, int target) {//中if(cur->left == nullptr && cur->right == nullptr && target == 0) {result.push_back(path);return;}//左if(cur->left) {path.push_back(cur->left->val);traverse(cur->left, target - cur->left->val);path.pop_back();//回溯!!!这样才可以返回找到别的路径}//右if(cur->right) {path.push_back(cur->right->val);traverse(cur->right, target - cur->right->val);path.pop_back();}return;}vector<vector<int>> pathSum(TreeNode* root, int targetSum) {// result.clear();// path.clear();if(root == nullptr) return result;path.push_back(root->val);traverse(root, targetSum - root->val);return result;}
};

二、303区域和检索

1.解题思路

这里用到了前缀和的思想,求left和right之间的元素的和就是求从头到right的元素和  减去  从头到left的元素和,所以定义一个数组求一下所有的从头到任意一个元素的前缀和即可。注意,这个前缀和数组应该预先定义一项s[0] = 0,这样从left到right就可以用公式s[right + 1] - s[left]这样进行求解了。

2.代码

class NumArray {
public:vector<int> s;NumArray(vector<int>& nums) {s.resize(nums.size() + 1);s[0] = 0;for(int i = 0; i < nums.size(); i++) {s[i + 1] = s[i] + nums[i];}}int sumRange(int left, int right) {return s[right + 1] - s[left];}
};/*** Your NumArray object will be instantiated and called as such:* NumArray* obj = new NumArray(nums);* int param_1 = obj->sumRange(left,right);*/

二、560和为k的子数组

1.暴力法

暴力法:直接两层for枚举出来所有的子数组,然后一一判断是否和为k,和为k就统计值count++。

但是会超时

class Solution {
public:int subarraySum(vector<int>& nums, int k) {int count = 0;for(int i = 0; i < nums.size(); i++) {int sum = 0;for(int j = i; j < nums.size(); j++) {sum += nums[j];if(sum == k) {count++;}}}return count;}
};

2.前缀和方法

求所有的子序列的和也就是求子序列 从头到j的前缀和 减去 从头到i的前缀和,看有几个满足条件的s[j] - s[i] = k。这个实际上可以转换为依次遍历s中的所有元素,看对于每个元素(也就是可以视为s[j]),在s数组从0-j这部分,到底有几个s[i] = s[j] - k。

所以还需要一个map统计一下每个s的值,以及s数组中有几个这样的值,一边遍历s数组一边进行统计即可,遍历的过程中,该map对应的值++即可。

class Solution {
public:int subarraySum(vector<int>& nums, int k) {int n = nums.size();vector<int> s(n + 1, 0);for(int i = 0; i < nums.size(); i++) {s[i + 1] = s[i] + nums[i];}int ans = 0;unordered_map<int, int> cnt;// 一边遍历前缀和数组,一边统计有多少个前缀和为该数值// s[i] = s[j] - k, k是目标结果,也就是在求有几个s[j] - s[i] = k,这里是先遍历所有的s[j],求出每个s[j]对应的s[i],然后看s[j]的前面有几个s[i],这样进行统计。// 同时在遍历的过程中,也顺便统计s[j]的个数。for(int sj : s) {ans += cnt.contains(sj - k) ? cnt[sj - k] : 0;cnt[sj]++;}return ans;}
};
http://www.lryc.cn/news/612168.html

相关文章:

  • gorm:初识gorm
  • 线性代数中矩阵的基本运算运算
  • 二、Istio流量治理(一)
  • Kali Linux虚拟机安装和中文配置详细教程(2025版)
  • Aop中的相关术语
  • FluentUI的介绍与使用案列
  • K8S的POD数量限制
  • 《Transformer黑魔法Mask与Softmax、Attention的关系:一个-∞符号如何让AI学会“选择性失明“》
  • sqli-labs靶场less40-less45
  • 【python中级】关于Flask服务在同一系统里如何只被运行一次
  • 大型音频语言模型论文总结
  • 基于CentOS-7.6部署k8s-1.24.0,containerd作为CRI,nerdctl作为容器管理CLI
  • 高阶组件实现Button权限
  • 对 .NET线程 异常退出引发程序崩溃的反思
  • PowerShell部署Windows爬虫自动化方案
  • 玩转 InfluxDB 3:用 HTTP API 快速创建高效数据表
  • 【Linux】调试器gdb/cgdb的使用
  • 信号处理:信号产生
  • 张艺兴续约担任传音手机全球品牌代言人 携手共启创新征程
  • 企业级DDoS防护实战案例
  • 数字取证和网络安全:了解两者的交叉点和重要性
  • 什么是 Kafka 中的消息?它由哪些部分组成
  • 《设计模式之禅》笔记摘录 - 13.迭代器模式
  • JP3-4-MyClub后台前端(二)
  • leetcode 3479. 水果成篮 III 中等
  • 多端同步新解法:Joplin+cpolar联合通过开源设计实现跨平台无缝协作?
  • 【学习笔记之redis】删除缓存
  • vue3 el-select el-option 使用
  • 学习嵌入式之硬件——ARM体系
  • CubeFS存储(一)