@@ -163,221 +163,71 @@ func main() {
163163
164164> 快慢指针最优解,不使用容器结构(stack),O(1):同样的找到中点位置,把右半部分指针回指到中点。接着指针1从L位置,指针2从R位置,往中间遍历。,每步比对,如果有不一样,则不是回文。返回答案之前,把中点右边的指针调整回来
165165
166- ``` Java
167- package class06 ;
168-
169- import java.util.Stack ;
170-
171- public class Code02_IsPalindromeList {
172-
173- public static class Node {
174- public int value;
175- public Node next;
176-
177- public Node (int data ) {
178- this . value = data;
179- }
180- }
181-
182- // need n extra space
183- public static boolean isPalindrome1 (Node head ) {
184- // 依次进栈
185- Stack<Node > stack = new Stack<Node > ();
186- Node cur = head;
187- while (cur != null ) {
188- stack. push(cur);
189- cur = cur. next;
190- }
191- // 每个元素和栈中比较
192- while (head != null ) {
193- if (head. value != stack. pop(). value) {
194- return false ;
195- }
196- head = head. next;
197- }
198- return true ;
199- }
166+ ``` Go
167+ package main
200168
201- // need n/2 extra space
202- // 中点右侧进栈
203- public static boolean isPalindrome2 (Node head ) {
204- if (head == null || head. next == null ) {
205- return true ;
206- }
207- Node right = head. next;
208- Node cur = head;
209- while (cur. next != null && cur. next. next != null ) {
210- right = right. next;
211- cur = cur. next. next;
212- }
213- Stack<Node > stack = new Stack<Node > ();
214- while (right != null ) {
215- stack. push(right);
216- right = right. next;
217- }
218- while (! stack. isEmpty()) {
219- if (head. value != stack. pop(). value) {
220- return false ;
221- }
222- head = head. next;
223- }
224- return true ;
225- }
169+ // 判断一个链表是否是回文链表
170+ // 解法1:遍历链表,把链表放入一个数组中,倒序遍历数组切片,和正序遍历数组切片依次对比,都相等即为回文,实现略
171+ // 解法2:遍历链表,按照快慢指针使慢指针定位到链表的中点位置,依次把慢指针指向的值写入数组切片中,此时数组中保存着链表前一半的元素。
172+ // 且slow的位置是链表的中间位置。按倒序遍历数组切片,与按slow位置顺序遍历链表的元素依次对比,如果都相等,则为回文。实现略
173+ // 解法2比解法1省了一半的空间,解法一空间复杂度O(n),解法2空间复杂度为O(n/2)
174+ // 解法3:不使用额外空间,空间复杂度为O(1)
226175
227- // need O(1) extra space
228- // 不使用容器(stack)的方法
229- public static boolean isPalindrome3 (Node head ) {
230- if (head == null || head. next == null ) {
231- return true ;
232- }
233- // 慢指针
234- Node n1 = head;
235- // 快指针
236- Node n2 = head;
237- while (n2. next != null && n2. next. next != null ) { // find mid node
238- n1 = n1. next; // n1 -> mid
239- n2 = n2. next. next; // n2 -> end
240- }
241- // n1 中点
242-
243-
244- n2 = n1. next; // n2 -> right part first node
245- n1. next = null ; // mid.next -> null
246- Node n3 = null ;
247- // 右半部逆序指向中点
248- while (n2 != null ) { // right part convert
249- n3 = n2. next; // n3 -> save next node
250- n2. next = n1; // next of right node convert
251- n1 = n2; // n1 move
252- n2 = n3; // n2 move
253- }
254- // 引入n3记录最后的位置,之后把右半部再逆序回原来的次序
255- n3 = n1; // n3 -> save last node
256- n2 = head;// n2 -> left first node
257- boolean res = true ;
258- while (n1 != null && n2 != null ) { // check palindrome
259- if (n1. value != n2. value) {
260- res = false ;
261- break ;
262- }
263- n1 = n1. next; // left to mid
264- n2 = n2. next; // right to mid
265- }
266- n1 = n3. next;
267- n3. next = null ;
268- // 把右半部分再逆序回来
269- while (n1 != null ) { // recover list
270- n2 = n1. next;
271- n1. next = n3;
272- n3 = n1;
273- n1 = n2;
274- }
275- return res;
276- }
176+ type Node struct {
177+ Val int
178+ Next *Node
179+ }
277180
278- public static void printLinkedList (Node node ) {
279- System . out. print(" Linked List: " );
280- while (node != null ) {
281- System . out. print(node. value + " " );
282- node = node. next;
283- }
284- System . out. println();
181+ // IsPalindrome 给定链表头节点,判断该链表是不是回文链表。空间复杂度为O(1)
182+ func (head *Node ) IsPalindrome () bool {
183+ // 链表为空,或者链表只有一个节点,是回文结构
184+ if head == nil || head.Next == nil {
185+ return true
285186 }
286-
287- public static void main (String [] args ) {
288-
289- Node head = null ;
290- printLinkedList(head);
291- System . out. print(isPalindrome1(head) + " | " );
292- System . out. print(isPalindrome2(head) + " | " );
293- System . out. println(isPalindrome3(head) + " | " );
294- printLinkedList(head);
295- System . out. println(" =========================" );
296-
297- head = new Node (1 );
298- printLinkedList(head);
299- System . out. print(isPalindrome1(head) + " | " );
300- System . out. print(isPalindrome2(head) + " | " );
301- System . out. println(isPalindrome3(head) + " | " );
302- printLinkedList(head);
303- System . out. println(" =========================" );
304-
305- head = new Node (1 );
306- head. next = new Node (2 );
307- printLinkedList(head);
308- System . out. print(isPalindrome1(head) + " | " );
309- System . out. print(isPalindrome2(head) + " | " );
310- System . out. println(isPalindrome3(head) + " | " );
311- printLinkedList(head);
312- System . out. println(" =========================" );
313-
314- head = new Node (1 );
315- head. next = new Node (1 );
316- printLinkedList(head);
317- System . out. print(isPalindrome1(head) + " | " );
318- System . out. print(isPalindrome2(head) + " | " );
319- System . out. println(isPalindrome3(head) + " | " );
320- printLinkedList(head);
321- System . out. println(" =========================" );
322-
323- head = new Node (1 );
324- head. next = new Node (2 );
325- head. next. next = new Node (3 );
326- printLinkedList(head);
327- System . out. print(isPalindrome1(head) + " | " );
328- System . out. print(isPalindrome2(head) + " | " );
329- System . out. println(isPalindrome3(head) + " | " );
330- printLinkedList(head);
331- System . out. println(" =========================" );
332-
333- head = new Node (1 );
334- head. next = new Node (2 );
335- head. next. next = new Node (1 );
336- printLinkedList(head);
337- System . out. print(isPalindrome1(head) + " | " );
338- System . out. print(isPalindrome2(head) + " | " );
339- System . out. println(isPalindrome3(head) + " | " );
340- printLinkedList(head);
341- System . out. println(" =========================" );
342-
343- head = new Node (1 );
344- head. next = new Node (2 );
345- head. next. next = new Node (3 );
346- head. next. next. next = new Node (1 );
347- printLinkedList(head);
348- System . out. print(isPalindrome1(head) + " | " );
349- System . out. print(isPalindrome2(head) + " | " );
350- System . out. println(isPalindrome3(head) + " | " );
351- printLinkedList(head);
352- System . out. println(" =========================" );
353-
354- head = new Node (1 );
355- head. next = new Node (2 );
356- head. next. next = new Node (2 );
357- head. next. next. next = new Node (1 );
358- printLinkedList(head);
359- System . out. print(isPalindrome1(head) + " | " );
360- System . out. print(isPalindrome2(head) + " | " );
361- System . out. println(isPalindrome3(head) + " | " );
362- printLinkedList(head);
363- System . out. println(" =========================" );
364-
365- head = new Node (1 );
366- head. next = new Node (2 );
367- head. next. next = new Node (3 );
368- head. next. next. next = new Node (2 );
369- head. next. next. next. next = new Node (1 );
370- printLinkedList(head);
371- System . out. print(isPalindrome1(head) + " | " );
372- System . out. print(isPalindrome2(head) + " | " );
373- System . out. println(isPalindrome3(head) + " | " );
374- printLinkedList(head);
375- System . out. println(" =========================" );
376-
187+ // 慢指针
188+ slow := head
189+ // 快指针
190+ fast := head
191+ for fast.Next != nil && fast.Next .Next != nil { // 循环结束,slow停在链表中点位置
192+ slow = slow.Next
193+ fast = fast.Next .Next
377194 }
378195
196+ fast = slow.Next // 快指针回到中点的下一个节点,之后快指针将从每次走两步,变为每次走一步
197+ slow.Next = nil // 从中点截断链表,mid.next -> nil
198+ var tmp *Node
199+ // 对原链表右半部分,进行逆序,逆序后,从原尾节点指向中点
200+ for fast != nil {
201+ tmp = fast.Next // tmp暂时保存fast的下一个节点
202+ fast.Next = slow // 翻转链表指向
203+ slow = fast // slow 移动
204+ fast = tmp // fast 移动
205+ }
206+
207+ // tmp指针记录最后的位置,之后把右半部再逆序回原来的次序
208+ tmp = slow
209+ fast = head
210+ var res = true
211+ for slow != nil && fast != nil { // 原链表的左右部门进行回文对比
212+ if slow.Val != fast.Val {
213+ res = false
214+ break
215+ }
216+ slow = slow.Next // 从原链表头节点,往原链表中间节点移动
217+ fast = fast.Next // 从原链表尾节点,往原链表中间节点移动
218+ }
219+ slow = tmp.Next
220+ tmp.Next = nil
221+ // 把原链表右半部分再逆序回来
222+ for slow != nil {
223+ fast = slow.Next
224+ slow.Next = tmp
225+ tmp = slow
226+ slow = fast
227+ }
228+ // 返回回文的判断结果 true
229+ return res
379230}
380-
381231```
382232
383233### 1.1.3 面试题二:按值划分单链表
0 commit comments