反转链表
给定一个单链表的头结点pHead(该头节点是有值的,比如在下图,它的val是1),长度为n,反转该链表后,返回新链表的表头。
数据范围: 0≤n≤10000≤n≤1000
要求:空间复杂度 O(1)O(1) ,时间复杂度 O(n)O(n) 。
如当输入链表{1,2,3}时,
经反转后,原链表变为{3,2,1},所以对应的输出为{3,2,1}。
以上转换过程如下图所示:
解法1:反转链表
using System;
using System.Collections.Generic;/*
public class ListNode
{
public int val;
public ListNode next;public ListNode (int x)
{
val = x;
}
}
*/class Solution {
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
*
* @param head ListNode类
* @return ListNode类
*/public ListNode ReverseList (ListNode head) {
// write code here
Stack<ListNode> stack = new Stack<ListNode>();
// 遍历链表,将链表中的节点存储在栈中
while (head != null) {
stack.Push(head);
head = head.next;
}
if(stack.Count <= 0) return null;
ListNode node = stack.Pop();
head = null;
head = node; // 新的头节点
// 利用栈先进后出的原理,进行链表数据反转
while (stack.Count > 0) {
ListNode tempNode = stack.Pop();
node.next = tempNode;
node = node.next;
}
// 确保最后一个节点的 next 指针为 null
node.next = null;
return head;
}
}
解法2:双链表求解
双链表求解是把原链表的结点一个个摘掉,每次摘掉的链表都让他成为新的链表的头结点,然后更新新链表。下面以链表1→2→3→4为例画个图来看下。
他每次访问的原链表节点都会成为新链表的头结点,最后再来看下代码
public ListNode ReverseList (ListNode head) { // write code here //新链表 ListNode newHead = null; while (head != null) { //先保存访问的节点的下一个节点,保存起来 //留着下一步访问的 ListNode temp = head.next; //每次访问的原链表节点都会成为新链表的头结点, //其实就是把新链表挂到访问的原链表节点的 //后面就行了 head.next = newHead; //更新新链表 newHead = head; //重新赋值,继续访问 head = temp; } //返回新链表 return newHead; }