链表内指定区间反转

链表内指定区间反转

https://www.nowcoder.com/practice/b58434e200a648c589ca2063f1faf58c

package main

import . "nc_tools"
// import "fmt"

/*
 * 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 m == n {
		return head
	}
	if head.Next == nil {
		return head
	}

	pBeforeM := head
	for i := 1; i < m-1; i++ {
		pBeforeM = pBeforeM.Next
	}
	pM := pBeforeM.Next
    if m == 1 {
        pM = head
        pBeforeM = nil
    }

	pN := pM
	for i := m; i < n; i++ {
		pN = pN.Next
	}
	pAfterN := pN.Next

	pA := pM
	pB := pA.Next
	for pB != pAfterN {
		pTmp := pB.Next
		pB.Next = pA
		pA = pB
		pB = pTmp
	}

    if pBeforeM != nil {
        pBeforeM.Next = pN
    }
	pM.Next = pAfterN

    if m == 1 {
        return pA
    }
	return head
}

解题思路:

  1. 找出四个节点:
  2. pM,m 对应的节点
  3. pBeforeM,pM 的上一个节点
  4. pN,n 对应的节点
  5. pAfterN,pN 的下一个节点
  6. 将 [pM, pN] 之间的节点按照 反转链表 进行处理
  7. 将 pBeforeM.Next 改为指向 pN,将 pM.Next 改为指向 pAfterN

注意事项:

  • m 等于 1 的情况下,需要将 pBeforeM 修正为 nil,将 pM 修正为等于 head
  • pBeforeM 不等于 nil 的情况下,才需要执行解题思路中步骤 3 的 "pBeforeM.Next = pN"
  • 关于返回值
  • m == 1 的情况下,返回 [pM, pN] 区间之间反转后的链表头部
  • m != 1 的情况下,直接返回 head
全部评论

相关推荐

点赞 收藏 评论
分享
牛客网
牛客企业服务