234.回文链表
请判断一个链表是否为回文链表。
示例1
输入: 1->2
输出: false
示例2
输入: 1->2->2->1
输出: true
进阶:
你能否用 O(n) 时间复杂度和 O(1) 空间复杂度解决此题?
回文:从左往右和左右往左,是相同的。
solution1:
/**
* 将数据放入数组中,利用数组的有序判断首尾节点是否相等
*
* @param head
* @return
*/
public boolean isPalindrome1(ListNode head) {
List<Integer> valList = new ArrayList<>();
ListNode cur = head;
while (cur != null) {
valList.add(cur.val);
cur = cur.next;
}
int left = 0, right = valList.size() - 1;
while (left < right) {
if (!Objects.equals(valList.get(left++), valList.get(right--))){
return false;
}
}
return true;
}
执行结果:通过
执行用时:4 ms, 在所有 Java 提交中击败了28.12%的用户
内存消耗:42.2 MB, 在所有 Java 提交中击败了42.04%的用户
时间复杂度:O(n)
空间复杂度:O(n),List开销。
solution2:
/**
* 快慢指针将链表拆为2个子链表,并反转第二个子链表
* 顺序比较两个链表的值
*
* @param head
* @return
*/
public boolean isPalindrome2(ListNode head) {
if (head == null || head.next == null) {
return true;
}
// 定义快慢指针 slow每次走一步,fast每次走两步
ListNode slow = head;
ListNode fast = head;
while (fast.next != null && fast.next.next != null){
slow = slow.next;
fast = fast.next.next;
}
// slow指针前(包含slow)为链表1,slow指针后(不包含slow)为链表2,即secondHead=slow.next
ListNode secondHead = slow.next;
// 反转链表
secondHead = reverseList(secondHead);
while (secondHead != null) {
if (!Objects.equals(head.val, secondHead.val)) {
return false;
}
head = head.next;
secondHead = secondHead.next;
}
return true;
}
/**
* 反转链表
*
* @param head
* @return
*/
public ListNode reverseList(ListNode head) {
if (head == null) {
return null;
}
if (head.next == null) {
return head;
}
ListNode pre = null;
while (head != null) {
ListNode next = head.next;
head.next = pre;
pre = head;
head = next;
}
return pre;
}
执行结果:通过
执行用时:2 ms, 在所有 Java 提交中击败了54.30%的用户
内存消耗:41.9 MB, 在所有 Java 提交中击败了44.41%的用户
时间复杂度:O(n)
空间复杂度:O(1),满足进阶要求。