美文网首页
反转链表之迭代

反转链表之迭代

作者: 追风骚年 | 来源:发表于2021-02-28 18:34 被阅读0次

通常代码都只会想到迭代的方式,因为迭代就是一步一步向前进,不会有后退的操作。

反转链表的迭代法之所以有难度,在于单链表的本身,链表只知道自己的下个节点,不知道自己的上个节点,所以反转的时候是找不到上个节点,所以这里需要有个指针始终持有当前节点的上个节点的位置。

反转整个链表

func reverseAll2(head *ListNode) *ListNode {
    var pre *ListNode // pre 始终指向 cur 的前个节点
    for cur := head; cur != nil; {
        // 正是 go 语言的先天的优越性,可以一次多赋值,从而非常易于理解,正常都需要弄一个变量存储 cur.Next 的值,因为 cur.Next会丢失
        // 当前节点 cur的下一个节点要指向 pre,pre 向 cur 前进一步, cur 向前前进一步
        cur.Next, pre, cur = pre, cur, cur.Next
    }
    return pre
}
func TestReverseAll2(t *testing.T) {
    t.Log(reverseAll2(GenerateLists(1, 2, 3, 4, 5)))
}

反转链表前 K 个节点

func reverseK2(head *ListNode, k int) *ListNode {
    var pre *ListNode // pre 始终指向 cur 的前个节点
    cur := head
    for i := 0; i < k; i++ {
        cur.Next, pre, cur = pre, cur, cur.Next // 同上
    }

    // 1->2->3->4->5
    // 1<-2<-3 4->5
    // 5<-4<=1<-2<-3
    head.Next = cur // 在迭代过程中 head 还是指向 1的 ,cur 由于在迭代到 4 的时候停止,head.next 需要指向 cur
    return pre
}

func TestReverseK2(t *testing.T) {
    t.Log(reverseK2(GenerateLists(1, 2, 3, 4, 5), 3))
}

反转链表 M 到 N 个节点


func reverseMN2(head *ListNode, m, n int) *ListNode {
    // 先前进 m 步
    mhead, mheadPre := head, new(ListNode)

    // 假如 m =2 n=4
    // 1->2->3->4->5
    for i := 0; i < m-1; i++ { // m 是指向 head 的,所以只需要迭代 m-1 步
        mheadPre = mhead
        mhead = mhead.Next
    }

    nhead, nCur := mhead, mhead
    // 1->2(nhead)->3->4->5
    var pre *ListNode
    for i := m; i < n+1; i++ { // nCur 需要移动到 5 ,pre 才会移动到 4
        nCur.Next, pre, nCur = pre, nCur, nCur.Next
    }

    mheadPre.Next = pre // mheadPre 是 1 需要指向 4
    nhead.Next = nCur   // nhead 是 2 需要指向 5

    // 1-> 4->3->2 ->5
    return head
}

func TestReverseMN2(t *testing.T) {
    t.Log(reverseMN2(GenerateLists(1, 2, 3, 4, 5, 6, 7), 2, 4))
}

相关文章

  • LeetCodeDay12 —— 反转链表&合并两个有序链表

    206. 反转链表 描述 反转一个单链表。 进阶 链表可以迭代或递归地反转。你能否两个都实现一遍? 思路 迭代版本...

  • leecode刷题(22)-- 反转链表

    leecode刷题(22)-- 反转链表 反转数组 反转一个单链表。 示例: 进阶:你可以迭代或递归地反转链表。你...

  • 反转链表之迭代

    通常代码都只会想到迭代的方式,因为迭代就是一步一步向前进,不会有后退的操作。 反转链表的迭代法之所以有难度,在于单...

  • 链表简单算法相关练习

    单链表反转: 给你单链表的头节点 head ,请你反转链表,并返回反转后的链表。 迭代方式实现: 复杂度分析: 时...

  • 初级算法-链表-反转链表

    给你单链表的头节点 head ,请你反转链表,并返回反转后的链表。 进阶:链表可以选用迭代或递归方式完成反转。你能...

  • 算法学习:链表反转

    题目1: 给你单链表的头节点 head ,请你反转链表,并返回反转后的链表。 递归解法: 迭代解法: 题目2: 题...

  • Swift 反转链表 - LeetCode

    题目: 反转链表 反转一个单链表。示例: 进阶:你可以迭代或递归地反转链表。你能否用两种方法解决这道题? 方案一...

  • LeetCodeSwift 206.Reverse Linked

    题目 206.反转链表 反转一个单链表。 示例: 进阶:你可以迭代或递归地反转链表。你能否用两种方法解决这道题? ...

  • Swift - LeetCode - 反转链表

    题目 反转一个单链表。 示例: 进阶: 你可以迭代或递归地反转链表。你能否用两种方法解决这道题? 方案一: 迭代:...

  • 单向链表反转算法

    常用的4种: 迭代反转法 递归反转法 头插法 就地逆置法 1 迭代反转法 从当前链表的首元节点开始,一直遍历至链表...

网友评论

      本文标题:反转链表之迭代

      本文链接:https://www.haomeiwen.com/subject/iyagfltx.html