var reverseList = function(head) {
if (head === null || head.next === null)
return head;
let cur = head;
let pre = null;
while (cur !== null) {
let temp = cur.next;
cur.next = pre;
pre = cur;
cur = temp;
}
return pre;
};
/**
* Definition for singly-linked list.
* type ListNode struct {
* Val int
* Next *ListNode
* }
*/
func reverseList(head *ListNode) *ListNode {
// 1. var newHead = new(ListNode)
// 2. var newHead *ListNode = nil
// 1 和 2 的区别:
// 2 是*ListNode 的零值
// 1 等价于 var newHead = &ListNode{Val:0, Next:nil}
// 本题 newHead 初始值是反转之后的尾节点, 所以需要 nil
var pre *ListNode = nil
cur := head
for cur != nil {
next := cur.Next
cur.Next = pre
pre = cur
cur = next
}
return pre
}
class Solution:
def reverseList(self, head: ListNode) -> ListNode:
if not head or not head.next:
return head
last=self.reverseList(head.next)
head.next.next=head
head.next=None
return last
class Solution:
def reverseList(self, head: ListNode) -> ListNode:
if not head or not head.next:
return head
pre = None # 虚拟节点
cur = head
while cur:
tmp = cur.next
cur.next = pre
pre = cur
cur = tmp
return pre
原地反转 时间复杂度O(n) 空间复杂度O(1)
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution:
def reverseList(self, head: ListNode) -> ListNode:
if not head or not head.next:
return head
cur = head
pre = None
while cur:
tmp = cur.next
cur.next = pre
pre = cur
cur = tmp
return pre
class Solution {
public ListNode reverseList(ListNode head) {
ListNode pre = null;
ListNode cur = head;
while(cur!=null){
ListNode next = cur.next;
cur.next = pre;
pre = cur;
cur = next;
}
return pre;
}
}
};
class Solution {
public:
//双指针法
ListNode* reverseList(ListNode* head) {
if(head NULL) return head;
if(head -> next NULL) return head;
ListNode * cur = head -> next;
ListNode * pre = head;
pre -> next = NULL;
while( cur != NULL){
ListNode * temp = cur -> next;
cur -> next = pre;
pre = cur;
cur = temp;
}
return pre;
}
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution:
def reverseList(self, head: ListNode) -> ListNode:
if not head or not head.next:
return head
prev = None
cur = head
while cur:
nxt = cur.next
cur.next = prev
prev = cur
cur = nxt
return prev
共以下 75 个回答
“`java
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
class Solution {
public ListNode reverseList(ListNode head) {
ListNode cur = head,pre=null;
while(cur!=null){
ListNode tmp = cur.next;
cur.next = pre;
pre = cur;
cur = tmp;
}
return pre;
}
}
加油
时间:O(n)
空间:O(1)
//原地反转
class Solution {
public ListNode reverseList(ListNode head) {
//原地反转
if(head null || head.next null){
return head;
}
if(head.next.next null){
int tmp = head.next.val;
head.next.val = head.val;
head.val = tmp;
return head;
}
ListNode tmp = head;
ListNode low = head;
ListNode high = head.next;
ListNode tmp1 = high.next;
}
原地反转
时间复杂度:O(n)
空间复杂度:O(1)
方法:递归
时间复杂度:O(n)
空间复杂度:O(n)
思路:使用两个指针【前驱指针、当前指针】进行反转
时间复杂度:O(n)
空间复杂度:O(1)
“`java
class Solution{
Public ListNode reverseList(ListNode head){
if(head == null || head.next == null){
return head;
}
ListNode cur = head,pre=null;
while(cur!=null){
ListNode temp=cur.next;
cur.next=pre;
pre=cur;
cur=temp;
}
return pre;
额外空间复杂度=1
原地反转
}
利用递归到达链表的尾部,然后通过一个全局的Node来从尾部依次链接节点
时间复杂度O(N), 空间复杂度O(1)
代码:
时间复杂度:O(n),需要遍历一次链表
空间复杂度:O(n),递归栈的大小为链表长度
1.递归
时间复杂度:O(n)
额外空间复杂度:O(n)
2.原地反转
时间复杂度:O(n)
额外空间复杂度:O(1)
时间复杂度O(n)
空间复杂度O(1)
原地反转迭代
方法一:原地反转(迭代)+ 双指针
Time:O(n)
Space:O(1)
方法二:递归
Time:O(n)
Space:O(n)
反转链表
使用双指针法,原地反转链表
方法1:递归。
时间复杂度:O(n)。
空间复杂度:O(n)。
方法2:原地反转。
时间复杂度:O(n)。
空间复杂度:O(1)。
1、原地反转
2、递归反转
【思路】向后遍历的同时往新链表头插入节点
【复杂度】时间O(n),空间O(1)
“`java /**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
class Solution {
public ListNode reverseList(ListNode head) {
ListNode curr = head;
ListNode prev = null;
while (curr != null) {
ListNode next = curr.next;
curr.next = prev;
prev = curr;
curr = next;
}
return prev;
}
}
“`
时间复杂度:O(n) 空间复杂度:O(1)
java反转链表
public ListNode reverseList(ListNode head) {
if(head null || head.next null){
return head;
}
ListNode cur = head;
ListNode pre = null;
while(cur != null){
ListNode temp = cur.next;//保存后面的节点
cur.next = pre;
pre = cur;
cur = temp; //继续指向后面节点
}
return pre;
}
时间复杂度o(n)
空间复杂度o(1)
打卡
前中后 pre cur back 三个指针 改变next意味着对指向的下个节点的丢失,想要使用要先保存
public ListNode ReverseList(ListNode head) {
用的虚拟头节点
“`java
public ListNode reverseList(ListNode head) {
if (head == null) {
return head;
}
ListNode fakeHead = new ListNode(0);
//假头指向真头
fakeHead.next = head;
//从第二个开始
ListNode current = head.next;
//这一步避免形成环路
head.next = null;
//避免链表丢失,用来保存下一个
ListNode temp;
while (current != null) {
//记录下一个
temp = current.next;
//插入到假头和真头之间
current.next = fakeHead.next;
fakeHead.next = current;
//继续下一个
current = temp;
}
return fakeHead.next;
}
“`java
时间复杂度:O(n),空间复杂度O(1)
class Solution {
public ListNode reverseList(ListNode head) {
ListNode pre=null;
ListNode cur=head;
}
递归算法
}
时间复杂度是O(n)
空间复杂度是O(1)
“`c++
// c++实现
class Solution {
public:
ListNode* reverseList(ListNode* head) {
if(!head || !head->next){
return head;
}
ListNode* newhead = reverseList(head->next);
head->next->next = head;
head->next = nullptr;
return newhead;
}
};
使用的压栈出栈思路,要是递归、迭代的话好像更好一些
cpp双指针实现
ListNode* pre = NULL;
ListNode* cur = head;
if(curNULL||(cur!=NULL&&cur->nextNULL))
{
return cur;
}
while(cur!=NULL)
{
ListNode* temp = cur;
cur = cur->next;
temp->next = pre;
pre=temp;
}
return pre;
“`c++
class Solution {
public:
//递归法
ListNode* reverse(ListNode* pre, ListNode*cur){
if(cur == NULL) return pre;//结束条件
ListNode* temp = cur -> next;
cur -> next = pre;
};
class Solution {
public:
//双指针法
ListNode* reverseList(ListNode* head) {
if(head NULL) return head;
if(head -> next NULL) return head;
};
“`
时间复杂度O(N)
空间复杂度O(1)
递归
原地反转
思想:递归
三指针
时间:O(n)
空间:O(1)
时间复杂度O(n)
空间复杂度O(n)
C++
方法1: for循环遍历反转
TC: O(n)
SC: O(1)
“`C++
class Solution {
public:
ListNode* reverseList(ListNode* head) {
ListNode* prev = NULL;
ListNode* curr = head;
while (curr) {
ListNode *temp = curr->next;
curr->next = prev;
prev = curr;
curr = temp;
}
return prev;
}
};
【时间O(n),空间O(1)】
遍历并反转每个指针
“`java
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
class Solution {
public ListNode reverseList(ListNode head) {
//迭代法
ListNode cur = head;
ListNode pre = null;
while(cur!=null){
ListNode tempNode = cur.next;
cur.next = pre;
pre = cur;
cur = tempNode;
}
}
““
时间复杂度:O(n)
空间复杂度:O(n)
1、先总结出递归出口
2、再将当前头结点next结点进行递归
3、想象递归返回时此时指向的head节点,将head.next.next = head (比如链表1234,将3next指向的4的next指向3,将3的next 指向null)
时间复杂度:O(n)
空间复杂度:O(1)
思路:递归
时间复杂度O(n) 空间复杂度O(n)
执行用时:0 ms
内存消耗:8.2 MB
思路:
想法:设置两个辅助节点(NULL和头节点),将头节点的下一个节点取出赋给局部节点,然后将NULL赋给头节点的下一个节点,接下来,将改变后的头节点和局部节点作为函数新的变量值继续递归,达到将头节点的下一个节点的值备份后,将被改变的头节点的下一个值作为头节点下一个节点的值,递归结束条件是遍历结束,此时头节点为空。
时间复杂度 O(n),空间复杂度 O(1)
这个题直接遍历就可以了,只是注意在修改某个节点的next节点时,要保存原来的那个next以方便遍历
而且对第一个节点,它的next字段应当为NULL
可以
简单
递归法 =》 时间复杂度:O(n),空间复杂度:O(n)
C++原地反转:class Solution {
public:
ListNode* reverseList(ListNode* head) {
if(head NULL) return head;
ListNode* cur = head;
ListNode* tmp;
ListNode* pre = NULL;
while(cur){
tmp = cur->next;
cur->next = pre;
pre = cur;
cur = tmp;
}
return pre;
}
};
递归解法
class Solution {
public:
ListNode* reverseList(ListNode* head) {
//base case
if(headnullptr||head->nextnullptr){
return head;
}
ListNode* last = reverseList(head->next);
head->next->next = head;
head->next = nullptr;
return last;
}
};
栈解法
class Solution {
public:
ListNode* reverseList(ListNode* head) {
};
c实现
struct ListNode* reverseList(struct ListNode* head){
if(headNULL||head->nextNULL){
return head;
}
struct ListNode* newhead=NULL;
struct ListNode* head_cur=head;
struct ListNode* head_next=head;
while(head_cur){
head_next=head_cur->next;
head_cur->next=newhead;
newhead=head_cur;
head_cur=head_next;
}
return newhead;
}
原地反转
时间复杂度:O(n)
空间复杂度:O(1)
递归反转
解法没想出来,被自己绕晕
使用java实现
原地的时间复杂度为n,空间为1,反转时间复杂为n,空间为n
思路:如果是原地的话主要运用了两个指针较为简单,而反转递归的思想,则和视频中介绍的有一些不同,是从最后一个开始 head.next=null,是为了避免闭环!
思路:单向链表只能指向后面不能指向前面所以主要想法是定义一个新的指针记录当前节点的前驱节点,令当前节点指向其前驱节点,实现翻转。
···c++
class Solution {
public:
ListNode* reverseList(ListNode* head) {
// 找到前驱节点
ListNode* pre = nullptr;
ListNode* cur = head;
while(cur){
ListNode* temp = cur->next;
cur->next = pre;
pre = cur;
cur = temp;
}
return pre;
}
};
递归比较难理解,主要就是要想好返回值和当前节点的操作。
1.原地反转 参考帅地
class Solution {
public ListNode reverseList(ListNode head) {
if(headnull || head.nextnull){
return head;
}
ListNode cur=head;
ListNode pre=null;
}
2.递归实现
class Solution {
public ListNode reverseList(ListNode head) {
if(headnull || head.nextnull){
return head;
}
}
思路
代码
这里是Ming的打卡:
思路1:递归
//演示temp第一次被赋值时情况:
//temp = 5 temp.next = null;
//此时参数head为4; head.next.next = head 也就是 5.next = 4; head.next = null 主要用于temp最后一次赋值时
思路2:原地反转:双指针,前驱指向null,后面指向现结点,cur.next = pre达到效果
时间复杂度:O(n),空间复杂度:O(1)
public reverseList(ListNode head){
if(headnull){
return head;
}
ListNode temp=reverseList(head.next);
head.next.next=head;
head.next=null;
return temp;
}
时间复杂度:O(n)
额外空间复杂度:O(N)