这是我尝试解决的问题。
public boolean isPalindrome(ListNode head) {
if(head == null || head.next == null)
return true;
ListNode hare = head;
ListNode tort = head;
while(hare!=null && hare.next!=null) {
//System.out.print("Hare "+ hare.val +"tort "+tort.val);
hare = hare.next.next;
tort = tort.next;
}
//Tort is the middle of the list
reverseLL(tort);
ListNode tmp = tort;
printList(tmp);
while(tort!=null) {
if(head.val!=tort.val)
return false;
head = head.next;
tort = tort.next;
continue;
}
return true;
}
private ListNode reverseLL(ListNode head) {
if(head == null || head.next == null) {
return head;
}
ListNode nextElem = head.next;
//System.out.println("Processing "+head.val);
head.next = null;
ListNode rev = reverseLL(nextElem);
nextElem.next = head;
return rev;
}
private void printList(ListNode head){
while(head!=null){
System.out.println("[" +head.val + "]");
head = head.next;
}
}
但是我注意到我无法弄清的东西很奇怪。 tort
当前结束于链接列表的中间。但是,从tort
到最后的反转似乎使侵权行为与链表的其余部分断开了联系。
例如,如果输入为1-> 2-> 3-> 4,侵权最终以3表示,但是从侵权中反转后打印列表仅打印3,即。 3从列表的其余部分断开。
我已经分别测试过reverseLL
,它可以工作,但是当它作为isPalindrome方法的一部分应用时。知道我可能会缺少什么吗?
答案 0 :(得分:1)
在第一个while循环中找到链接列表的中间时,为什么不维护指向tort之前的节点的指针:
ListNode prev_tort = head;
while(hare!=null && hare.next!=null) {
//System.out.print("Hare "+ hare.val +"tort "+tort.val);
hare = hare.next.next;
prev_tort = tort;
tort = tort.next;
}
现在,当元素数为偶数时,野兔将为NULL。因此,对于奇怪的情况,请跳过中间节点:
if(hare != NULL){
tort = tort.next;
prev_tort = prev_tort.next;
}
tort = reverseLL(tort);
prev_tort.next = tort; // only to ensure list is connected
,然后是您的比较代码。
此外,在reverseLL()函数中:
ListNode rev = reverseLL(nextElem);
head.next.next = head;
head.next = NULL;
return rev;
如果我的理解正确,您正在尝试通过倒转下半部分来检查列表是否为回文。在这种情况下,对于输入1-> 2-> 3-> 4,在倒数第二部分倒转后,侵权行为不应该指向4吗?上面的代码就是这样做的(列表将是:1-> 2-> 4-> 3)。
答案 1 :(得分:1)
似乎您想在原位检查回文 ,但是您尚未说明这样的要求,因此我提出了一种更简单的算法:
直到堆栈不为空:
false
返回true
这是带有泛型的Java实现:
public <T> boolean isPalindrome(ListNode<T> head) {
Stack<ListNode<T>> stack = new Stack<>();
ListNode<T> x = head;
while(x != null) {
stack.push(x);
x = x.next;
}
while(!stack.isEmpty()) {
ListNode<T> el = stack.pop();
if(el.t != head.t) return false;
head = head.next;
}
return true;
}
此算法的时间为O(n),空间为O(n)。