Skip to content

Commit 640ae13

Browse files
committed
palindrome list
1 parent 9c0c0b1 commit 640ae13

File tree

1 file changed

+58
-208
lines changed

1 file changed

+58
-208
lines changed

06-链表相关高频题总结.md

Lines changed: 58 additions & 208 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)