版权声明: https://blog.csdn.net/qq_26460841/article/details/82148816
前言:最近在leetcode上刷题,发现很多涉及数的操作的问题,无一例外都需要使用到函数的递归调用。然后自己也试着写了一些简单的函数来理解栈的使用。
关于递归的理解:
函数递归调用,使用到栈。而栈退出的条件是: 在调用的过程中,无压栈再次进行,就开始退栈。
需要注意的是:
- 在递归函数中自定义的局部变量,在每次调用的过程中都会创建一个新的副本,所以每次调用都是该变量所设置的初始值
- 一个递归函数中可以有多个return ,但是递归函数说到底也是函数,所以最终也只有一个return返回值
- return 函数调用过程中,满足边界条件的返回结果;但是return不是决定函数是否退栈的标志, 决定退栈标志的始终都是是否还有压栈情况。
- 充分考虑是否含有不压栈的边界情况。
注:
同时在刷题的过程中,遇到比较多的是一个函数中调用另一个递归函数。我这里称之为函数的改造。如下面的代码:
给定一个二叉树,检查它是否是镜像对称的。例如,二叉树 [1,2,2,3,4,4,3] 是对称的。
1
/ \
2 2
/ \ / \
3 4 4 3
给出的接口函数是下面的第二个isSymmetric(TreeNode* root);也就是函数中只有一个参数,所以如果死板的使用这一个接口函数来编程必然会加大程序的复杂程度,我们也不得不使用队列来实现。
而,使用另一个递归函数中,使用两个指针分别判断树的左右子树的结点中的元素是否镜像对称来实现是比较简洁的。
bool isSymmetrics(TreeNode* Left, TreeNode* Right){
if(!Left&&!Right)
return true;
if(!Left||!Right)
return false;
/*
使用两个指针判断,画图不难发现,对称的二叉树必然是左子树的左结点和右子树的右结点相等
所以下面的比较也是Left->left vs right->right left->right vs right->left
*/
if(Left->val==Right->val){
return isSymmetrics(Left->left, Right->right) and isSymmetrics(Left->right, Right->left);
}
return false;
}
bool isSymmetric(TreeNode* root) {
if(root==NULL) return true;
/**
这里,调用另外一个递归函数的思想要掌握
*/
return isSymmetrics(root->left, root->right);
}
附:链表的删除试题:
指针变量 p 指向单链表中结点 A ,若删除单链表中结点 A ,则需要修改指针的操作序列为( )。
A. q=p->next;p->data=q->data;p->next=q->next;free(q);
B. q=p->next;q->data=p->data;p->next=q->next;free(q);
C. q=p->next;p->next=q->next;free(q);
D. q=p->next;p->data=q->data;free(q);
答案:A
想必都知道答案,但是这种思想赋值思想我觉得是比较优秀的,所以这里拎出来了。