1.递归+迭代:反转链表
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
class Solution {
public ListNode reverseList(ListNode head) {
//1.递归解法
// if(head==null) return head;
// if(head.next==null) return head;
// ListNode last=reverseList(head.next);
// head.next.next=head;
// head.next=null;
// return last;
//2.迭代解法
if(head==null) return head;
ListNode pre=null,mid=head,next=null;
while(mid!=null){
next=mid.next;
mid.next=pre;
pre=mid;
mid=next;
}
return pre;
}
}
2.递归+迭代:反转链表2
递归:
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode() {}
* ListNode(int val) { this.val = val; }
* ListNode(int val, ListNode next) { this.val = val; this.next = next; }
* }
*/
class Solution {
ListNode s=null;//后继节点,即从哪开始反转链表的节点的前一个节点
public ListNode reverseBetween(ListNode head, int left, int right) {
//递归
if(head==null || head.next==null) return head;
if(left==1){
return reverseN(head,right);
}
head.next=reverseBetween(head.next,left-1,right-1);
return head;
}
public ListNode reverseN(ListNode head,int n){
if(head==null || head.next==null){
return head;
}
if(n==1){
s=head.next;//找到后继节点
return head;
}
ListNode last=reverseN(head.next,n-1);
head.next.next=head;
head.next=s;
return last;
}
}
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode() {}
* ListNode(int val) { this.val = val; }
* ListNode(int val, ListNode next) { this.val = val; this.next = next; }
* }
*/
class Solution {
public ListNode reverseBetween(ListNode head, int left, int right) {
//迭代
ListNode dummyHead=new ListNode(0);
dummyHead.next=head;
ListNode g=dummyHead,p=head;
//找到反转起始位置以及该位置的前一个节点
int loc=1;
while(loc<left){
p=p.next;
g=g.next;
loc++;
}
//迭代反转链表
for(int i=0;i<right-left;i++){
ListNode temp=p.next;
p.next=p.next.next;//往后面指
temp.next=g.next;//往前面指
g.next=temp;//往后面指
}
return dummyHead.next;
}
}
3.递归:k个一组翻转链表
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode() {}
* ListNode(int val) { this.val = val; }
* ListNode(int val, ListNode next) { this.val = val; this.next = next; }
* }
*/
class Solution {
public ListNode reverseKGroup(ListNode head, int k) {
if(head==null) return head;
ListNode a=head,b=head;
for(int i=0;i<k;i++){
//不足下一组,直接返回头结点,结束反转过程
if(b==null){
return head;
}
b=b.next;
}
ListNode newHead=reverse(a,b);
//递归反转
a.next=reverseKGroup(b,k);
return newHead;
}
public ListNode reverse(ListNode a,ListNode b){
ListNode pre=null,cur=a,next=null;
//不包含b节点,当cur为b节点时跳出while循环
while(cur!=b){
next=cur.next;
cur.next=pre;
pre=cur;
cur=next;
}
return pre;
}
}
4.递归:
解法1:后序遍历,比较左边节点和右边节点的值是否相等
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode() {}
* ListNode(int val) { this.val = val; }
* ListNode(int val, ListNode next) { this.val = val; this.next = next; }
* }
*/
class Solution {
ListNode left;
public boolean isPalindrome(ListNode head) {
left=head;
return traverse(head);
}
public boolean traverse(ListNode right){
if(right==null) return true;
boolean res=traverse(right.next);
//后序遍历
res=res&(left.val==right.val);
left=left.next;
return res;
}
}
解法2:先找到中间节点,然后反转后半部分链表,最后进行比较
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode() {}
* ListNode(int val) { this.val = val; }
* ListNode(int val, ListNode next) { this.val = val; this.next = next; }
* }
*/
class Solution {
public boolean isPalindrome(ListNode head) {
if(head==null) return true;
//反转后半部分链表,然后进行比较,使用双指针
ListNode fast=head,slow=head,left=head;
while(fast!=null && fast.next!=null){
fast=fast.next.next;
slow=slow.next;
}
//要确保slow在中间偏右的节点上
if(fast!=null){
slow=slow.next;
}
//反转slow及slow后面节点这部分的链表
ListNode right=reverse(slow);
//开始比较前半部分链表和反转之后的后半部分链表
while(right!=null){
if(right.val!=left.val){
return false;
}
left=left.next;
right=right.next;
}
return true;
}
public ListNode reverse(ListNode head){
if(head==null){
return head;
}
ListNode pre=null,cur=head,next=null;
while(cur!=null){
next=cur.next;
cur.next=pre;
pre=cur;
cur=next;
}
return pre;
}
}