LeetCode.234 回文链表
题目描述:请判断一个链表是否为回文链表。
回文的意思就是,正着读跟反着读都是一样的。
题目地址:https://leetcode-cn.com/problems/palindrome-linked-list/
解法一:栈
既然是正反进行比较,刚好利用栈的“先进后出”特点,出栈的顺序刚好就是反着读。
出栈节点和原链表节点同时进行比较,有任意一个节点不相同,就不是回文。
时间复杂度:遍历链表O(N),出栈O(N),总计O(2N),去常数项O(N)
空间复杂度:调用系统栈需要额外空间O(N)
class Solution { public boolean isPalindrome(ListNode head) { Stack<Integer> stack = new Stack<>(); ListNode temp = head; while(temp != null){ stack.push(temp.val); temp = temp.next; } while (!stack.isEmpty()){ if (head.val != stack.pop()){ return false; } head = head.next; } return true; } }
方法二:快慢指针+反转链表
快指针一次走2步,慢指针一次走1步,快指针走到null时,慢指针停下,此时慢指针就是中间节点。
将中间节点的下一个节点进行反转,此时如果是一个回文链表,将以中间节点为对称轴。
使用两个新的指针,一个从链表头开始,一个从反转部分的表头开始,走一步比较一次,如果有一个节点不想等就不是回文链表。
class Solution { public boolean isPalindrome(ListNode head) { if(head == null){ return true; } ListNode leftHeadNode = head; ListNode midNode = findMidNode(head); ListNode rightHeadNode = reverseLinkedList(midNode.next); while (leftHeadNode !=null && rightHeadNode !=null){ if (leftHeadNode.val != rightHeadNode.val){ return false; } leftHeadNode = leftHeadNode.next; rightHeadNode = rightHeadNode.next; } return true; } /* 反转链表:返回反转后的链表头节点 */ public ListNode reverseLinkedList(ListNode head){ ListNode temp = null; ListNode cur = head; ListNode prevNode = null; while (cur != null){ temp = cur.next; cur.next = prevNode; prevNode = cur; cur = temp; } return prevNode; } /* 寻找中间节点 */ public ListNode findMidNode(ListNode head){ ListNode fast = head; ListNode low = head; /** * 快指针一次走2步,慢指针一次走1步。 * 快指针走到null时,慢指针停止,此时慢指针就是中间节点。 */ while (fast.next !=null && fast.next.next!=null){ fast = fast.next.next; low = low.next; } return low; } }
学习的博客多用于在笔记中,防止笔记过于臃肿,所以将样例及运行结果放在博客中,后以超链接的形式记录在笔记中,所以有些博文过于单薄。如果有小伙伴遇到问题欢迎评论,看到就会回复,学渣一枚,加油努力。