单双链表及其反转-堆栈诠释
值引用:函数调用得到原值的拷贝,函数实际使用的变量与原变量解耦。
引用传递:函数调用拷贝原指针得到一个新指针,该指针和原指针指向同一个内存区域。
反转单链表
题干:给你单链表的头节点 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
}