给定一个单链表的头结点pHead(该头节点是有值的,比如在下图,它的val是1),长度为n,反转该链表后,返回新链表的表头。
数据范围:
要求:空间复杂度
,时间复杂度
。
如当输入链表{1,2,3}时,
经反转后,原链表变为{3,2,1},所以对应的输出为{3,2,1}。
以上转换过程如下图所示:
{1,2,3}
{3,2,1}
{}
{}
空链表则输出空
public class Solution { public ListNode ReverseList(ListNode head) { if(head==null) return null; //head为当前节点,如果当前节点为空的话,那就什么也不做,直接返回null; ListNode pre = null; ListNode next = null; //当前节点是head,pre为当前节点的前一节点,next为当前节点的下一节点 //需要pre和next的目的是让当前节点从pre->head->next1->next2变成pre<-head next1->next2 //即pre让节点可以反转所指方向,但反转之后如果不用next节点保存next1节点的话,此单链表就此断开了 //所以需要用到pre和next两个节点 //1->2->3->4->5 //1<-2<-3 4->5 while(head!=null){ //做循环,如果当前节点不为空的话,始终执行此循环,此循环的目的就是让当前节点从指向next到指向pre //如此就可以做到反转链表的效果 //先用next保存head的下一个节点的信息,保证单链表不会因为失去head节点的原next节点而就此断裂 next = head.next; //保存完next,就可以让head从指向next变成指向pre了,代码如下 head.next = pre; //head指向pre后,就继续依次反转下一个节点 //让pre,head,next依次向后移动一个节点,继续下一次的指针反转 pre = head; head = next; } //如果head为null的时候,pre就为最后一个节点了,但是链表已经反转完毕,pre就是反转后链表的第一个节点 //直接输出pre就是我们想要得到的反转后的链表 return pre; } }
public ListNode ReverseList(ListNode head) { ListNode pre = null; ListNode next = null; while (head != null) { next = head.next; head.next = pre; pre = head; head = next; } return pre; }
public class Solution { public ListNode ReverseList(ListNode head) { ListNode pre = null; ListNode next = head; while(head != null){ next = head.next; head.next = pre; pre = head; head = next; } return pre; } }
import java.util.*; import java.io.*; public class Main{ public static void main(String[] args) throws IOException{ BufferedReader in = new BufferedReader(new InputStreamReader(System.in)); String str=null; while((str = in.readLine()) != null){ String[] str1 = str.split("[^0-9]"); StringBuffer str2 = new StringBuffer(); str2.append("{"); for(int i=str1.length-1;i>0;i--){ if(i==1){ str2.append(str1[i]); break; } str2.append(str1[i] + ","); } str2.append("}"); System.out.print(str2.toString()); } } }
Rust 尾插法:
pub fn ReverseList(&self, head: Option<Box<ListNode>>) -> Option<Box<ListNode>> { // write code here let mut res=None; let mut cur=head; while let Some(mut x)=cur{ cur=x.next; x.next=res; res=Some(x); } res }
Rust 递归写法:
pub fn ReverseList(&self, head: Option<Box<ListNode>>) -> Option<Box<ListNode>> { // write code here if let None=head{ return None; } let mut tmp=head.unwrap(); match tmp.next { None=> return Some(tmp), Some(mut x)=>{ tmp.next=None; let mut flag=&mut x as *mut Box<ListNode>; let last=self.ReverseList(Some(x)); unsafe { (*flag).next=Some(tmp); } return last; } } }
/* 双指针 */ public class Solution { public ListNode ReverseList(ListNode head) { if(head == null || head.next == null)return head; //存储t2.next 因为要将t2.next设为t1,所以需要记录 ListNode tmp = null; //相邻的两个节点 ListNode t1 = head; ListNode t2 = head.next; do{ tmp = t2.next; t2.next = t1; t1 = t2; t2 = tmp; }while(t2 != null); //头节点需要设置一下,不然在第一个节点和第二个节点会产生环 head.next = null; return t1; } }
public class Solution { public ListNode ReverseList(ListNode head) { ListNode p1=head; ListNode p2=head; ListNode root=head; if(head == null){ return null; } int k = 1; while(p1.next != null){ p1=p1.next; k++; } int[] m=new int[k]; for(int i=0;i<k;i++){ m[i]=p2.val; p2=p2.next; } ListNode p=root; while(k>0){ root.next=new ListNode(m[k-1]); root=root.next; k--; } return p.next; } }
class Solution { public: ListNode* ReverseList(ListNode* pHead) { if(pHead == NULL || pHead->next == NULL) return pHead; ListNode* dummy = new ListNode(-1); dummy->next = pHead; ListNode* cur = dummy->next; ListNode* temp = NULL; while(cur->next){ temp = cur->next; cur->next = temp->next; temp->next = dummy->next; dummy->next = temp; } return dummy->next; } };双指针:
class Solution { public: ListNode* ReverseList(ListNode* pHead) { if(pHead == NULL || pHead->next == NULL) return pHead; ListNode* pre = NULL; ListNode* cur = pHead; ListNode* temp = NULL; while(cur){ temp = cur->next; cur->next = pre; pre = cur; cur = temp; } return pre; } };
/* 这题的关键点要存下当前节点的前一个节点、当前点以及当前点后一个节点,以免出现节点丢失的问题。 在一开始可以把head当作当前点,null作为前一个点prenode,head.next作为后一个点aftnode 然后把当前点head指向prenode,此时head变化为新的prenode,aftnode变为新的head, 新的head.next变成aftnode,循环继续。 直到当前点的下下个节点为空,不能生成新的aftnode时,说明只剩最后两个点,逆序输出即可。 */
public class Solution { public ListNode ReverseList(ListNode head) { if(head == null){ return null; } if(head.next == null){ return head; } ListNode prenode = null; ListNode aftnode = head.next; while(head.next.next != null){ head.next = prenode; prenode = head; //当前节点保留作为下一个节点的前一个节点 head = aftnode; //当前节点后移 aftnode = head.next; //保留下一个节点 } head.next = prenode; aftnode.next = head; return aftnode; } }
class Solution: """ 如果链表长度 <= 1,则直接返回原头节点 否则,将原头节点后面的节点依次移动到前面去 需要操作的只有原头节点后面的节点,然后维护一个新的头节点 """ def ReverseList(self, pHead): if pHead==None or pHead.next==None: return pHead head = pHead # 新的头指针 while pHead.next: # 还有节点可以移动 node = pHead.next # 即将被移动的节点 pHead.next = node.next # 将该节点从后面的链表中删除 node.next = head # 移动节点到新的头节点之前 head = node # 更新头指针 return head