当前位置: 首页 > 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.dtcms.com/a/318300.html

相关文章:

  • google官方性能文档:Android 动态性能框架优化散热和 CPU 性能-Thermal API部分
  • 短剧小程序系统开发:技术驱动下的内容创新之路
  • 2025年08月 GitHub 热门项目推荐
  • 1深度学习Pytorch-pytorch、tensor的创建、属性、设备和类型转换、数据转换、常见操作(获取元素、元素运算、形状改变、相乘、广播)
  • 【31】C++实战篇——C++ 从数组里找出相邻两个波谷之间的主波峰的y值和其对应下标i,考虑到波形的上升和下降情况
  • 【AI总结】python连接MySQL(5)- 高级数据库配置与连接器设计
  • go语言变量2
  • 开疆智能ModbusTCP转Profinet网关连接安川YRC1000机器人配置案例
  • 嵌入式处理器指令系统:精简指令集RISC与复杂指令集CISC的简介,及区别
  • Cervantes:面向渗透测试人员和红队的开源协作平台
  • 勇芳字体查看器 v1.0 免费版
  • 当前就业形势下,软件测试工程师职业发展与自我提升的必要性
  • Kubesphere搜索镜像问题
  • 深度解析|资源位管理工具如何重构媒体商业化效率?
  • 飞书对接E签宝完整方案
  • AI浪潮下,FPGA如何实现自我重塑与行业变革
  • 动态代理常用的两种方式?
  • 开发教育全链路管理系统 + 微信小程序,为各类教育主体注入数字化动力!
  • LeetCode 面试经典 150_数组/字符串_O(1)时间插入、删除和获取随机元素(12_380_C++_中等)(哈希表)
  • Conda虚拟环境安装包
  • 信号处理:信号产生
  • 2025年WiFi技术白皮书:全球物联网无线通信的关键创新
  • Codeforces Round 987 (Div. 2)
  • [特殊字符]海尔考察游学 | 解码人才培养秘籍
  • 长时间面对电脑屏幕需要使用防晒霜吗?
  • js中的 slice、splice、split、substring、substr
  • 面试题:使用class类来写工个五子棋
  • spring-dubbo
  • Post-train 入门(1):SFT / DPO / Online RL 概念理解和分类
  • C++与C语言实现Stack的对比分析