文章目录
来源:
~~~~~~~
力扣(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.当head == null时, 我们直接return null
2.当head.next == null时, 我们直接return head
- 定义变量,设置循环条件
因为下面的情况要用到 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)
下面处理四种情况:
- 处理要交换的两个节点,前后没有节点的情况
此时: 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即可
- 处理要交换的两个节点,前无节点,后有节点的情况
此时: 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;
}
- 处理要交换的两个节点,前有节点,后无节点的情况
此时: 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
- 处理要交换的两个节点,前有节点,后有节点的情况
此时: 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、代码运行结果
请老爷们给个赞吧