「这是我参与2022首次更文挑战的第12天,活动详情查看:2022首次更文挑战」
题目
给你单链表的头指针 head 和两个整数 left 和 right ,其中 left <= right 。请你反转从位置 left 到位置 right 的链表节点,返回 反转后的链表 。
示例 1:
输入:head = [1,2,3,4,5], left = 2, right = 4
输出:[1,4,3,2,5]
示例 2:
输入:head = [5], left = 1, right = 1
输出:[5]
提示:
- 链表中节点数目为
n 1 <= n <= 500-500 <= Node.val <= 5001 <= left <= right <= n
进阶: 你可以使用一趟扫描完成反转吗?
解题
解题一:截取链表
思路
找到对应需要反转的链表,截取下来之后使用反转方法进行反转
代码
/**
* 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 result = head;
if (head == null || head.next == null || left == right) {
// null 或者 只有一个元素 或者 反转节点一样,返回链表本身
return head;
}
// 截取反转链表左边
ListNode leftNode = null;
ListNode tempNode = head;
// 寻找到指定的节点,然后进行反转
for (int i = 0; i < left - 1; i++) {
// 将需要反转的链表截取出来
leftNode = head;
tempNode = head.next;
head = head.next;
}
// 截取反转链表右边
for (int i = 0; i < (right - left); i++) {
head = head.next;
}
ListNode rightNode = head.next;
head.next = null;
// 链表反转
tempNode = reverseList(tempNode);
// 链表驳接
if (leftNode != null) {
leftNode.next = tempNode;
} else{
result = tempNode;
}
while (tempNode.next != null) {
tempNode = tempNode.next;
}
tempNode.next = rightNode;
return result;
}
public static ListNode reverseList(ListNode head) {
// 空链表 和 只有一个节点的链表 返回原本的链表
if (head == null || head.next == null) {
return head;
}
ListNode tempHead = head.next;
ListNode tail = tempHead.next;
head.next = null;
tempHead.next = head;
head = tempHead;
while (tail != null) {
tempHead = tail;
tail = tail.next;
tempHead.next = head;
head = tempHead;
}
return head;
}
}
总结
- 执行耗时:0 ms,击败了 100.00% 的 Java 用户
- 内存消耗:36 MB,击败了 55.88% 的 Java 用户
解题二:头插法
思路
将需要反转的节点头插进入
代码
/**
* 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 result = head;
if (head == null || head.next == null || left == right) {
// null 或者 只有一个元素 或者 反转节点一样,返回链表本身
return head;
}
// 截取反转链表左边
ListNode leftNode = null;
ListNode tempNode = head;
// 寻找到指定的节点,然后进行插入
for (int i = 0; i < left - 1; i++) {
// 将需要反转的链表截取出来
leftNode = head;
tempNode = head.next;
head = head.next;
}
ListNode nextHead = tempNode.next;
// 插入 leftNode 和 tempNode 之间,达到反转效果
for (int i = 0; i < (right - left); i++) {
tempNode.next = nextHead.next;
if (leftNode == null) {
nextHead.next = result;
result = nextHead;
} else {
nextHead.next = leftNode.next;
leftNode.next = nextHead;
}
nextHead = tempNode.next;
}
return result;
}
}
总结
- 执行耗时:0 ms,击败了 100.00% 的 Java 用户
- 内存消耗:35.8 MB,击败了 81.81% 的 Java 用户