day19

 第一题

24. 两两交换链表中的节点

解法一:

        递归,该方法详见与好多天以后

解法二:

        循环迭代

本题我们这里采用循环迭代的方法来解决,下面我们采用画图来详细分析,下图所示,我们需要将上面的链表按照一定的规则变化为下面的链表

        首先,我们定义新的头结点,其次我们发现当两个节点之间首先进行交换的时候会和这两个几点相邻的两个节点(共四个节点有关),所以我们定义这四个节点方便我们进行位置交换;

        此时我们要注意细节,当原链表为空链表或者只有一个节点的链表时,我们不需要进行位置转化直接返回原链表;

        

        如上图所示,进行节点交换;如下图所示,进行指针修改,进行下一轮位置交换:

        但是我们要注意循环的临界值:

一:

        在交换节点前,cur节点和next节点不能为空;

二:

        在指针修改之后,cur和next不能为空的情况下,才能进行指针移动;即这种情况:

综上所述,代码如下:

class Solution {
    public ListNode swapPairs(ListNode head) {
        if(head == null || head.next == null) return head;
        //如果所给的链表为空链表或只有一个节点的链表,直接返回链表
        ListNode newHead = new ListNode(0);
        newHead.next = head;

        ListNode prev = newHead,cur = prev.next,next = cur.next,nenext = next.next;
        while(cur != null && next != null){
            //交换节点
            prev.next = next;
            next.next = cur;
            cur.next = nenext;
            //修改指针
            prev = cur;
            cur = nenext;
            if(cur != null) next = cur.next;
            if(next != null) nenext = next.next;
        }
        return newHead.next;
    }
}

第二题 

143. 重排链表

        如下图所示,题目要求将原始链表改为下面的链表;

        我们本题采用模拟的解法:

步骤一:

        通过快慢指针找到整个链表的中间结点;

判断结束条件:当快指针或快指针的下一个节点为空节点时,慢指针所指的节点就是链表的中间节点;

步骤二:

情况一

        判断从慢节点(中间结点)的下一个节点开始的后半部分链表进行逆序,得到一个逆序链表;

        分析如下:

        当原始链表的节点为奇数的时候:

        一切顺利

        当原始链表的节点为偶数的时候:

        也没有问题;

情况二:

        我们将中间结点开始,后面的链表进行逆序;

        当原始链表的节点为奇数的时候:

        当原始链表的节点为偶数的时候:

        也没有问题,我们本题采用情况一,一中间结点后面的节点为新链表的开始,并将该链表逆序;

        此时将我们的后半部分链表进行逆序;

        

        首先cue节点指向null节点,其次head2节点指向cur节点,当头插完成后,cur节点向后移动一位,直到完成整个链表的头插操作

步骤三:

        合并两个链表;

判断条件:因为前半部分的链表的长度较长,方合并到前一个链表当前节点的后一个节点为空的时候,两个链表已经合并结束;

        综上所述,代码如下:

class Solution {
    public void reorderList(ListNode head) {
        //边界情况
        if(head == null || head.next == null || head.next.next == null){
            return ;
        }
        //1、早知道到链表的中间结点-使用快慢双指针
        ListNode slow = head,fast = head;
        while (fast != null && fast.next != null){
            slow = slow.next;
            fast = fast.next.next;
        }
        //2、把slow后面的部分逆序
        ListNode head2 = new ListNode(0);
        ListNode cur = slow.next;
        slow.next = null;//把两个链表分离
        while(cur != null){
            ListNode next = cur.next;
            cur.next = head2.next;
            head2.next =cur;
            cur = next; 
        }
        //合并两个链表-双指针
        ListNode cur1 = head,cur2 = head2.next;
        ListNode ret = new ListNode(0);
        ListNode prev = ret;
        while(cur1 != null){
            prev.next = cur1;
            prev = cur1;
            cur1 = cur1.next;

            if(cur2 != null){
                prev.next = cur2;
                prev = cur2;
                cur2 = cur2.next;
            }
        }
    }
}

 ps:本次的内容就到这里,如果对你有所帮助的话,就请一键三连哦!!!

  • 8
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值