题目:
给你一个链表,两两交换其中相邻的节点,并返回交换后链表的头节点。你必须在不修改节点内部的值的情况下完成本题(即,只能进行节点交换)。。
示例1:
输入:head = [1,2,3,4] 输出:[2,1,4,3]
示例2:
输入:head = [] 输出:[]
示例3:
输入:head = [1] 输出:[1]
解法一:递归法(思路理清楚就超级简单)
解题思路:
首先判断head和head.next是否为空,任一为空就返回head。此时就说明至少有两个元素
然后将newhead=head.next,此时head在第一个位置,newhead在第二个位置。用fin=newhead以记住链表初始节点位置。
此处需要先保留newhead.next方向,以及将head.next准确的指向剩余整体; head.next=self.swapPairs(newhead.next)
此处思想是:将两个元素看为一组,将newhead后面的所有都看做是一个完整的链表,对于newhead.next来说就是剩余的一整块(我不管里面有没有元素或者有多少元素),这部分就是递的思想。
最后就是将head和newhead调换顺序。newhead.next=head,而对于head.next就继续指向我们所看为整体的剩下部分,因此head.next=self.swapPairs(newhead.next).对于剩下递归过程,就是整体循环过程。
解决方案(python)
#递归法
if (not head) or (not head.next):
return head
newhead=head.next
fin=newhead
#先保留head.next指针方向(因为目前newhead。next才是指向后面剩余整体的,如果移到下一行,就变成了
head.next=self.swapPairs(newhead.next)
newhead.next=head
return fin
解法二:迭代法(这是我第一思路,思路一定要通过画图先捋清楚,再用代码实现,下面解释是捋清楚后的)
解题思路:
一、首先判断head和head.next是否为空,任一为空就返回head。此时就说明至少有两个元素。
然后将new放到head.next(第二个元素位置),fin记录new的第一个节点位置(用于最后返回链表)。
二、第一步之后,由于调换new和head过程中,会破坏下一个指针的位置,因此此处就要判断是不是还有new.head,存在的话就用tem记录下来,然后new.next可以指向head了,此时,head就应该指向记录的tem。此时,head在第三个元素,new还在第二个元素,就还要继续将new移动到第一个元素位置new=new.next. 如果还有第四个元素的话(做判断tem.next是否为空),就要继续将new.next指向第四个元素(也就是head.next),同时next移动到第四个元素;但如果只有三个元素,没有第四个,那么new.next指向第三个元素head就可以了,同时也不会再有往下循环的可能,输出即可。
三:继续第二步中有第四个元素的情况,如果有第四个,上面已经做到new在第四个元素,head在第三个元素,如果进一步换new和head,又面临第二步开头考虑new.next是否存在的问题,(就跟最开始new在第二个元素,head在第一个元素形式是一样的了,因此进入循环)因此,将第二步整体做成循环。
四:当new.next不存在的时候,就只需将new.next指向当前head,同时还要注意要将head.next指向空(这样才能让位于第三个位置的head原来指向第四个元素的指针断裂,并指向链表结束),最后返回fin即可。
if (not head) or (not head.next):
return head
else:
new=head.next
fin=new
while(new.next):#如果有大于两个元素(需要记住new.next后面的地址,因此这里要讨论,存在就记住)
tem=new.next
new.next=head
head=tem
new=new.next
if (tem.next): #这里是判断是否有大于三个的元素,有就需要继续换后面两个
new.next=head.next
new=new.next
else: #如果只要三个元素,那么第三个元素就不需要调换,就直接指针指向它即可
new.next=head #此时的head就是最后一个元素
return fin #只有三个元素就不会流入下一次循环,此处可直接返回链表
new.next=head #指向最后一个元素
head.next=None #指针结束
return fin
知识点:
思路说明:
迭代法就是消除指针建立新指针的过程。用一个指针记录开始节点的位置,另外的指针都是用来修改链表指针方向的,主要体现的是思路。一定记住new=head表示new放到当前head的位置,new.next=head表示new的下一个元素指向head(会改变链表指向的位置),new=new.next表示new往下一个元素位置移动(不会改变链表指向的位置,仅仅是移动new的位置)。