每日训练(一)

简介: 题目来源于PTA基础编程和力扣剑指offer

1.求单链表结点的阶乘和

题目:本题要求实现一个函数,求单链表L结点的阶乘和。这里默认所有结点的值非负,且题目保证结果在int范围内。

函数接口定义:

int FactorialSum( List L);

image.gif

其中单链表List的定义如下:

typedef struct Node *PtrToNode;
struct Node {
    int Data; /* 存储结点数据 */
    PtrToNode Next; /* 指向下一个结点的指针 */
};
typedef PtrToNode List; /* 定义单链表类型 */

image.gif

输入样例

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;
}

image.gif

2.求自定类型元素的最大值

题目:本题要求实现一个函数,求N个集合元素S[]中的最大值,其中集合元素的类型为自定义的ElementType

函数接口定义:

ElementType Max( ElementType S[], int N );

其中给定集合元素存放在数组S[]中,正整数N是数组元素个数。该函数须返回NS[]元素中的最大值,其值也必须是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;
}

image.gif

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;
}

image.gif

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;
}

image.gif

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;
}

image.gif

相关文章
|
1月前
|
机器学习/深度学习 弹性计算 TensorFlow
在阿里云上打造强大的模型训练服务
随着人工智能技术的迅猛发展,模型训练服务变得愈发关键。阿里云提供了一系列强大的产品,使得在云端轻松搭建、优化和管理模型训练变得更加便捷。本文将详细介绍如何使用阿里云的相关产品构建高效的模型训练服务。
236 0
|
1月前
|
机器学习/深度学习 人工智能 边缘计算
为何人们喜欢推理胜于训练大模型?
在AI和机器学习领域,越来越多的人转向重视推理而非大规模模型训练。推理的即时性和高效性使其在需要快速响应的场景中占优,如自然语言处理和图像识别。推理过程的可视化能帮助用户理解模型决策,便于调试和提升性能。此外,推理在边缘计算和移动设备上的应用降低了延迟和带宽成本,同时保护了用户隐私。相比于训练大模型的高资源消耗,推理更为节能且成本效益高,尤其在数据挖掘和新知识探索方面展现出创新潜力。推理在实际应用中与训练模型相结合,提供了性能与成本的有效平衡。随着技术进步,推理将在推动人工智能领域发展中发挥更大作用。
|
10月前
|
XML 数据挖掘 数据格式
|
11月前
|
网络安全 开发工具 网络架构
YOLOV7详细解读(四)训练自己的数据集
YOLOV7详细解读(四)训练自己的数据集
648 0
|
机器学习/深度学习 数据处理
训练多个epoch来提高训练模型的准确率
训练多个epoch来提高训练模型的准确率
148 0
每日训练(五)
每日训练五,题目来源:牛客、力扣
每日训练(五)
|
算法 搜索推荐
每日训练(二)
每日训练(二),题目来源:力扣,PTA。
每日训练(二)