1.求单链表结点的阶乘和
题目:本题要求实现一个函数,求单链表L
结点的阶乘和。这里默认所有结点的值非负,且题目保证结果在int
范围内。
函数接口定义:
int FactorialSum( List L);
其中单链表List
的定义如下:
typedef struct Node *PtrToNode; struct Node { int Data; /* 存储结点数据 */ PtrToNode Next; /* 指向下一个结点的指针 */ }; typedef PtrToNode List; /* 定义单链表类型 */
输入样例:
3
5 3 6
输出样例:846
实现思路:
遍历链表,每找到一个结点的值,使用循环,将其阶乘。最后把所有的结点的阶乘加起来。
int FactorialSum(List L) { int sum = 0; List tail = L; while(tail) { int temp = 1; for(int i = 1;i<=tail->Data;i++) { temp*=i; } sum+=temp; tail = tail->Next; } return sum; }
2.求自定类型元素的最大值
题目:本题要求实现一个函数,求N
个集合元素S[]
中的最大值,其中集合元素的类型为自定义的ElementType
。
函数接口定义:
ElementType Max( ElementType S[], int N );
其中给定集合元素存放在数组S[]
中,正整数N
是数组元素个数。该函数须返回N
个S[]
元素中的最大值,其值也必须是ElementType
类型。
输入样例:
3
12.3 34 -5
输出样例:34.00
解题思路:求数组中的最大值很简单,就是遍历一遍,然后找出最大值就可。但是主要的是有负数,或者说是数组中的元素全都是负数,当全都是负数的时候,max的初始化的值就需要改变一下。
ElementType Max(ElementType S[], int N) { float max = 0.0; for (int j = 0; j < N; j++) { if (S[j] > max) { max = S[j]; } if (S[0] < 0)//如果第一个是小于0,那么先将max变成小于0的数 { max = S[0]; } } return max; }
3.二叉树的镜像
题目:请完成一个函数,输入一个二叉树,该函数输出它的镜像。
例如输入:
4
/ \
2 7
/ \ / \
1 3 6 9
镜像输出:
4
/ \
7 2
/ \ / \
9 6 3 1
示例 1:
输入:root = [4,2,7,1,3,6,9]
输出:[4,7,2,9,6,3,1]
解题思路:通过递归和交换来实现。先将根的左右孩子交换,注意不是交换值!!!然后再将左右孩子通过递归,进行后续的交换。
struct TreeNode* mirrorTree(struct TreeNode* root){ if(root==NULL) { return; } if(root->left==NULL && root->right == NULL) { return root; } struct TreeNode* temp = root->left; root->left = root->right; root->right = temp; mirrorTree(root->left); mirrorTree(root->right); return root; }
4.树的子结构
题目:
输入两棵二叉树A和B,判断B是不是A的子结构。(约定空树不是任意一个树的子结构)。B是A的子结构, 即 A中有出现和B相同的结构和节点值
例如:
给定的树 A:
3
/ \
4 5
/ \
1 2
给定的树 B:
4
/
1
返回 true,因为 B 与 A 的一个子树拥有相同的结构和节点值。
示例 1:
输入:A = [1,2,3], B = [3,1]
输出:false
示例 2:
输入:A = [3,4,5,1,2], B = [4,1]
输出:true
解题思路:我们需要分两步走。第一步:找出根,也就是找出A和B根的值相同的子树。第二步:找出根植相同的子树后,开始判断它们的孩子结点或者是子树,是否相同。
第一步解释:首先需要判断树的根结点的值是否相同,如果不相同,则递归,判断A树的下一个左结点或右结点,是否跟B数的根结点相同。先判断左结点,一直向左走,直到找到或空结点,找到不需要返回值,而是之间进入第二步。,没找到返回false。遍历完左,再遍历右。
第二步解释:当找到根后,通过递归来判断其左右孩子是否相同。若不相同,返回false,相同,则通过递归往下判断。需要注意的是,当B的孩子为空的是时候,要返回ture,A的孩子为空时,需要返回false。
bool SameChild(struct TreeNode* A,struct TreeNode* B) { if(B==NULL) { return true; } if(A==NULL) { return false; } if(A->val!=B->val) { return false; } return (SameChild(A->left,B->left) && SameChild(A->right,B->right)); } bool isSubStructure(struct TreeNode* A, struct TreeNode* B){ bool result = false; if(B==NULL || A==NULL) { return false; } if(A->val==B->val) { result = SameChild(A,B); } if(!result) { result = isSubStructure(A->left,B); } if(!result) { result = isSubStructure(A->right,B); } return result; }
5.合并两个排序的链表
题目:输入两个递增排序的链表,合并这两个链表并使新链表中的节点仍然是递增排序的
示例1:
输入:1->2->4, 1->3->4
输出:1->1->2->3->4->4
解题思路:这道题需要注意的点是空链和合并后依然是递增排序。
因此,我们需要判断该链表是否为空,如果为空,则返回另外一条链表。
可以通过递归的方式来合并两个链表,就是先判断两条链表的第一个结点的值,将小的值的链表链接到新的链表头,然后指向这个新链表的指针指向被链接的链表和另外一条没有被链接的表,即递归的参数。
struct ListNode* mergeTwoLists(struct ListNode* l1, struct ListNode* l2){ if(l1==NULL) { return l2; } else if(l2==NULL) { return l1; } struct ListNode* phead = NULL; if(l1->val < l2->val) { phead = l1; phead->next = mergeTwoLists(l1->next,l2); } else{ phead = l2; phead ->next = mergeTwoLists(l1,l2->next); } return phead; }