题目:
请判断一个链表是否为回文链表。
示例 1:
输入: 1->2
输出: false
示例 2:
输入: 1->2->2->1
输出: true
进阶:
你能否用 O(n) 时间复杂度和 O(1) 空间复杂度解决此题?
进阶思考:反转再比较,反转用头插法。
代码:
package leetCode;
import java.util.concurrent.SynchronousQueue;
import leetCode.Nineteen.ListNode;
/**
* 2018.7.23
* 回文链表
* @author dhc
*
*/
public class TwoHundredAndThirtyFour {
public class ListNode {
int val;
ListNode next;
ListNode(int x) {
val = x;
}
}
//思路:可以先遍历一下链表求长度,并且保存链表值,然后第二遍遍历的时候从链表的中间开始判断,即判断对应位置的数
//但是空间复杂度为O(n), 2ms
//看了一下前面大佬的答案,大概都用到了对链表的反转,一种是反转后半部分链表在比较,一种是直接反转整个链表,如果反转
//链表时用的是递归的话,空间复杂度为O(n),如果用的是头插法的话,空间复杂度就是O(1)
public static boolean isPalindrome(ListNode head) {
if(head == null || head.next == null) {
return true;
}
boolean flag = true;
ListNode tem = head;
int length = 0;
//求链表长度
while(tem != null) {
length++;
tem = tem.next;
}
int[] val = new int[length/2];
tem = head;
int index = 0;
int index1 = 0;
boolean flag1 = true;
while(tem!=null) {
//先把前面部分的数存到数组 中
if(index1 < length/2) {
val[index1++] = tem.val;
tem = tem.next;
index = index1;
}else {
//从后面部分开始依次和前面对应的数比较,这里需要区分一下长度为奇偶的不同
if(length%2 == 0) {
if(val[--index] != tem.val) {
flag = false;
break;
}
tem = tem.next;
}else {
if(flag1) {
flag1 = false;
tem = tem.next;
}else {
if(val[--index] != tem.val) {
flag = false;
break;
}
tem = tem.next;
}
}
}
}
return flag;
}
public static void main(String[] args) {
ListNode head = new TwoHundredAndThirtyFour().new ListNode(1);
ListNode node1 = new TwoHundredAndThirtyFour().new ListNode(0);
ListNode node2 = new TwoHundredAndThirtyFour().new ListNode(1);
ListNode node3 = new TwoHundredAndThirtyFour().new ListNode(2);
ListNode node4 = new TwoHundredAndThirtyFour().new ListNode(2);
ListNode node5 = new TwoHundredAndThirtyFour().new ListNode(1);
head.next = node1;
node1.next = node2;
/*node2.next = node3;
node3.next = node4;
node4.next = node5;*/
System.out.println(isPalindrome(head));
}
}