4.链表入门

单双链表及其反转-堆栈诠释

        值引用:函数调用得到原值的拷贝,函数实际使用的变量与原变量解耦。

        引用传递:函数调用拷贝原指针得到一个新指针,该指针和原指针指向同一个内存区域。

反转单链表

        题干:给你单链表的头节点 head ,请你反转链表,并返回反转后的链表。

        使用双指针法,使用head进行遍历,pre指向head前一个节点,next指向head后一个节点。在每轮,首先得到head的下一个节点(为了在断掉这个节点的next后能够找到下一个节点),让head.next指向pre,然后pre指向当前节点,head指向原来的下一个节点next。

func ReverseList(head *Node) *Node {
	var pre *Node
	var next *Node
	for head != nil {
		next = head.next
		head.next = pre
		pre = head
		head = next
	}
	return pre
}

反转双链表

        题干:给你双链表的头节点 head ,请你反转链表,并返回反转后的链表。

        和反转单链表一样,唯一不同增加一个把当前节点的last指向next的操作。

func ReverseDoubleList(head *Node) *Node {
	var pre *Node
	var next *Node
	for head != nil {
		next = head.next
		head.next = pre
		head.last = next
		pre = head
		head = next
	}
	return pre
}

链表入门题目-合并两个有序链表

        将两个升序链表合并为一个新的 升序 链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。 

        首先确定新链表的首节点head,pre指向head。然后list1和list2不断往后遍历。随后循环比较大小,确定pre下一个要链接的节点。最后如果有一个为空,则直接链接另一个剩余的所有节点。引用传递直接使用list1和list2也没问题。

func mergeTwoLists(list1 *ListNode, list2 *ListNode) *ListNode {
	if list1 == nil {
		return list2
	} else if list2 == nil {
		return list1
	}
	var head, pre *ListNode
	if list1.Val > list2.Val {
		head = list2
		list2 = head.Next
	} else {
		head = list1
		list1 = head.Next
	}
	pre = head
	for list1 != nil && list2 != nil {
		if list1.Val > list2.Val {
			pre.Next = list2
			list2 = list2.Next
		} else {
			pre.Next = list1
			list1 = list1.Next
		}
		pre = pre.Next
	}
	if list1 == nil {
		pre.Next = list2
	} else if list2 == nil {
		pre.Next = list1
	}
	return head
}

链表入门题目-两个链表相加

        给你两个 非空 的链表,表示两个非负的整数。它们每位数字都是按照 逆序 的方式存储的,并且每个节点只能存储 一位 数字。

        使用temp存储当前数,temp%10是当前要存储的数,temp/10是判断是否有进位。这里在每轮循环让cur创建节点并对其赋值是为了保证不会在最后创建无值节点。保证除了头节点之后的所有节点的值是由temp决定的。否则如果先对当前节点赋值后创建下一个节点,则在计算的最后一轮给当前节点赋值后会再创建一个值,从而造成错误结果。

func addTwoNumbers(l1 *ListNode, l2 *ListNode) *ListNode {
	temp := 0
	head := &ListNode{}
	var cur = head
	for l1 != nil || l2 != nil {
		if l1 != nil {
			temp += l1.Val
			l1 = l1.Next
		}
		if l2 != nil {
			temp += l2.Val
			l2 = l2.Next
		}
		cur.Next = &ListNode{Val: temp % 10}
		temp /= 10
		cur = cur.Next
	}
	if temp != 0 {
		cur.Next = &ListNode{Val: temp}
	}
	return head.Next
}

链表入门题目-划分链表

        给你一个链表的头节点 head 和一个特定值 x ,请你对链表进行分隔,使得所有 小于 x 的节点都出现在 大于或等于 x 的节点之前。

        你应当 保留 两个分区中每个节点的初始相对位置。

        创建两个新链表,不断往后创建符合该链表要求的节点,创建并赋值的理由同上一题。最后让小于链表的next指向等于或大于链表头的next

func partition(head *ListNode, x int) *ListNode {
	less, more := &ListNode{}, &ListNode{}
	var lesshead, morehead  *ListNode
	lesshead = less
	morehead =more
	cur := head
	for cur != nil {
		if cur.Val < x {
			less.Next = &ListNode{Val: cur.Val}
			less = less.Next
		} else {
			more.Next = &ListNode{Val: cur.Val}
			more = more.Next
		}
        cur = cur.Next
	}
	less.Next = morehead.Next
	return lesshead.Next
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值