题目来源: JZ24 反转链表
题目描述:
- 描述: 给定一个单链表的头结点pHead(该头节点是有值的,比如在下图,它的val是1),长度为n,反转该链表后,返回新链表的表头。 数据范围: 0≤n≤1000
- 要求: 空间复杂度 O(1),时间复杂度 O(n)
- 如当输入链表{1,2,3}时,经反转后,原链表变为{3,2,1},所以对应的输出为{3,2,1}。以上转换过程如下图所示:
- 如当输入链表{1,2,3}时,经反转后,原链表变为{3,2,1},所以对应的输出为{3,2,1}。以上转换过程如下图所示:
示例1:
输入:{1,2,3}
返回值:{3,2,1}
示例2:
输入:{}
输出:{}
说明:空链表则输出空
思路1:数组
- 1.循环遍历,将链表中的元素存储到list中
- 2.反向输出list
具体实现1:
/*
public class ListNode {
int val;
ListNode next = null;
ListNode(int val) {
this.val = val;
}
}*/
import java.util.*;
public class Solution {
public ListNode ReverseList(ListNode head) {
if(head == null){
return null;
}
ArrayList<Integer> list = new ArrayList<>();
while(head!=null){
list.add(head.val);
head = head.next;
}
ListNode newHead = new ListNode(list.get(list.size()-1));
ListNode cur = newHead;
for(int i=list.size()-2;i>=0;i--){
cur.next = new ListNode(list.get(i));
cur = cur.next;
}
return newHead;
}
}
- 复杂度分析:
- 时间复杂度O(n):遍历链表
- 空间复杂度O(n):额外存储数组占用空间
- 问题:
- 空间复杂度不满足题意(但是在牛客提交是没问题的)
思路2:迭代
- 如何理解
反转链表,其实就是使得每个元素指向后的指针变成指向前,而想要达到这个目的,我们可以通过遍历链表,将遇到的节点的指针逆向即可. - 如何
将指针逆向,其实就是断开节点向后的指针,改成向前就可以了(发现又绕回来了,其实就是一个意思,很好理解的)cur.next = pre
- 具体做法:
- 1.对于空链表,进行优先处理,因为空链表时无需进行反转的
- 2.使用
双指针,一个是当前结点的指针,另一个是前面结点的指针 - 3.遍历整个链表的时候,达到每个节点时,进行的操作是:断开当前结点与后面结点的指针,并使用一个临时量对后面的结点进行记录,然后当前结点指向前面的结点,这就完成了指针的逆转
- 4.然后再将双指针进行移动,对下一个节点进行3的操作
- 图示:
具体实现1:
public class Solution {
public ListNode ReverseList(ListNode head) {
//处理空链表
if(head == null)
return null;
ListNode cur = head;
ListNode pre = null;
while(cur != null){
//断开链表,要记录后续一个
ListNode temp = cur.next;
//当前的next指向前一个
cur.next = pre;
//前一个更新为当前
pre = cur;
//当前更新为刚刚记录的后一个
cur = temp;
}
return pre;
}
}
- 复杂度分析:
- 时间复杂度O(n):遍历链表
- 空间复杂度O(1):常数级变量,无额外辅助空间使用
开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 1 天,点击查看活动详情”