力扣24 | 两两交换链表中的节点(非递归算法)


来源:         ~~~~~~~        力扣(leetcode)
题目链接:两两交换链表中的节点

1、题目

给你一个链表,两两交换其中相邻的节点,并返回交换后链表的头节点。
你必须在不修改节点内部的值的情况下完成本题(即,只能进行节点交换)。




示例1:

在这里插入图片描述

输入:head = [1,2,3,4]
输出:[2,1,4,3]

示例2:

输入:head = []
输出:[]

示例3:

输入:head = [1]
输出:[1]

2、分析

I.交换的两个节点前后都无节点

在这里插入图片描述


像这种情况,我们只需把两个节点交换一下就可以了.

交换后:

在这里插入图片描述



II.交换的两个节点前无节点,后有节点

在这里插入图片描述

第一步:left.next = rightNext;

在这里插入图片描述

第二步:right.next = left;

在这里插入图片描述


最终效果:

在这里插入图片描述



III.交换的两个节点前有节点,后无节点


在这里插入图片描述

第一步:    ~~   leftPrev.next = right;
在这里插入图片描述



第二步:    ~~   right.next = left;
在这里插入图片描述



第三步:    ~~   left.next = null



最终效果:
在这里插入图片描述



IIII.交换的两个节点前有节点,后有节点

在这里插入图片描述



第一步:leftPrev.next = right
在这里插入图片描述




第二步:right.next = left
在这里插入图片描述

第三步:left.next = rightPrev
在这里插入图片描述




最终效果:
在这里插入图片描述

3、思路

在这里插入图片描述

  1. 我们先处理链表为空 和只有一个节点的情况
1.当head == null时,      我们直接return null
2.当head.next == null时, 我们直接return head
  1. 定义变量,设置循环条件
 因为下面的情况要用到 leftPrev, left , right,  rightNext指针
 所以我们先定义四个指针,并初始化

ListNode leftPrev = null;				初始化为空
ListNode left = head;					初始化指向表头
ListNode right = left.next;				初始化为left.next
ListNode rightNext = right.next;		初始化为right.next

循环条件:
我们要遍历链表,只有当left != null && right != null 时我们才要交换两个节点
即:			while(left != null && right != null)	

下面处理四种情况:
  1. 处理要交换的两个节点,前后没有节点的情况
此时: leftPrev == null && rightNext == null;
进行下面的操作:

right.next = left;		右边节点的next指向left
left.next = null;		左边节点的next指向null
head = right;			更新一下头指针
left = null;			更新left
right = null;			更新right

注意:

这种情况下,不需要更新leftPrev和rightNext了

因为链表已经交换完了,下次不用交换了,只需把left和right都置为null即可



  1. 处理要交换的两个节点,前无节点,后有节点的情况
此时: leftPrev == null && rightNext != null;
进行下面的操作:

right.next = left;			右边节点的next指向left
left.next = rightNext;		左边节点的next指向rightNext
head = right;				更新头指针
leftPrev = left				更新leftPrev
left = rightNext;			更新left

此时rightNext.next可能为null,要进行判断
if (rightNext.next == null) {			rightNext.next 为空的情况
	right = null;
	rightNext = null;
} else {								rightNext.next 不为空的情况
    right = rightNext.next;
    rightNext = right.next;
}

  1. 处理要交换的两个节点,前有节点,后无节点的情况
此时: leftPrev != null && rightNext == null;
进行下面的操作:

leftPrev.next = right;		
right.next = left;				
left.next = null;				
leftPrev = left;				更新leftPrev
left = null;					更新left
right = null;					更新right
rightNext = null;				更新rightNext
  1. 处理要交换的两个节点,前有节点,后有节点的情况
此时: leftPrev != null && rightNext != null;
进行下面的操作:

leftPrev.next = right;		
right.next = left;				
left.next = rightNext;				
leftPrev = left;							更新leftPrev
left = rightNext;							更新left

此时rightNext.next可能为null,要进行判断
if (rightNext.next == null) {			rightNext.next 为空的情况
	right = null;						把right和rightNext都置为空
	rightNext = null;
} else {								rightNext.next 不为空的情况
    right = rightNext.next;	
    rightNext = right.next;
}

4、代码

class Solution {
    public ListNode swapPairs(ListNode head) {
        if (head == null) {
            return null;
        }
        if (head.next == null) {
            return head;
        }
        ListNode leftPrev = null;               //初始化为空
        ListNode left = head;                   //初始化指向表头
        ListNode right = left.next;             //初始化为left.next
        ListNode rightNext = right.next;        //初始化为right.next

        //当left != null && right != null时,交换节点
        while (left != null && right != null) {

            if (leftPrev == null && rightNext == null) {
                right.next = left;              //右边节点的next指向left
                left.next = null;               //左边节点的next指向null
                head = right;                   //更新一下头指针
                left = null;                    //更新left
                right = null;                   //更新right

            } else if (leftPrev == null && rightNext != null) {
                right.next = left;              //右边节点的next指向left
                left.next = rightNext;          //左边节点的next指向rightNext
                head = right;                   //更新头指针
                leftPrev = left;                //更新leftPrev
                left = rightNext;               //更新left

                //此时rightNext.next可能为null,要进行判断
                if (rightNext.next == null) {   //rightNext.next 为空的情况
                    right = null;
                    rightNext = null;
                } else {                        //rightNext.next 不为空的情况
                    right = left.next;
                    rightNext = right.next;
                }

            } else if (leftPrev != null && rightNext == null) {
                leftPrev.next = right;
                right.next = left;
                left.next = null;
                leftPrev = left;                //更新leftPrev
                left = null;                    //更新left
                right = null;                   //更新right
                rightNext = null;               //更新rightNext

            } else {
                leftPrev.next = right;
                right.next = left;
                left.next = rightNext;
                leftPrev = left;                //更新leftPrev
                left = rightNext;               //更新left

                //此时rightNext.next可能为null,要进行判断
                if (rightNext.next == null) {   //rightNext.next 为空的情况
                    right = null;               //把right和rightNext都置为空
                    rightNext = null;
                } else {                        //rightNext.next 不为空的情况
                    right = rightNext.next;
                    rightNext = right.next;
                }

            }
        }
        return head;
    }
}

5、代码运行结果

在这里插入图片描述





请老爷们给个赞吧
在这里插入图片描述

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值