206反转链表
双指针解法,如下图,定义三个节点,然后依次先使temp=curr.next,然后再把curr指向前一个结点,然后再将prev前进一个结点指向curr结点,最后使curr前进一个节点指向temp节点,循环至curr等于null。
class Solution {
public ListNode reverseList(ListNode head) {
if(head==null)return null;
ListNode prev=null;
ListNode curr=head;
while(curr!=null){
ListNode temp=curr.next;
curr.next=prev;
prev=curr;
curr=temp;
}
return prev;
}
}
234回文链表
第一种解法,将链表中的值全部存储到一个动态数组中去,然后使用双指针,一个指向数组的头,一个指向数组的尾,循环遍历看看他们指向的节点的值是不是始终相等直至头指针超过尾指针。
class Solution {
public boolean isPalindrome(ListNode head) {
ArrayList <Integer> list=new ArrayList<Integer>();
ListNode p=head;
while(p!=null){
list.add(p.val);
p=p.next;
}
int front=0;
int back=list.size()-1;
while(front<back){
if(list.get(front)!=list.get(back))return false;
front++;
back--;
}
return true;
}
}
第二种解法,还是利用双指针,当链表节点为偶数个时(如下面第一个图),快指针走两步,慢指针走一步,快指针走完后指针最后指向的情况为下面第二张图所示,此时我们将fast指针重新指向head节点,然后将slow指向的节点及它后面的节点形成的链表反转,然后再循环遍历使fast和slow每次向前移一步,每次都比较一下它们的值是不是相等。
当链表的节点是奇数个时,如下面第一个图,快指针走两步,慢指针走一步,快指针走完后指针的指向情况如下面第二张图所示,此时我们还需要将slow的节点再往前走一步然后再反转slow节点及它之后的节点形成的链表,因此要加一个判断条件当快指针fast不为空的时候slow节点再往前走一步。
class Solution {
public boolean isPalindrome(ListNode head) {
ListNode fast=head;
ListNode slow=head;
while(fast!=null&&fast.next!=null){
fast=fast.next.next;
slow=slow.next;
}
if(fast!=null){
slow=slow.next;
}
slow=reverse(slow);
fast=head;
while(slow!=null){
/*使slow!=null作为循环结束条件的原因可以从上面偶数个节点或者
奇数个节点的图看出,当为偶数个节点时,slow指向的及slow后面的节点的
数量等于fast指向的及fast后面的节点的数量,当为奇数个节点时,slow指
向的及后面的节点的数量比fast指向的及fast后面的节点的数量少一个,
但是其实fast后面最后的那个节点是回文中公共的部分。
*/
if(fast.val!=slow.val)return false;
fast=fast.next;
slow=slow.next;
}
return true;
}
public ListNode reverse(ListNode head){
ListNode prev=null;
ListNode curr=head;
while(curr!=null){
ListNode temp=curr.next;
curr.next=prev;
prev=curr;
curr=temp;
}
return prev;
}
}