Leetcode每日刷题:链表&(递归+迭代)

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;
    }
    
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值