From 1505b4cc21dfc6ef738e148ddb946cd7413788df Mon Sep 17 00:00:00 2001 From: gameloader Date: Sat, 23 Mar 2024 16:16:19 +0800 Subject: [PATCH] leetcode update --- content/posts/leetcode.md | 111 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 111 insertions(+) diff --git a/content/posts/leetcode.md b/content/posts/leetcode.md index 9fdd750..320d1b6 100644 --- a/content/posts/leetcode.md +++ b/content/posts/leetcode.md @@ -1861,3 +1861,114 @@ func reverse(head *ListNode) *ListNode{ return prev } ``` + +## day26 2024-03-23 + +### 143. Reorder + +You are given the head of a singly linked-list. The list can be represented as: + +> L0 → L1 → … → Ln - 1 → Ln + +Reorder the list to be on the following form: + +> L0 → Ln → L1 → Ln - 1 → L2 → Ln - 2 → … + +You may not modify the values in the list's nodes. Only nodes themselves may be changed. + +![0323xGTn0liJdHDU](https://testingcf.jsdelivr.net/gh/game-loader/picbase@master/uPic/0323xGTn0liJdHDU.png) + +### 题解 + +拿到本题, 首先想到的是将链表中的全部数据保存到数组中, 然后通过同时从前后遍历数组并且给原来的链表赋值的方式, 即可快速解决本题, 如果不使用额外的空间, 可以使用快慢指针, 找到链表的中间节点, 从中间节点开始将链表的后半部分反向, 用两个指针分别从前半部分的开始和后半部分的末尾开始遍历, 并构造新链表即可. 也可以构造一个栈, 将链表的后半部分放入栈中, 然后从顶端一边出栈一边构造新链表即可. 题目中要求不能直接修改节点的值, 因此采用第三种思路. + +### 代码 + +```go +/** + * Definition for singly-linked list. + * type ListNode struct { + * Val int + * Next *ListNode + * } + */ +func reorderList(head *ListNode) { + slow := head + fast := head + if head.Next != nil{ + fast = head.Next + } + stack := []*ListNode{} + for fast != nil && fast.Next != nil{ + fast = fast.Next.Next + slow = slow.Next + } + odd := false + if fast == nil{ + odd = true + } + // construct pointer stack + slow = slow.Next + for slow != nil{ + stack = append(stack, slow) + slow = slow.Next + } + slow = head + temp := head.Next + temp2 := head + flag := 1 + for i:=len(stack)-1;i>=0;i--{ + if flag == 1{ + stack[i].Next = nil + slow.Next = stack[i] + slow = slow.Next + flag = 0 + }else{ + temp2 = temp.Next + temp.Next = nil + slow.Next = temp + slow = slow.Next + flag = 1 + i++ + temp = temp2 + } + } + if odd{ + temp.Next = nil + slow.Next = temp + } + return +} + + +``` + +### 总结 + +查看最快速度代码, 使用了一个数组先将链表的全部节点指针留一个间隔存放在数组中, 然后再逆序遍历数组将后半节点的指针逆序插入前面留出的空格中, 最后从头遍历数组, 连接整个链表即可. 这样写得出的代码比较简洁. + +```go +/** + * Definition for singly-linked list. + * type ListNode struct { + * Val int + * Next *ListNode + * } + */ +func reorderList(head *ListNode) { + list := []*ListNode{} + + for node := head; node != nil; node = node.Next { + list = append(list, node) + list = append(list, nil) + } + + for i := 1; i < len(list) - i - 1; i += 2 { + list[i] = list[len(list) - i - 1] + } + + for i := 0; list[i] != nil; i++ { + list[i].Next = list[i + 1] + } +} +```