[Go版]算法通关村第二关青铜——终于学会链表反转了

题目:反转链表

题目链接:LeetCode-206. 反转链表
在这里插入图片描述

解决方法

源码地址:GitHub-golang版本

方法1:借助虚拟头节点反转

说明:遍历该链表,依次取出当前节点插入到新链表的首位(虚拟头结点紧后)即可,注意要提前保存当前节点的Next数据,否则插入到新链表后就没法继续向下遍历了。

func ReverselistByHead[T any](listNode *slink.LinkNode[T]) *slink.LinkNode[T]{
	if listNode == nil || listNode.Next == nil {
		return listNode
	}
	newHead := &slink.LinkNode[T]{}
	// 第一个有值结点
	tmp := listNode.Next
	for {
		next := tmp.Next
		// 下面两步将tmp结点挂在到新链表的首位
		tmp.Next = newHead.Next
		newHead.Next = tmp
		if next == nil {
			break
		}
		tmp = next
	}
	return newHead
}

方法2:不借助虚拟头节点,仅靠自身反转

说明:原理和方法1一致,只不过现在没有虚拟头结点,所以每次遍历到的当前节点都将其的Next指向新链表,然后再让新链表的头节点变更为该节点(就是每次都给新链表变更头结点),同样注意要提前保存当前节点的Next数据之后再做变更指向操作。

func ReverselistBySelf[T any](listNode *slink.LinkNode[T]) *slink.LinkNode[T] {
	if listNode == nil || listNode.Next == nil {
		return listNode
	}
	var newList *slink.LinkNode[T]
	tmp := listNode
	for {
		next := tmp.Next
		tmp.Next = newList
		newList = tmp
		if next == nil {
			break
		}
		tmp = next
	}
	return newList
}

方法3:利用递归来反转

说明:递归思想是自身调用自身。这里要反转一个链表,就是先找到它的末尾节点,作为新链表的头节点,然后依次将其与其上一个节点的指向关系对换,即:
1->2->3->4->5->nil 中的 4->5->nil 对换成 5->4->nil,然后接着
3->4->nil对换成4->3->nil( 这里5的指向没有变,所以 5->4->3->nil
2->3->nil对换成3->2->nil ( 这里4的指向没有变,所以 5->4->3->2->nil )
1->2->nil对换成2->1->nil ( 同理3的指向没有变,所以得到了 5->4->3->2->1->nil )

func ReverseListByRecursion[T any](listNode *slink.LinkNode[T]) *slink.LinkNode[T]{
	if listNode == nil || listNode.Next == nil {
		return listNode
	}
	tmp := listNode
	// newList将是该链表的尾节点
	newList := ReverseListByRecursion(tmp.Next)
	// 将tmp和它的下一个交换(eg: 2->3 ==> 3->2)
	tmp.Next.Next = tmp
	tmp.Next = nil
	return newList
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值