牛客-剑指offer系列题解&LeedCode字节跳动企业面试题库之一:反转链表

1、问题描述:
输入一个链表,反转链表后,输出新链表的表头。

2、数据结构:
链表

3、题解:
方法1:双指针法
反转需要两步 ,第一步找到它的 结点,第二步改变结点就可以了;
之后需要 把结点 赋值为 这个元素的 本身 ;

循环:
找到 元素结点指向的元素,
目标是 让元素结点指向的元素 改为 自己本身。

# -*- coding:utf-8 -*-
# class ListNode:
#     def __init__(self, x):
#         self.val = x
#         self.next = None
class Solution:
    # 返回ListNode
    def ReverseList(self, pHead):
        # 首先判断这个链表里是否只有一个结点,只有一个结点那么它就不需要发生变化,它第一个结点指向的指针就为 none
        # 这个时候就直接返回这个 pHead
        if not pHead or not pHead.next:
            return pHead
        # 首先要明白 反转过后,第一个数值的指针的结点指向的是none 也就是一个指向反转后的首结点 为none
        last = None

        # 当 要反转的结点 pHead 存在的时候
        while pHead:
            # 先找到第一个元素的结点指向的元素,赋值给一个临时变量
            temp = pHead.next
            """
            本来一个元素的结点 是要指向它的下一个 元素的 .
            反转后 就是  这个元素 要指向它的 上一个 元素 .

            """
            # 然后第一次循环 把这第一个元素的结点 改为 none last 第一个值 是 none (此时还没有发生改变的last)
            # 之后循环 就是 每 反转一个结点 把pHead结点的下一个结点指向last,
            pHead.next = last
            # 下一步 是把 pHead 这个 元素的 赋值给last
            # last指向pHead成为反转后首结点,
            last = pHead
            # 再把pHead向前移动一个结点直至None结束
            pHead = temp

        return last

方法二:三指针法
1 将现有的头换成尾,尾部的next为空
2 将从第二个node开始,循环将next指向前一个
3 需要一直有一个指针指向还没有反转的链表的头部

class Solution:
    # 返回ListNode
    def ReverseList(self, pHead):
        # 判断是否为空值,没有元素
        if pHead == None:
            return None
        # 判断是否只有一个元素
        if pHead.next == None:
            return pHead
        # 左边指针为 头 第一个 指针
        leftPointer = pHead
        # 中间 的指针 为 第二个指针
        midPointer = pHead.next
        # 右边的指针  为 指向 中间 指针后的 所有的元素
        rightPointer = midPointer.next
        # 左边的指针为 起始 的 元素, 反转后 它的next 为 None;
        leftPointer.next = None
        # 循环,当我的右边的结点指向的 元素 一直存在的时候,那么就会一直循环,一直来反转结点。
        while rightPointer:
            # 中间指针指向的为上一个 元素 即 leftPointer
            midPointer.next = leftPointer
            # 三个指针开始往右移。每次移一个。
            # 左边指针 往右移一个 就是中间指针的位置
            leftPointer = midPointer
            # 中间指针 往 右 移 一个,就时 右边指针的位置
            midPointer = rightPointer
            # 右边指针往右移 一个 ,就时 右边指针的下一个。
            rightPointer = rightPointer.next
        # 当右指针 指向的为 空的时候 就会跳出循环,那么此时的最后一次循环的 中间的指针的 指向的 是此时的左 指针。
        midPointer.next = leftPointer
        # 最后返回中间的 这个指针,就是 最后一个 反转的指针的第一个,表头。
        return midPointer

4、复杂度分析:

方法1:
时间复杂度:O(N)
空间复杂度:O(1)
方法2:
时间复杂度:O(N)
空间复杂度:O(1)

发布了61 篇原创文章 · 获赞 10 · 访问量 2907

猜你喜欢

转载自blog.csdn.net/weixin_42042056/article/details/105610262