T1. 链表倒数K个节点
时间复杂度复习下
在想快慢针和直接遍历得链表长度然后找节点有什么区别,想了下时间复杂度上还是有区别的,计数多n次
func FindKthToTail(pHead *ListNode, k int) *ListNode {
// write code here
if k <= 0 {
return nil
}
fast := pHead
slow := &ListNode{-1, pHead}
for i := 0; i < k; i++ {
if fast == nil {
return nil
}
fast = fast.Next
}
for fast != nil {
fast = fast.Next
slow = slow.Next
}
return slow.Next
}
吐槽:
牛客后台是怎么算运行时间的???我这段代码和榜一代码有啥区别,我跑了100ms???
T2. 公共节点
func FindFirstCommonNode( pHead1 *ListNode , pHead2 *ListNode ) *ListNode {
// write code here
len1, len2 := getLenth(pHead1), getLenth(pHead2)
if len1 < len2 {
n := len2 - len1
for ; n > 0; n-- {
pHead2 = pHead2.Next
}
} else {
n := len1 - len2
for ; n > 0; n-- {
pHead1 = pHead1.Next
}
}
for pHead1 != pHead2 {
pHead1 = pHead1.Next
pHead2 = pHead2.Next
}
return pHead1
}
func getLenth(pHead *ListNode) int {
cur := &ListNode{-1,pHead}
lenth := 0
for cur.Next != nil {
cur = cur.Next
lenth ++
}
return lenth
}
可改进:
骚操作一下
func FindFirstCommonNode( pHead1 *ListNode , pHead2 *ListNode ) *ListNode {
p1, p2 := pHead1, pHead2
if p1 == nil || p2 == nil {
return nil
}
for p1 != p2 {
if p1 == nil {
p1 = pHead2
} else {
p1 = p1.Next
}
if p2 == nil {
p2 = pHead1
} else {
p2 = p2.Next
}
}
return p2
}
T3. 链表相加
旧版:
func addInList(head1 *ListNode, head2 *ListNode) *ListNode {
// write code here
if head1 == nil {
return head2
}
if head2 == nil {
return head1
}
new1 := reverse(head1)
new2 := reverse(head2)
newHead := ListNode{-1, nil}
cur := &newHead //cur.Next存放新节点地址
tag := 0
for new1 != nil && new2 != nil { //加法运算设计不够好,代码繁琐,时间开销增大
cur.Next = &ListNode{(new1.Val + new2.Val + tag) % 10, nil}
if (new1.Val + new2.Val + tag) > 9 {
tag = 1
} else {
tag = 0
}
new1 = new1.Next
new2 = new2.Next
cur = cur.Next
}
if new1 == nil && new2 == nil && tag == 1 {
cur.Next = &ListNode{tag, nil}
}
for new1 != nil {
new1 = add2(new1, cur, tag)
}
for new2 != nil {
new2 = add2(new2, cur, tag)
}
return reverse(newHead.Next)
}
func reverse(head *ListNode) *ListNode {
var pre, cur, next *ListNode
pre = nil
cur = head
for cur != nil {
next = cur.Next
cur.Next = pre
pre = cur
cur = next
}
return pre
}
func add2(head, cur *ListNode, tag int) *ListNode { //加法运算设计不够好导致多写一个函数来处理有一个链表已空的情况
for head != nil {
cur.Next = &ListNode{(tag + head.Val) % 10, nil}
if (tag + head.Val) > 9 {
tag = 1
} else {
tag = 0
}
cur = cur.Next
head = head.Next
}
if tag == 1 {
cur.Next = &ListNode{tag, nil}
}
return head
}
改进思路:
注意进行算法设计时要足够细致,想清楚再动手,否则后面改动更麻烦。加法运算部分没有仔细考虑导致加法处理繁琐,加法部分实际为new1.Val + new2.Val + tag ,三部分分别判断有无即可一个循环写完,少很多代码,且不用再另写add2()做额外处理
func addInList(head1 *ListNode, head2 *ListNode) *ListNode {
// write code here
if head1 == nil {
return head2
}
if head2 == nil {
return head1
}
new1 := reverse(head1)
new2 := reverse(head2)
newHead := ListNode{-1, nil}
cur := &newHead //cur.Next存放新节点地址
val, tag := 0, 0
for new1 != nil || new2 != nil {
val = tag
if new1 != nil {
val += new1.Val
new1 = new1.Next
}
if new2 != nil {
val += new2.Val
new2 = new2.Next
}
if val > 9 {
tag = 1
} else {
tag = 0
}
cur.Next = &ListNode{val % 10, nil}
cur = cur.Next
}
if tag == 1 {
cur.Next = &ListNode{val % 10, nil}
}
return reverse(newHead.Next)
}
func reverse(head *ListNode) *ListNode {
var pre, cur, next *ListNode
pre = nil
cur = head
for cur != nil {
next = cur.Next
cur.Next = pre
pre = cur
cur = next
}
return pre
}
T4. 奇偶重排
写这题时犯了个错,没对even做处理,奇数个节点时成环了
func oddEvenList(head *ListNode) *ListNode {
// write code here
odd := &ListNode{-1, nil}
new1 := odd
even := &ListNode{-1, nil}
new2 := even
tag := 1
for head != nil {
if tag == 1 {
odd.Next = head
odd = odd.Next
tag = 2
} else {
even.Next = head
even = even.Next
tag = 1
}
head = head.Next
}
even.Next = nil //奇数个节点时even.Next指向了odd,链表成环
odd.Next = new2.Next
return new1.Next
}
T5. 删除重复节点(输入1 1 1 2,输出2)
func deleteDuplicates(head *ListNode) *ListNode {
// write code here
pre := &ListNode{-1, head}
newHead := pre
for head != nil && head.Next != nil {
if head.Val == head.Next.Val {
tag := head.Val
pre.Next = head.Next.Next
head = pre.Next
for head != nil { //不开内循环不行啊!!!!!
if tag == head.Val {
pre.Next = head.Next
head = head.Next
} else {
break
}
}
} else {
pre = head
head = head.Next
}
}
return newHead.Next
}