目录
141. 环形链表 Linked List Cycle 🌟
142. 环形链表 II Linked List Cycle II 🌟🌟
143. 重排链表 Reorder List 🌟🌟
🌟 每日一练刷题专栏 🌟
Golang每日一练 专栏
Python每日一练 专栏
C/C++每日一练 专栏
Java每日一练 专栏
141. 环形链表 Linked List Cycle
给你一个链表的头节点 head
,判断链表中是否有环。
如果链表中有某个节点,可以通过连续跟踪 next
指针再次到达,则链表中存在环。 为了表示给定链表中的环,评测系统内部使用整数 pos
来表示链表尾连接到链表中的位置(索引从 0 开始)。注意:pos
不作为参数进行传递 。仅仅是为了标识链表的实际情况。
如果链表中存在环 ,则返回 true
。 否则,返回 false
。
示例 1:
输入:head = [3,2,0,-4], pos = 1 输出:true 解释:链表中有一个环,其尾部连接到第二个节点。
示例 2:
输入:head = [1,2], pos = 0 输出:true 解释:链表中有一个环,其尾部连接到第一个节点。
示例 3:
输入:head = [1], pos = -1 输出:false 解释:链表中没有环。
提示:
- 链表中节点的数目范围是
[0, 10^4]
-10^5 <= Node.val <= 10^5
pos
为-1
或者链表中的一个 有效索引 。
进阶:你能用 O(1)
(即,常量)内存解决此问题吗?
代码1: 快慢指针
package main
import "fmt"
type ListNode struct {
Val int
Next *ListNode
}
func hasCycle(head *ListNode) bool {
if head == nil || head.Next == nil {
return false
}
slow, fast := head, head.Next
for slow != fast {
if fast == nil || fast.Next == nil {
return false
}
slow, fast = slow.Next, fast.Next.Next
}
return true
}
func createRingNodeList(nums []int, pos int) *ListNode {
if len(nums) == 0 {
return nil
}
head := &ListNode{Val: nums[0]}
tail := head
for i := 1; i < len(nums); i++ {
tail.Next = &ListNode{Val: nums[i]}
tail = tail.Next
}
if pos >= 0 {
p := head
for pos > 0 {
p = p.Next
pos--
}
tail.Next = p
}
return head
}
func main() {
nums, pos := []int{3, 2, 0, -4}, 1
head := createRingNodeList(nums, pos)
fmt.Println(hasCycle(head))
nums, pos = []int{1, 2}, 0
head = createRingNodeList(nums, pos)
fmt.Println(hasCycle(head))
nums, pos = []int{1}, -1
head = createRingNodeList(nums, pos)
fmt.Println(hasCycle(head))
}
代码2: 哈希表
package main
import "fmt"
type ListNode struct {
Val int
Next *ListNode
}
func hasCycle(head *ListNode) bool {
visited := make(map[*ListNode]bool)
for head != nil {
if visited[head] {
return true
}
visited[head] = true
head = head.Next
}
return false
}
func createRingNodeList(nums []int, pos int) *ListNode {
if len(nums) == 0 {
return nil
}
head := &ListNode{Val: nums[0]}
tail := head
for i := 1; i < len(nums); i++ {
tail.Next = &ListNode{Val: nums[i]}
tail = tail.Next
}
if pos >= 0 {
p := head
for pos > 0 {
p = p.Next
pos--
}
tail.Next = p
}
return head
}
func main() {
nums, pos := []int{3, 2, 0, -4}, 1
head := createRingNodeList(nums, pos)
fmt.Println(hasCycle(head))
nums, pos = []int{1, 2}, 0
head = createRingNodeList(nums, pos)
fmt.Println(hasCycle(head))
nums, pos = []int{1}, -1
head = createRingNodeList(nums, pos)
fmt.Println(hasCycle(head))
}
代码3: 递归
package main
import "fmt"
type ListNode struct {
Val int
Next *ListNode
}
func hasCycle(head *ListNode) bool {
visited := make(map[*ListNode]bool)
return checkCycle(head, visited)
}
func checkCycle(head *ListNode, visited map[*ListNode]bool) bool {
if head == nil {
return false
}
if visited[head] {
return true
}
visited[head] = true
return checkCycle(head.Next, visited)
}
func createRingNodeList(nums []int, pos int) *ListNode {
if len(nums) == 0 {
return nil
}
head := &ListNode{Val: nums[0]}
tail := head
for i := 1; i < len(nums); i++ {
tail.Next = &ListNode{Val: nums[i]}
tail = tail.Next
}
if pos >= 0 {
p := head
for pos > 0 {
p = p.Next
pos--
}
tail.Next = p
}
return head
}
func main() {
nums, pos := []int{3, 2, 0, -4}, 1
head := createRingNodeList(nums, pos)
fmt.Println(hasCycle(head))
nums, pos = []int{1, 2}, 0
head = createRingNodeList(nums, pos)
fmt.Println(hasCycle(head))
nums, pos = []int{1}, -1
head = createRingNodeList(nums, pos)
fmt.Println(hasCycle(head))
}
输出:
true
true
false
142. 环形链表 II Linked List Cycle II
给定一个链表的头节点 head
,返回链表开始入环的第一个节点。 如果链表无环,则返回 null
。
如果链表中有某个节点,可以通过连续跟踪 next
指针再次到达,则链表中存在环。 为了表示给定链表中的环,评测系统内部使用整数 pos
来表示链表尾连接到链表中的位置(索引从 0 开始)。如果 pos
是 -1
,则在该链表中没有环。注意:pos
不作为参数进行传递,仅仅是为了标识链表的实际情况。
不允许修改 链表。
示例 1:
输入:head = [3,2,0,-4], pos = 1 输出:返回索引为 1 的链表节点 解释:链表中有一个环,其尾部连接到第二个节点。
示例 2:
输入:head = [1,2], pos = 0 输出:返回索引为 0 的链表节点 解释:链表中有一个环,其尾部连接到第一个节点。
示例 3:
输入:head = [1], pos = -1 输出:返回 null 解释:链表中没有环。
提示:
- 链表中节点的数目范围在范围
[0, 10^4]
内 -10^5 <= Node.val <= 10^5
pos
的值为-1
或者链表中的一个有效索引
进阶:你是否可以使用 O(1)
空间解决此题?
代码1: 快慢指针
package main
import "fmt"
type ListNode struct {
Val int
Next *ListNode
}
func detectCycle(head *ListNode) *ListNode {
if head == nil || head.Next == nil {
return nil
}
slow, fast := head, head
for fast != nil && fast.Next != nil {
slow = slow.Next
fast = fast.Next.Next
if slow == fast {
slow = head
for slow != fast {
slow = slow.Next
fast = fast.Next
}
return slow
}
}
return nil
}
func createRingNodeList(nums []int, pos int) *ListNode {
if len(nums) == 0 {
return nil
}
head := &ListNode{Val: nums[0]}
tail := head
for i := 1; i < len(nums); i++ {
tail.Next = &ListNode{Val: nums[i]}
tail = tail.Next
}
if pos >= 0 {
p := head
for pos > 0 {
p = p.Next
pos--
}
tail.Next = p
}
return head
}
func showResult(head *ListNode) {
if detectCycle(head) == nil {
fmt.Println("null")
} else {
fmt.Println(detectCycle(head).Val)
}
}
func main() {
nums, pos := []int{3, 2, 0, -4}, 1
head := createRingNodeList(nums, pos)
showResult(detectCycle(head))
nums, pos = []int{1, 2}, 0
head = createRingNodeList(nums, pos)
showResult(detectCycle(head))
nums, pos = []int{1}, -1
head = createRingNodeList(nums, pos)
showResult(detectCycle(head))
}
代码2: 哈希表
package main
import "fmt"
type ListNode struct {
Val int
Next *ListNode
}
func detectCycle(head *ListNode) *ListNode {
visited := make(map[*ListNode]bool)
for head != nil {
if visited[head] {
return head
}
visited[head] = true
head = head.Next
}
return nil
}
func createRingNodeList(nums []int, pos int) *ListNode {
if len(nums) == 0 {
return nil
}
head := &ListNode{Val: nums[0]}
tail := head
for i := 1; i < len(nums); i++ {
tail.Next = &ListNode{Val: nums[i]}
tail = tail.Next
}
if pos >= 0 {
p := head
for pos > 0 {
p = p.Next
pos--
}
tail.Next = p
}
return head
}
func showResult(head *ListNode) {
if detectCycle(head) == nil {
fmt.Println("null")
} else {
fmt.Println(detectCycle(head).Val)
}
}
func main() {
nums, pos := []int{3, 2, 0, -4}, 1
head := createRingNodeList(nums, pos)
showResult(detectCycle(head))
nums, pos = []int{1, 2}, 0
head = createRingNodeList(nums, pos)
showResult(detectCycle(head))
nums, pos = []int{1}, -1
head = createRingNodeList(nums, pos)
showResult(detectCycle(head))
}
代码3: 数组
package main
import "fmt"
type ListNode struct {
Val int
Next *ListNode
}
func detectCycle(head *ListNode) *ListNode {
visited := make([]*ListNode, 0)
for head != nil {
for _, node := range visited {
if node == head {
return node
}
}
visited = append(visited, head)
head = head.Next
}
return nil
}
func createRingNodeList(nums []int, pos int) *ListNode {
if len(nums) == 0 {
return nil
}
head := &ListNode{Val: nums[0]}
tail := head
for i := 1; i < len(nums); i++ {
tail.Next = &ListNode{Val: nums[i]}
tail = tail.Next
}
if pos >= 0 {
p := head
for pos > 0 {
p = p.Next
pos--
}
tail.Next = p
}
return head
}
func showResult(head *ListNode) {
if detectCycle(head) == nil {
fmt.Println("null")
} else {
fmt.Println(detectCycle(head).Val)
}
}
func main() {
nums, pos := []int{3, 2, 0, -4}, 1
head := createRingNodeList(nums, pos)
showResult(detectCycle(head))
nums, pos = []int{1, 2}, 0
head = createRingNodeList(nums, pos)
showResult(detectCycle(head))
nums, pos = []int{1}, -1
head = createRingNodeList(nums, pos)
showResult(detectCycle(head))
}
输出:
2
1
null
143. 重排链表 Reorder List
给定一个单链表 L
的头节点 head
,单链表 L
表示为:
L0 → L1 → … → Ln - 1 → Ln
请将其重新排列后变为:
L0 → Ln → L1 → Ln - 1 → L2 → Ln - 2 → …
不能只是单纯的改变节点内部的值,而是需要实际的进行节点交换。
示例 1:
输入:head = [1,2,3,4] 输出:[1,4,2,3]
示例 2:
输入:head = [1,2,3,4,5] 输出:[1,5,2,4,3]
提示:
- 链表的长度范围为
[1, 5 * 10^4]
1 <= node.val <= 1000
代码: 快慢指针 + 反转链表
package main
import "fmt"
type ListNode struct {
Val int
Next *ListNode
}
func reorderList(head *ListNode) {
if head == nil || head.Next == nil {
return
}
// 快慢指针找到中间节点
slow, fast := head, head
for fast.Next != nil && fast.Next.Next != nil {
slow = slow.Next
fast = fast.Next.Next
}
// 反转后半部分链表
mid := slow.Next
slow.Next = nil
var prev *ListNode
for mid != nil {
next := mid.Next
mid.Next = prev
prev = mid
mid = next
}
// 合并两个链表
p1, p2 := head, prev
for p2 != nil {
next1 := p1.Next
next2 := p2.Next
p1.Next = p2
p2.Next = next1
p1 = next1
p2 = next2
}
}
func createNodeList(nums []int) *ListNode {
if len(nums) == 0 {
return nil
}
head := &ListNode{Val: nums[0]}
tail := head
for i := 1; i < len(nums); i++ {
tail.Next = &ListNode{Val: nums[i]}
tail = tail.Next
}
return head
}
func (head *ListNode) travel() {
for p := head; p != nil; p = p.Next {
fmt.Print(p.Val)
if p.Next != nil {
fmt.Print("->")
}
}
fmt.Println("<nil>")
}
func main() {
nums := []int{1, 2, 3, 4}
head := createNodeList(nums)
head.travel()
reorderList(head)
head.travel()
nums = []int{1, 2, 3, 4, 5}
head = createNodeList(nums)
head.travel()
reorderList(head)
head.travel()
}
输出:
1->2->3->4<nil>
1->4->2->3<nil>
1->2->3->4->5<nil>
1->5->2->4->3<nil>
🌟 每日一练刷题专栏 🌟
✨ 持续,努力奋斗做强刷题搬运工!
👍 点赞,你的认可是我坚持的动力!
🌟 收藏,你的青睐是我努力的方向!
✎ 评论,你的意见是我进步的财富!
☸ 主页:https://hannyang.blog.csdn.net/
Golang每日一练 专栏 | |
Python每日一练 专栏 | |
C/C++每日一练 专栏 | |
Java每日一练 专栏 |