【leetcode】第二天
问题描述:反转一个单链表。
示例:
输入: 1->2->3->4->5->NULL
输出: 5->4->3->2->1->NULL
-
c
迭代法
反转链表需要用到的一个知识点就是链表的"头插法"。将需要插入的节点的next指向待插入链表,即实现了节点的头插。通过迭代则将所有的节点按照头插的方式插入即将返回的链表,实现了链表的反转。
struct ListNode* reverseList(struct ListNode* head){
struct ListNode *p,*rev=NULL;
while(head)
{
p=head->next;//中间需要用head链表来把当前头结点和反转链表串起来,所以首先需要对head进行存储。
head->next=rev;//反转链表初始为空,然后通过将反转链表指向头结点,
rev=head;//再将head赋给反转链表,实现增加头结点的功能。
head=p;//最后把初使head节点后移,循环,实现链表的反转。
}
return rev;
}
-
python
这里利用了多元赋值,右边的值在赋值过程中不变,因此不需要借助C语言中的中间链表来存储head节点。(代码思想同c语言)。
class Solution:
def reverseList(self, head):
"""
:type head: ListNode
:rtype: ListNode
"""
p, rev = head, None
while p:
rev, rev.next, p = p, rev, p.next
return rev
3.java(交换函数swap()的妙用)
注意点:java函数中对象类型都是通过引用拷贝(跟C++中引用不同)传参,通过该引用能够更改其指向的对象内部值,但是更改该引用值,仅对函数内部可见,函数外部的实参依然没有改变。
p取出来除头结点的值,head只取头结点。
交换p和head后head为去掉头节点的链表,p为增加了头结点的链表。
继续迭代 …
// Time 8ms, 99%
class Solution {
public:
ListNode* reverseList(ListNode* head) {
ListNode *p;
for(p=NULL; head; swap(head,p))
swap(p,head->next);
return p;
}
- 递归法
当第n次执行reverseList函数满足终止条件时,跳出第n次递归,执行下面的两句语句。
class Solution:
def reverseList(self, head: ListNode) -> ListNode:
if head==None or head.next==None:
return head
tail=self.reverseList(head.next)
head.next.next=head
head.next=None
return tail
- 1→2→3→NULL
- 1→2→3→2→3→NULL
- 1→2 3→2→NULL
- 3→2→1→2→NULL
- 3→2→1→NULL
节点的位置是固定的,例子中的2都是同一个节点,有可能多个节点链接到同一个节点。
递归的思路一定要清晰,要有终止递归的条件!!