leetcode刷题-链表反转206、92、25、234

本文介绍了通过跟随labuladong的算法小抄进行的四道链表反转题目实践,包括全链表反转、反转固定位置片段、K个一组反转及判断回文链表。解题策略涉及单指针、双指针和递归等方法,重点在于链表反转的技巧和边界条件处理。
摘要由CSDN通过智能技术生成

跟着labuladong算法小抄进行刷题:
请添加图片描述

1、概述

这三个部分共有四道题,在力扣的题号分别是206、92、25、234。
这四道题都用到了部分链表的反转,下面是一个节点的反转思路:
(假设pre初始值是null的情况,也即从链表的表头开始反转,其他情况小作修改即可)
使用到了三个指针,分别是cur、pre、next这三个指针分别代指了当前需要反转的节点、该节点的前一节点、后一节点。
请添加图片描述

2、题目206

请添加图片描述
以题目206来说,这个题目就是遍历从链表头节点开始,每一个节点都进行反转。

3、题目92

请添加图片描述
题目92中,需要反转固定位置的链表片段,则可以借鉴快慢指针的思路,定义两个指针,差距即为right-left-1,当慢指针移动到left节点时,就开始反转节点,直到反转到right节点为止。设置快慢指针有助于反转部分的链表的前后连接。

##4、 题目25

请添加图片描述
题目25,K个一组进行反转,难点在于使用递归的思想,代码其实比较好理解,参考了labuladong的解答:
(这个题目使用迭代的思想也可以,此处不再多叙述)

//反转部分链表节点
 //设定特定长度
 //将不同长度连起来
    public ListNode reverseKGroup(ListNode head, int k) {
        //获得长度k
        if(head==null) return null;
        ListNode a=head;
        ListNode b=head;
        //判断长度是不是够
        for(int i=0;i<k;i++)
        {
            if(b==null)
            {
                return head;
            }
            b=b.next;
        }
        //经过for循环获得剩余长度不小于k个
        //首先得到交换后的链表的头节点,然后进行连接
        ListNode newHead=reverse(a,b);
        //注意  由于b进行移动的时候是从0开始的,所以相当于是移动了k下,是一个左开右闭的区间
        a.next=reverseKGroup(b,k);
        return newHead;
    }
    public ListNode reverse(ListNode a,ListNode b)
    {
        //将链表的头节点和尾结点传递到函数中
        //进行反转
        ListNode pre=null;
        ListNode cur=a,next=a;
        while(cur!=b)
        {
            next=cur.next;
            cur.next=pre;
            pre=cur;
            cur=next;
        }
        return pre;
    }

5、题目234

请添加图片描述

题目234,由于它前面全是链表反转的题目,所以这个题我也打算使用链表反转的思想来做。@TOC
(这个思路时间复杂度不是最优)
利用回文的定义,将前半部分进行反转,然后再和后半部分对比。

  public boolean isPalindrome(ListNode head) {
        //首先获得长度
        ListNode p=head;
        int len=0;
        while(p!=null)
        {
            len++;
            p=p.next;
        }
        //回文有两种  奇数回文和偶数回文
        if(len%2==0) 
        {
            //说明是偶数回文
            p=head;
            //首先获得后半部分的链表
            for(int j=0;j<len/2;j++)
            {
                p=p.next;
            }
            ListNode newH=reverse(head,len/2);
            //此处如果是使用p==newH来判断  结果是不对的???为啥
            while(p!=null)
            {
                if(p.val!=newH.val) return false; 
                p=p.next;
                newH=newH.next;
            }
            return true;
        }
        else
        {
            //说明是奇数回文
            p=head;
            //首先获得后半部分的链表
            for(int j=0;j<=len/2;j++)
            {
                p=p.next;
            }
            ListNode newH=reverse(head,len/2);
            while(p!=null)
            {
                if(p.val!=newH.val) return false; 
                p=p.next;
                newH=newH.next;
            }            
            return true;
        }
    }
    public ListNode reverse(ListNode a,int k){
        ListNode cur=a;
        ListNode pre=null;
        ListNode next=a;
        for(int i=0;i<k;i++)
        {
            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、付费专栏及课程。

余额充值