LeetCode力扣-hot100系列(2)
最近断更了,因为知识点差不多总结完了,剩下一些零零散散的需要注意的小点。这些也不好总结归纳,因此转向力扣刷题,不过速度有点慢。
这篇主要将链表的内容写完,不过内容可能一篇也写不完。
链表
[1]相交链表
问:给你两个单链表的头节点 headA
和 headB
,请你找出并返回两个单链表相交的起始节点。如果两个链表不存在相交节点,返回 null
。
这里主要就是需要计算两个链表之间的差值,也就是节点数量,可以在遍历节点的时候就开始计算。
func getIntersectionNode(headA, headB *ListNode) *ListNode {nodeA := headAa := 0b := 0nodeB := headB for nodeA.Next != nil {nodeA = nodeA.Nexta++}for nodeB.Next != nil {nodeB = nodeB.Nextb++}if nodeA.Next!=nodeB.Next{return nil}nodeA = headAnodeB = headBvar c intif a > b{c = a-bfor i := 0; i < c;i++{nodeA = nodeA.Next}}else{c = b-afor i := 0; i < c;i++{nodeB = nodeB.Next}}for nodeA != nodeB{nodeA = nodeA.NextnodeB = nodeB.Next}return nodeA
}
[2]反转链表
问:给你单链表的头节点 head
,请你反转链表,并返回反转后的链表。
做一个虚拟头节点就好了,然后用头插法将链表反转,返回虚拟头节点的下一个节点。
func reverseList(head *ListNode) *ListNode {if head == nil{return nil}node := &ListNode{Val: 0,Next: nil,}node1 := headnode2 := headfor node2.Next != nil{node2 = node1.Nextnode1.Next = node.Nextnode.Next = node1node1 = node2}node2.Next = node.Nextnode.Next = node2return node2
}
[3]回文链表
问:给你一个单链表的头节点 head
,请你判断该链表是否为回文链表。如果是,返回 true
;否则,返回 false
。
最简单的办法,用一个切片将所有的元素保存起来,然后再通过下标来判断就好了。
func isPalindrome(head *ListNode) bool {node := heads := []int{}for node!=nil{s = append(s, node.Val)node = node.Next}left := 0right := len(s)-1for left < right{if s[left] == s[right]{left++right--}else{return false}}return true
}
[4]环形链表
问:给你一个链表的头节点 head
,判断链表中是否有环。
很简单的公式,直接套用就好。就是快慢指针从头节点出发,然后快指针走两步,慢指针走一步,如果快指针走完了就没有环,如果快慢指针相遇了就有环。
func hasCycle(head *ListNode) bool {slow := headfast := headfor fast != nil && fast.Next != nil{fast = fast.Next.Nextslow = slow.Nextif fast == slow{return true}}return false
}
[5]环形链表II
问:给定一个链表的头节点 head
,返回链表开始入环的第一个节点。 如果链表无环,则返回 null
。
在第一次相遇的时候,快指针从头节点重新走,然后都是一步一步的走,再次相遇就是入口了。
func detectCycle(head *ListNode) *ListNode {slow := headfast := headfor fast != nil && fast.Next != nil{fast = fast.Next.Nextslow = slow.Nextif fast == slow{fast = headfor fast != slow{fast = fast.Nextslow = slow.Next}return fast}}return nil
}
[6]合并两个有序链表
问:将两个升序链表合并为一个新的 升序 链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。
func mergeTwoLists(list1 *ListNode, list2 *ListNode) *ListNode {node1 := list1node2 := list2node := &ListNode{Val: 0,Next: nil,}node0 := nodefor node1 != nil && node2 != nil{if node1.Val < node2.Val{node0.Next = node1node0 = node1node1 = node1.Next}else{node0.Next = node2node0 = node2node2 = node2.Next}}if node1 != nil{node0.Next = node1}if node2 != nil{node0.Next = node2}return node.Next
}
[7]两数相加
问:给你两个 非空 的链表,表示两个非负的整数。它们每位数字都是按照 逆序 的方式存储的,并且每个节点只能存储 一位 数字。
func addTwoNumbers(l1 *ListNode, l2 *ListNode) *ListNode {flag := 0node := &ListNode{Val: 0,Next: nil,}node1 := nodefor l1 != nil && l2 != nil{val := l1.Val + l2.Val + flagflag = 0if val >= 10{flag = 1val = val - 10}node0 := &ListNode{Val: val,Next: nil,}node.Next = node0node = node0l1 = l1.Nextl2 = l2.Next}for l1 != nil{val := l1.Val + flagflag = 0if val >= 10{flag = 1val = val - 10}node0 := &ListNode{Val: val,Next: nil,}node.Next = node0node = node0l1 = l1.Next}for l2 != nil{ val := l2.Val + flagflag = 0if val >= 10{flag = 1val = val - 10}node0 := &ListNode{Val: val,Next: nil,}node.Next = node0node = node0l2 = l2.Next}if flag != 0{node0 := &ListNode{Val: flag,Next: nil,}node.Next = node0}return node1.Next
}
[8]删除链表的倒数第N个节点
问:给你一个链表,删除链表的倒数第 n
个结点,并且返回链表的头结点。
使用两个相隔为n的节点指针就好了,但要注意不要让fast结点指针访问超过地址的内存空间。
func removeNthFromEnd(head *ListNode, n int) *ListNode {slow := headfast := headfor i:=0;i<n;i++{fast = fast.Next}if fast == nil{return head.Next}for fast.Next != nil{fast = fast.Nextslow = slow.Next}if n == 1{slow.Next = nil}else{slow.Next = slow.Next.Next}return head
}
[9]两两交换链表中的节点
问:给你一个链表,两两交换其中相邻的节点,并返回交换后链表的头节点。你必须在不修改节点内部的值的情况下完成本题(即,只能进行节点交换)。
注意不要让链子断开来了,尤其是处理完两个节点后,还需要保存其中后面的节点作为下两个节点的先驱节点。
func swapPairs(head *ListNode) *ListNode {size := 0node := headfor node != nil{size++node = node.Next}if size < 2{return head}pnode := &ListNode{Val: 0,Next: head,}node = headresult := head.Nextfor node != nil && node.Next != nil{pnode.Next = node.Nextmnode := node.Nextnode.Next = mnode.Nextmnode.Next = nodepnode = nodenode = node.Next}return result
}
[10]随机链表的复制
问:给你一个长度为 n
的链表,每个节点包含一个额外增加的随机指针 random
,该指针可以指向链表中的任何节点或空节点。
小细节需要注意,如链表别不小心断开了。方法就是在原来的基础上复制。
func copyRandomList(head *Node) *Node {node0 := headfor node0 != nil{node := &Node{Val: node0.Val,Next: node0.Next,Random: nil,}node0.Next = nodenode0 = node.Next}//再处理randomnode0 = headfor node0 != nil{if node0.Random != nil {node0.Next.Random = node0.Random.Next}node0 = node0.Next.Next}//再断开head1 := &Node{Val: 0,Next: nil,Random: nil,}node1 := head1node0 = headfor node0 != nil{node1.Next = node0.Nextnode1 = node1.Nextnode0.Next = node0.Next.Nextnode0 = node0.Next} return head1.Next
}