当前位置:网站首页>力扣递归训练
力扣递归训练
2022-08-03 09:27:00 【梦执..】
1374 生成每种字符都是奇数个的字符串
解题思路
分析好题的关键技巧即可,
用’a’,'b’最简单。n为奇数就返回n个’a’即可
n如果为偶数,就返回n-1个’a’再加上一个’b’即可。
代码
class Solution {
public:
string generateTheString(int n) {
string s="";
if(n % 2== 0){
for(int i = 0;i<n-1;i++)
s += 'a';
s += 'b';
}else{
for(int i = 0;i<n;i++)
s += 'a';
}
return s;
}
};
622 设计循环队列
解题思路
队列一定要有指向初始位置,以及结束位置的front和rear。
题中还要再记录一下队列的长度,用于进行front以及rear循环取余的判断。
注意:
1.队列长度为k但实际上最大的索引为k-1,另外由于需要我们空出一个位置,来区分起始位置和其余情况的是否队列为满的问题。所以最终申请的长度为k+1。为了对front以及rear取余我们对k2设置为k+1.
2.我们此处采用初始front= 0,rear = -1;的方式。如果为队列为空则rear+1 == front为true.
3.每次我们空出的那个格子都是front前面的一个格子。
4.其余就每次插入前判断是否为满,删除前判断是否为空即可。
代码
class MyCircularQueue {
public:
vector<int> ans;
int front;
int rear;
int k2;
//构造器,设置队列长度为 k 。
MyCircularQueue(int k) {
front = 0;
rear = -1;
k2 = k+1;
ans = vector<int>(k+1);//提前开辟这么大的空间
}
//向循环队列插入一个元素。如果成功插入则返回真。
bool enQueue(int value) {
if(isFull()) return false;
else{
rear++;rear %= k2; //记得每步加加后都要取余.
ans[rear] = value;
return true;
}
}
//从循环队列中删除一个元素。如果成功删除则返回真。
bool deQueue() {
if(isEmpty())return false;
else{
front += 1;
front %= k2;
return true;
}
}
//从队首获取元素。如果队列为空,返回 -1 。
int Front() {
if(isEmpty())return -1;
else
return ans[front];
}
//获取队尾元素。如果队列为空,返回 -1 。
int Rear() {
if(isEmpty()) return -1;
else
return ans[rear];
}
//检查循环队列是否为空。
bool isEmpty() {
return rear + 1 == front;
}
//检查循环队列是否已满。
bool isFull() {
//开始时刻和这种情况相同 (rear+1) % k2 == front,所以空一位.
return (rear + 2) % k2 == front;
}
};
24 两两交换链表中的结点
解题思路
首先我们要知道,只要剩下的未交换过的结点数为1或0则可以停止交换了。
代码
/** * Definition for singly-linked list. * struct ListNode { * int val; * ListNode *next; * ListNode() : val(0), next(nullptr) {} * ListNode(int x) : val(x), next(nullptr) {} * ListNode(int x, ListNode *next) : val(x), next(next) {} * }; */
class Solution {
ListNode* node;
public:
ListNode* swapPairs(ListNode* head) {
if(head == nullptr || head->next == nullptr){
return head;
}
ListNode* newhead = head->next;//由于交换过后head->next打头,则直接让头指针指向该结点。
head->next = swapPairs(newhead->next);//要知道head指向的结点将会和后面的结点连接,则重新更新head->next.
newhead->next = head;//将当前头结点和第二个结点建立联系。
return newhead;//而下一个将会被返回的结点仍是打头的结点。
}
};
572 另一棵树的子树
解题思路
理解题意:只要依次走过root树的每个结点,将其与以subRoot为根的树进行深搜比较即可。
通过check依次遍历每个结点,其含义为:当前结点成功或者当前节点的左子树成功,或者当前结点的右子树成功都行。
然后进入dfs中依次匹配,只有当两个结点都为空了,说明能递归到这儿还没被return false 则return 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 isSubtree(TreeNode* root, TreeNode* subRoot) {
/* 1.从相同的根节点开始,递归 */
return check(root,subRoot);
}
bool check(TreeNode* root,TreeNode* subRoot){
if(!root){
return false;
}
return dfs(root,subRoot) || check(root->left,subRoot)||check(root->right,subRoot);
}
//匹配两个树是否完全相同
bool dfs(TreeNode* root, TreeNode* subRoot){
if(!root && !subRoot)return true;//都为空返回true
if(!root || !subRoot||root->val != subRoot->val){
//至多有一个为空,返回false;
return false;
}
/* 只有这一对结点的值相等不能说明这个结点的后代结点也都对应相等。 只有对应结点判断后都不能走false,直到最后叶子结点之后,都为空了,才可以判断说这两个树至此都没有不同,则 返回true. */
// if(root && subRoot){
// return root->val == subRoot->val;
// }
return dfs(root->left,subRoot->left) && dfs(root->right,subRoot->right);
}
};
112 路径总和
解题思路
代码
/** * 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 hasPathSum(TreeNode* root, int targetSum) {
return dfs(root,0,targetSum);
}
bool dfs(TreeNode* root,int sum,int targetSum){
if(root==nullptr) return false;//首先要 判断是否为空,要不然sum已经被赋值为0了,可能遇到targetSum的第一个值为0,而root为空的情况。
if(root->left == nullptr && root->right==nullptr) return (sum+root->val) == targetSum;
//只有左右孩子都为空才可以进行判断。说明才到达了叶子结点。
// int leftSum = 0,rightSum = 0;不能再声明了,会每次都被赋值 成0的,还是得放到函数参数中.
return
dfs(root->left,sum+root->val,targetSum) ||
dfs(root->right,sum+root->val,targetSum);
}
};
解题思路
首先就是要注意进位的问题,每次相加都是两个链表的对应结点值和进位count相加,
采取新建链表的形式,递归建立每个结点,以及各节点和之前结点的next联系。
只有当两个结点为空且进位为0,时才会返回nullptr。
代码
/** * Definition for singly-linked list. * struct ListNode { * int val; * ListNode *next; * ListNode() : val(0), next(nullptr) {} * ListNode(int x) : val(x), next(nullptr) {} * ListNode(int x, ListNode *next) : val(x), next(next) {} * }; */
class Solution {
public:
ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {
return dfs(l1,l2,0);
}
ListNode* dfs(ListNode*l,ListNode* r,int count){
if(!l&&!r&&!count)return nullptr;
int sum = (l?l->val:0) + (r?r->val:0) + count;//必须要加括号,否则结果不对,加法运算符的优先级大于三目运算符
count = sum /10;
ListNode * node = new ListNode(sum%10);
node->next = dfs(l?l->next:nullptr,r?r->next:nullptr,count);
return node;
}
};
95 不同的二叉搜索树II
解题思路
代码
/** * 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<TreeNode*> generateTrees(int n) {
if(!n){
return {
};
}
return generateTrees(1,n);
}
vector<TreeNode*> generateTrees(int start,int end){
if(start > end){
//等于是返回这一个结点的情况。
return {
nullptr};//空也一定要 返回,才会在左右孩子集合中 出现。
}
vector<TreeNode*> allTrees;
for(int i = start;i<=end;i++){
//从start到end都可以当一次根节点
vector<TreeNode*> leftTrees = generateTrees(start,i-1);//注意左右孩子队列中的任何一个都可以当其左右孩子。
vector<TreeNode*> rightTrees = generateTrees(i+1,end);
//递归到左右孩子为空,,即上步两个generateTrees()返回两个nullptr。
//下面currTree的左右孩子被设置为nullptr,而currTree为叶子结点,
for(auto& left: leftTrees)
for(auto& right: rightTrees){
TreeNode* currTree = new TreeNode(i);
currTree->left = left;
currTree->right = right;
allTrees.emplace_back(currTree);
}
}
return allTrees;
}
};
边栏推荐
- 多媒体数据处理实验1:算术编码
- Flink Yarn Per Job - 提交应用
- STP普通生成树安全特性— bpduguard特性 + bpdufilter特性 + guard root 特性 III loopguard技术( 详解+配置)
- 分区分表(一)
- cmd(命令行)操作或连接mysql数据库,以及创建数据库与表
- SQL Daily Practice (Nioke New Question Bank) - Day 5: Advanced Query
- STP生成树(端口状态+端口角色+收敛机制 )|||| STP优化技术( uplinkfast技术+Portfast技术+backbonefast技术 )详解
- 【LeetCode】112. Path sum
- Redis实现分布式锁
- 多线程下的单例模式
猜你喜欢
Redis和MySQL如何保持数据一致性
Rabbit and Falcon are all covered, Go lang1.18 introductory and refined tutorial, from Bai Ding to Hongru, the whole platform (Sublime 4) Go lang development environment to build EP00
【无标题】
Oracle 迁移至Mysql
行业 SaaS 微服务稳定性保障实战
xtrabackup
RSTP(端口角色+端口状态+工作机制)|||| 交换机接口分析
浅聊缓存函数
批量将PNG格式转化为JPG格式
LeetCode第三题(Longest Substring Without Repeating Characters)三部曲之二:编码实现
随机推荐
MySQL-DDL数据定义语言-约束
基于百度AI和QT的景物识别系统
MySQL——几种常见的嵌套查询
gpnmb+ gpnmb-AT2 cell空转映射 上皮细胞的空转映射
STP普通生成树安全特性— bpduguard特性 + bpdufilter特性 + guard root 特性 III loopguard技术( 详解+配置)
慢 SQL 分析与优化
多媒体数据处理实验2:PCA
cmd(命令行)操作或连接mysql数据库,以及创建数据库与表
自动化测试浏览器驱动下载版本对应关系
SAP Analytics Cloud 和 SAP Cloud for Customer 两款 SaaS 软件的集成
dflow入门4——recurse&reuse&conditional
Redis集群概念与搭建
批量将PNG格式转化为JPG格式
浅析什么是伪类和伪元素?伪类和伪元素的区别解析
系统io统计
【微信小程序】底部有安全距离,适配iphone X等机型的解决方案
QT中线程调用GUI主线程控件的问题
Industry SaaS Microservice Stability Guarantee Actual Combat
【LeetCode】101.对称二叉树
Batch PNG format can be converted to JPG format