两道链表算法题:
1.删除链表的节点:
链接: 题目链接
这道题的做法就是单链表的删除操作思想,看完题目条件后,首先,当链表只存有一个数据时,直接返回next,变为空链表;其次就是找到链表所删数据的前一个节点,进行删除操作就行了,代码注释如下:
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
struct ListNode* deleteNode(struct ListNode* head, int val){
if(head->val == val)//当只存有一个数据时
{
return head->next;//返回next空链表
}
struct ListNode *p=head;
while((p->next!=NULL) && (p->next->val!=val))//循环找到输出节点的前一个
{
p=p->next;
}
if(p->next != NULL)
{
p->next = p->next->next;//进行删除操作,力扣不需要Free哦,也可以重新定义一个q指针,q = p->next,p->next=q->next也可以,不过比较麻烦~
}
return head;//题目说明返回head即可
}
2.反转链表:
链接: 题目链接
这道题的做法就是将数据"倒放",但是显然单链表不支持访问前驱节点,所以这里咱们需要一个newhead与一个old head,让oldhead->next=new->head实现"头插法",再令temp=old->next,实现头指针的移动,代码如下:
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
struct ListNode* reverseList(struct ListNode* head){
typedef struct ListNode *Node;
Node new_head, old_head, temp;
old_head=head; //初始化当前旧表头为head
new_head=NULL; //初始化逆转后新表头为空
while(old_head){ //当旧表头不为空时
temp=old_head->next;
old_head->next=new_head;
new_head=old_head;
old_head=temp;
}
head=new_head; //更新head
return head;
}
核心代码图解:
2.思考题:
1.神经网络中激活函数的作用:
当我们处理一个线性可分数据时,用单层感知机是可以进行数据的分类的,但是如果数据是线性不可分的话:
不带激活函数的单层感知机就有点吃力了,怎么分都有数据"站错"位置,这是激活函数就显得尤为重要了,它的作用可大着呢,加入非线性因素,直接:
这里的曲线即为非线性因素,通过神经网络输入层带有权重的输入,再经过隐藏层与输出层的激活函数,就将数据分开了.如果不用激活函数,神经网络的每一层的输入都是上一层的线性输出,即 f(x) = x,因此,无论该神经网络有多少层,最终的输出都是输入的线性组合,隐藏层的效果就无了.
2.机器学习中验证集和测试集的区别:
首先给出下面一图:
训练集: 用于训练模型(拟合参数),即模型拟合的数据样本集合,如通过训练拟合一些参数来建立一个分类器.
验证集:是模型训练过程中单独留出的样本集,它可以用于调整模型的超参数和用于对模型的能力进行初步评估。主要目的是为了挑选在验证集上表现最好的模型.
测试集:使用测试数据评估模型的好坏,用于评估该模型泛化能力的数据集.
3.机器学习的基本流程:
首先进行数据的采集,即数据集的获取,然后对数据进行预处理(将有用的数据集提取出来,无用的剔除,或者转换数据类型等),然后确定处理问题的模型,即函数,优化函数以及损失函数等,还有参数的学习(误差率,学习率,偏项,权重等)参数的优化,使其不断逼近我们想要的预期值,然后进行模型的评估,基于评估的好与坏,可能会再次进行模型参数的优化,最后进行数据集的测试,完成一个机器学习任务.