两两交换链表中的节点
问题描述
给定一个链表,两两交换其中相邻的节点,并返回交换后的链表。
你不能只是单纯的改变节点内部的值,而是需要实际的进行节点交换。
输入说明
首先输入链表长度len,然后输入len个整数,以空格分隔。
输出说明
输出格式见范例
输入范例
4
1 2 3 4
输出范例
head–>2–>1–>4–>3–>tail
题解
完整代码
问题不难,完整代码及注释如下:
#include<iostream>
#include<algorithm>
#include<vector>
using namespace std;
struct ListNode
{
int val;
ListNode *next;
ListNode() : val(0), next(NULL) {}
ListNode(int x) : val(x), next(NULL) {}
ListNode(int x, ListNode *next) : val(x), next(next) {}
};
class Solution
{
public:
ListNode* swapPairs(ListNode* head)
{
//填充本函数完成功能
ListNode* p=head,*q,*fade_head;
fade_head = new ListNode;
fade_head ->next =head;
ListNode *mark = fade_head;//direct to swap(p,q) 的前节点
//len
int len =0;
while(p)
{
len++;
p=p->next;
}
if(len >1)
{
//deal
p=head;
int tot=0;
while(p)
{
tot++;
if(tot == 2)//swap(p,q), 保证了q的存在
{
//swap(p,q)
mark->next =p;
q->next = p->next;
p->next = q;
//init
mark = q;
tot=0;
q=p;//前面 p、q节点换位置了
p=q->next;
}
//
q=p;
p=p->next;
}
}
head =fade_head->next;
return head;
}
};
ListNode *createByTail()
{
ListNode *head;
ListNode *p1,*p2;
int n=0,num;
int len;
cin>>len;
head=NULL;
while(n<len && cin>>num)
{
p1=new ListNode(num);
n=n+1;
if(n==1)
head=p1;
else
p2->next=p1;
p2=p1;
}
return head;
}
void displayLink(ListNode *head)
{
ListNode *p;
p=head;
cout<<"head-->";
while(p!= NULL)
{
cout<<p->val<<"-->";
p=p->next;
}
cout<<"tail\n";
}
int main()
{
ListNode* head = createByTail();
head=Solution().swapPairs(head);
displayLink(head);
return 0;
}
关于swap(p,q)的无效性讨论
p 、 q 为相邻节点
swap()
的思想出现在下面函数中,
class Solution
{
public:
ListNode* swapPairs(ListNode* head)
{
//填充本函数完成功能
ListNode* p=head,*q,*fade_head;
fade_head = new ListNode;
fade_head ->next =head;
ListNode *mark = fade_head;//direct to swap(p,q) 的前节点
//len
int len =0;
while(p)
{
len++;
p=p->next;
}
if(len >1)
{
//deal
p=head;
int tot=0;
while(p)
{
tot++;
if(tot == 2)//swap(p,q), 保证了q的存在
{
//swap(p,q)
mark->next =p;
q->next = p->next;
p->next = q;
//init
mark = q;
tot=0;
q=p;//前面 p、q节点换位置了
p=q->next;
}
//
q=p;
p=p->next;
}
}
head =fade_head->next;
return head;
}
};
其中的
q->next = p->next;
p->next = q;
本想着用swap(p,q)直接偷懒,最后更新下p、q前一个结点的指向关系就ok,结果输出和输入一毛一样,原本还在纠结,p、q 交换后到底交换了什么?到底是p、q节点的内容变了,位置不变【p、q指向发生了变化】,还是内容不变,p、q位置变了【p、q节点位置发生了变化】,自嘲自己一下,交换指针我还是自己手写交换节点位置吧,交换后p、q的指向再换一下,这个思路还是熟悉的。
感受
链表题目的特殊操作,考虑的特例 空表、1、2,为什么要考虑2个节点呢?
比如在节点向后尾插,可能当前操作节点和最后一个节点重叠,出bug。
浅谈IT班
利弊如何
1)利
- 学习专业知识
IT培训班提供系统化的专业知识和技能培训,帮助学员全面掌握IT领域的知识,提高技能水平 - 获得实践经验
培训班通常会提供实际项目和实验,让学员在实际操作中学习和应用所学知识,获得真实的实践经验 - 培养解决问题的能力
培训班注重培养学员的解决问题的能力,通过解决实际问题,培养学员的逻辑思维和解决问题的能力 - 学习团队合作
培训班安排学员进行团队项目,让学员学会有效地与他人合作,增强团队协作能力 - 接触最新技术
IT行业发展迅速,培训班可以让学员接触到最新的技术和发展动态,保持行业敏感度 - 职业发展机会
完成培训班后获得证书,为求职增加优势,许多公司更愿意雇佣有相关培训经历的候选人 - 拓展人际网络
在培训班中结识志同道合的同学和业界专业导师,建立人际网络,有助于个人职业发展
2)弊
- 费用
参加培训班需要支付一定的费用,特别是一些高级和专业的培训班费用较高,可能会对学员的经济造成一定压力 - 时间投入
培训班通常需要学员投入大量时间学习和参与实践项目,对于有工作或其他学习任务的学员来说可能会较为繁忙 - 质量参差不齐
培训班市场竞争激烈,质量良莠不齐。选择不合适的培训班可能导致学到的知识和技能不符合实际需求,浪费时间和金钱 - 自学成本
有些人可能具备一定的自学能力,通过网络、书籍等自学也能获得一定的IT知识,避免了培训班的费用和时间投入 - 学习负担
对于已经有一定IT基础的学员来说,培训班可能会显得过于简单,造成学习负担不均衡
因此,参加IT培训班有许多优势,可以提高学习效果和职业竞争力,帮助学员掌握专业知识和技能。然而,选择合适的培训班很重要,需要考虑费用、时间投入和培训班的质量。对于有自学能力的学员来说,自学也是一个不错的选择。最终决策要根据个人的情况和学习目标进行权衡。
其他途径
-
自学
利用互联网上的丰富资源,如在线教程、文档、教学视频等,自行学习IT知识。自学需要良好的自律性和学习计划,但也能取得不错的学习效果。 -
开放式课程
一些大学、教育机构或在线教育平台提供开放式课程,可以免费或低费用参与学习,这些课程可以是计算机科学、编程、网络技术等方面的。 -
MOOC(大规模开放在线课程)
MOOC平台如Coursera、edX、Udemy等提供丰富多样的计算机科学和IT相关课程,学员可以自由选择感兴趣的课程进行学习。 -
图书阅读
阅读IT相关的专业书籍和参考资料,可以深入了解具体领域的知识和实践经验。 -
参与开源项目
-积极参与开源项目,贡献自己的代码和解决问题,可以在实践中学到丰富的经验和技能。 -
制定学习计划
制定合理的学习计划,包括学习目标、内容、时间安排等,帮助自己有条理地学习IT知识。 -
参加技术社区
加入技术社区、技术论坛、开发者交流群等,与其他技术人员交流经验和学习心得。 -
实践项目
尝试完成一些实际项目,这有助于将理论知识应用到实际情境中,并提升解决问题的能力。
虽然上IT培训班是一种很有效的学习方式,但以上提到的方法同样能够帮助个人学到知识。最终,选择何种学习方式应该根据个人情况、学习目标和学习风格来做出决定。有些人可能适应培训班的有导师指导的学习方式,而有些人可能更喜欢自主学习和探索。重要的是找到适合自己的学习方式,不断进步和提升自己的技能。