LeetCode力扣Golang实现/链表 :21、83、141、142、160、206、234

​​​​​【Leetcode算法500题】目前B站最完整的数据结构算法教程,包含所有刷题攻略!这还没人看,我不更了!_哔哩哔哩_bilibilihttps://www.bilibili.com/video/BV11Y4y1q7YA?p=9

包: container/list"

遍历:

for e := l.Front(); e != nil; e = e.Next() {
	// do something with e.Value
}
常用函数总结------鸭鸭老板的博客-CSDN博客_go实现链表https://blog.csdn.net/qq_46093575/article/details/123054660

数据结构 链表(go实现)_Chandler~的博客-CSDN博客_go 链表icon-default.png?t=M4ADhttps://blog.csdn.net/qq_51535737/article/details/123310875?spm=1001.2101.3001.6661.1&utm_medium=distribute.pc_relevant_t0.none-task-blog-2%7Edefault%7ECTRLIST%7Edefault-1-123310875-blog-123684165.pc_relevant_default&depth_1-utm_source=distribute.pc_relevant_t0.none-task-blog-2%7Edefault%7ECTRLIST%7Edefault-1-123310875-blog-123684165.pc_relevant_default&utm_relevant_index=1

指针移动: p = p.Next

21、合并两个有序链表

递归相较于指针解法更节省空间,因为涉及出栈和入栈的操作

刚开始没有引入head结点,直接在list1、list2上操作,他会报错

:cannot use assignment (list1.Next) = (mergeTwoLists(list1.Next, l2)) as value (solution.go) 控制台 

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

}

83、删除排序链表中重复元素

我好像有一点悟到再设置一个结点的作用了,用来移动,正好可以直接输出值,所以就不用一个单单指针了,

func deleteDuplicates(head *ListNode) *ListNode {
        if head == nil {return head}
        crr := head
        for crr.Next !=nil {
            if crr.Val == crr.Next.Val{
                crr.Next =crr.Next.Next
            }else {
                crr = crr.Next
            }
        }
    
    return head

}

141、环形链表一

刚开始想到了哈希表,执行如下图,后来看了看发现是有数值重复但地址不同的元素,然后愚蠢了一把,想借用i存储下标,判断是否是同一个元素,但是一直报超出时间范围,

后来参考了一下这个哥:【go】力扣141_环形链表_ic_xcc的博客-CSDN博客 

 对啊我去,为什么不直接用记录结点啊

 //4 :如果下一个或者下下个为空,则一定无环

但是进入哈希表的时候存储结构体要{}{}

func hasCycle(head *ListNode) bool {
    if head == nil {return false }
    tmp :=make(map[*ListNode]struct{},0)
    for head.Next !=nil && head.Next.Next!=nil{
        _,ok :=  tmp[head] 
        if ok {
            return true
        }else{
            tmp[head] = struct{}{}
            head = head.Next
        }
    }
    return false
    
}

 心情舒畅了

后来看了一下进阶要求,要实现空间O(1)等我研究一下

环形链表通用解法:弗洛伊德解法:快慢指针

化为追击问题,如果能追上,肯定有环! 

 又是这里,真的呵了,报错无效地址

panic: runtime error: invalid memory address or nil pointer dereference [signal SIGSEGV:

循环条件错了,head固定跟他就没关系了,这里忘记改了 

func hasCycle(head *ListNode) bool {
    if head == nil {return false}
    fast,slow :=head,head
    for fast !=nil && slow !=nil && fast.Next !=nil {
        slow = slow.Next
        fast = fast.Next.Next
        if fast == slow{
            return true
        }
    }
    return false
}

 142.环形链表二 


func detectCycle(head *ListNode) *ListNode {
    fast,slow :=head,head
    var ans bool
    for fast !=nil && slow !=nil && fast.Next !=nil {
        slow = slow.Next
        fast = fast.Next.Next
        if fast == slow{
            ans =  true
            break
        }
    }
    if ans{
        slow = head
        for  slow != fast{
            slow = slow.Next
            fast = fast.Next
        }
        return slow
    }
    return nil
}

160、相交链表

func getIntersectionNode(headA, headB *ListNode) *ListNode {
    if headA ==nil || headB == nil{
        return nil
    }
    pA,pB := headA,headB
    for pA!= pB {
        if pA != nil{
            pA = pA.Next
        }else{
            pA =headB
        }

        if pB != nil{
            pB = pB.Next
        }else{
            pB =headA
        }
    }
    return pA
}

206、反转链表

最后返回的刚开始写的now,所以结果一直为空,但是在出循环的时候now已经=nil 了,真正的新表头是pre

func reverseList(head *ListNode) *ListNode {
    now:= head
    var pre *ListNode
    for now != nil{
        next := now.Next
        now.Next =pre
        pre=now
        now =next
    }
    return pre
}

234、回文链表

在最后for 比较是比较的是值 Val,刚开始直接用结点,所有一直得到返结果


func isPalindrome(head *ListNode) bool {
    if head == nil{return true}
    fast,slow := head,head
    for fast !=nil && fast.Next !=nil {
        fast = fast.Next.Next
        slow = slow.Next
    }
    if fast !=nil { //为奇数个
    slow = slow.Next
    }

    slow = reverseList(slow)
    fast = head
    
    for slow !=nil {
        if slow.Val != fast.Val{
            return false
        }
        slow = slow.Next
        fast = fast.Next
    }
    return true
}
//反转链表
    func reverseList(head *ListNode) *ListNode {
    now:= head
    var pre *ListNode
    for now != nil{
        next := now.Next
        now.Next =pre
        pre=now
        now =next
    }
    return pre
}

876、链表的中间结点

上题用过了

func middleNode(head *ListNode) *ListNode {
    if head == nil{return nil}
    if head !=nil  && head.Next == nil{return head}
    fast,slow := head,head
    for fast !=nil && fast.Next !=nil {
        slow = slow.Next
        fast = fast.Next.Next
    }

    return slow 
}

剑指offer22、返回链表中倒数第k个结点 

大胆推测凡是要通过遍历确定长度进而确定位置的都可以用快慢指针 

 快指针先行k-1个

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值