0206-leetcode算法实现-反转链表reverse-linked-list-python&golang实现

给你单链表的头节点 head ,请你反转链表,并返回反转后的链表。

示例 1:

输入:head = [1,2,3,4,5]
输出:[5,4,3,2,1]
示例 2:

输入:head = [1,2]
输出:[2,1]
示例 3:

输入:head = []
输出:[]

提示:

链表中节点的数目范围是 [0, 5000]
-5000 <= Node.val <= 5000

进阶:链表可以选用迭代或递归方式完成反转。你能否用两种方法解决这道题?

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/reverse-linked-list

python

# 反转单链表 迭代或递归

class ListNode:
    def __init__(self, val):
        self.val = val
        self.head = None

class Solution:
    def reverseList2(self, head: ListNode) -> ListNode:
        """
        双指针法
        :param head:
        :return:
        """
        # 空表时直接返空
        if head is None:
            return None
        # 初始化cur为head
        cur = head
        while head.next != None: # 当head的next非空时, 完成局部反转
            tmp = head.next.next
            head.next.next = cur
            cur = head.next
            head.next = tmp
        return cur


    def reverseList1(self, head: ListNode) -> ListNode:
        """
        迭代法,时间O(n), 空间O(1),
        思路:
        - 创建3个变量,prev,cur,next,prev表示前序节点,cur当前节点,next后继节点
        - 为不间断,赋值变量next取到cur的下个节点,cur节点指向prev, prev移动到cur, cur移动到下个节点
        算法流程:
        - 1.初始化节点,prev前序节点为空,cur当前节点为头结点
        - 2.当cur节点不为空时,为不间断链表,令cur.next为next节点,cur.next赋值为prev, prev节点移动到cur, cur节点后移至next, 重复执行
        - 3.当cur节点为None时,链表已经全部遍历,prev已走到原链表的最后位置
        :param head:
        :return:
        """
        prev = None # 初始化前序节点None,空
        cur = head # 当前节点为头结点
        while cur is not None: # 当当前节点非空时执行循环
            next = cur.next # 为不间断后续节点,赋值当前节点的下个节点给next
            cur.next = prev # cur节点指向prev
            prev = cur # prev节点移动到cur
            cur = next # cur节点移动到next
        return prev # 当遍历结束时,prev应该为原链表的最后的一个节点,也是新链表的第一个节点

    def reverseList(self, head: ListNode) -> ListNode:
        """
        递归法,时间O(n), 空间O(n)
        :param head:
        :return:
        """
        # 递归终止条件
        if head is None or head.next is None:
            return head
        # 每次将head节点的next部分反转,p为最后一个节点,也是反转后的第一个节点
        p = self.reverseList(head.next)
        # 因为经上已经反转head.next部分,此时next链表部分的最后一个节点就是head.next,
        # head.next节点指向head,即完成单次递归右往左的反转
        head.next.next = head
        # 由于head指针为当前递归的最后一个元素,next指向空即可
        head.next = None

        return p # 返回反转后的头结点

golang

package main

// 迭代
func reverselist1(head *ListNode) *ListNode {
	var prev *ListNode = nil
	cur := head
	for cur != nil {
		next := cur.Next
		cur.Next = prev
		prev = cur
		cur = next
	}
	return prev
}

// 递归
func reverseList2(head *ListNode) *ListNode {
	// 递归终止条件
	if head == nil || head.Next == nil {
		return head
	}

	var p *ListNode = reverseList2(head.Next)
	head.Next.Next = head
	head.Next = nil
	return p
}

// 双指针,不好理解建议迭代和递归
func reverseList3(head *ListNode) *ListNode {
	if head == nil {
		return head
	}

	cur := head
	for head.Next != nil {
		temp := head.Next.Next
		head.Next.Next = cur
		cur = head.Next
		head.Next = temp
	}
	return cur
}

posted on 2021-11-02 23:32  进击的davis  阅读(34)  评论(0编辑  收藏  举报

导航