【面试必刷TOP101】反转链表 & 链表内指定区间反转

目录

题目:反转链表_牛客题霸_牛客网 (nowcoder.com)

题目的接口:

解题思路:

代码:

过啦!!!

题目:链表内指定区间反转_牛客题霸_牛客网 (nowcoder.com)

题目的接口:

解题思路:

代码:

过啦!!!

写在最后:


题目:反转链表_牛客题霸_牛客网 (nowcoder.com)

【面试必刷TOP101】反转链表 & 链表内指定区间反转_第1张图片

题目的接口:

package main
import "fmt"
import . "nc_tools"
/*
 * type ListNode struct{
 *   Val int
 *   Next *ListNode
 * }
 */

/**
 * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
 *
 * 
 * @param head ListNode类 
 * @return ListNode类
*/
func ReverseList( head *ListNode ) *ListNode {
    // write code here
}

解题思路:

这道题我能想到两个思路,第一个思路是不断遍历原链表,然后通过尾插的方式新建一个链表,但是这样的时间复杂度会变得很高,因为我们需要从遍历找尾开始,再尾插,而且代码也比较繁杂。

第二个方法就是通过反转指针的方式,只需要遍历一次链表,将每一个节点的指针反转过来就行了,具体操作是这样的:用 pNext 记录下一个节点,让当前节点指向 newNode, 如图:

第一步:(head 从指向 pNext 改成指向 newNode)

【面试必刷TOP101】反转链表 & 链表内指定区间反转_第2张图片

也就是现在的新链表是这样的:

【面试必刷TOP101】反转链表 & 链表内指定区间反转_第3张图片

第二步:(newNode = head,让 newNode 更新成新链表的头节点)

【面试必刷TOP101】反转链表 & 链表内指定区间反转_第4张图片

最后再让 head = pNext,就能继续往后遍历链表了。

代码:

package main
import . "nc_tools"
/*
 * type ListNode struct{
 *   Val int
 *   Next *ListNode
 * }
 */

/**
 * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
 *
 * 
 * @param head ListNode类 
 * @return ListNode类
*/
func ReverseList( head *ListNode ) *ListNode {
    if head == nil || head.Next == nil {
        return head
    }

    var newHead *ListNode
    for head != nil {
        pNext := head.Next   // 保存下一个节点
        head.Next = newHead; // 将当前节点指向一个新节点
        newHead = head       // 更新反转链表
        head = pNext         // 更新当前节点
    }

    return newHead
}

过啦!!!

【面试必刷TOP101】反转链表 & 链表内指定区间反转_第5张图片

题目:链表内指定区间反转_牛客题霸_牛客网 (nowcoder.com)

【面试必刷TOP101】反转链表 & 链表内指定区间反转_第6张图片

题目的接口:

package main
import . "nc_tools"
/*
 * type ListNode struct{
 *   Val int
 *   Next *ListNode
 * }
 */

/**
 * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
 *
 * 
 * @param head ListNode类 
 * @param m int整型 
 * @param n int整型 
 * @return ListNode类
*/
func reverseBetween( head *ListNode ,  m int ,  n int ) *ListNode {
    // write code here
}

解题思路:

这道题的核心思路如下:

首先先找到需要反转节点的位置,然后开始操作:

pre 节点作为反转链表的前一个节点,并保持不变,cur 节点作为反转链表的第一个节点,tmp 节点不断将下一个节点转移到前面,也就是反转的过程,我们以题目的样例为例:

【面试必刷TOP101】反转链表 & 链表内指定区间反转_第7张图片

进行一次操作之后,pre 保持在反转链表的前一个节点,cur 保持在反转链表的头结点位置,tmp 就出现在下一个节点的位置,而 3 节点就被反转到了前面

【面试必刷TOP101】反转链表 & 链表内指定区间反转_第8张图片

继续进行操作:

【面试必刷TOP101】反转链表 & 链表内指定区间反转_第9张图片

还是一样的:

【面试必刷TOP101】反转链表 & 链表内指定区间反转_第10张图片

代码:

package main
import . "nc_tools"
/*
 * type ListNode struct{
 *   Val int
 *   Next *ListNode
 * }
 */

/**
 * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
 *
 * 
 * @param head ListNode类 
 * @param m int整型 
 * @param n int整型 
 * @return ListNode类
*/
func reverseBetween( head *ListNode ,  m int ,  n int ) *ListNode {
    if head == nil || head.Next == nil {
        return head
    }

    // 找到反转链表的起始位置的前一个位置
    Node := &ListNode{ Next: head, }
    pre := Node
    for i := 1; i < m; i++ {
        pre = pre.Next
    }

    // 反转操作的主逻辑
    cur := pre.Next
    for i := m; i < n; i++ {
        tmp := cur.Next
        cur.Next = tmp.Next
        tmp.Next = pre.Next
        pre.Next = tmp
    }

    return Node.Next
}

过啦!!!

【面试必刷TOP101】反转链表 & 链表内指定区间反转_第11张图片

写在最后:

以上就是本篇文章的内容了,感谢你的阅读。

如果感到有所收获的话可以给博主点一个哦。

如果文章内容有遗漏或者错误的地方欢迎私信博主或者在评论区指出~

你可能感兴趣的:(牛客面试必刷,TOP101,#,链表专题,面试,链表,职场和发展)