剑指 Offer 06. 从尾到头打印链表

题目描述

输入一个链表,按链表从尾到头的顺序返回一个ArrayList。

示例1

  • 输入: {67,0,24,58}
  • 返回值: [58,24,0,67]

难度:简单


题解

方法一:List.Reverse 方法

  • Reverse():将整个 List 中元素的顺序反转。此方法是 O (n) 操作,其中 n 是 List 中包含的元素数Count.
  • Reverse(int index, int count):将指定范围中元素的顺序反转。
    index:要反转的范围的从零开始的起始索引。
    count:要反转的范围内的元素数。
    Sample: csharplist.Reverse(1, 4) //使用方法重载反转列表中间,从元素1开始,包含四个元素

C#:

using System.Collections.Generic;
/*
public class ListNode
{
    public int val;
    public ListNode next;
    public ListNode (int x)
    {
        val = x;
    }
}*/
class Solution
{
    // 返回从尾到头的列表值序列
    public List<int> printListFromTailToHead(ListNode listNode)
    {
        List<int> resList = new List<int>();
        
        while(listNode != null)
        {
            resList.Add(listNode.val);
            listNode = listNode.next;
        }
        resList.Reverse();
        
        return resList;
    }
}

方法二:递归

C#:

using System.Collections.Generic;
/*
public class ListNode
{
    public int val;
    public ListNode next;
    public ListNode (int x)
    {
        val = x;
    }
}*/
class Solution
{
    List<int> resList = new List<int>(); // 递归,必须定义在方法外。
   
    public List<int> printListFromTailToHead(ListNode listNode)
    {
        if(listNode!=null) 
        {
           if(listNode.next !=null)
           {
                printListFromTailToHead(listNode.next);
           }
        	resList.Add(listNode.val);
       }
       
       return resList;
    }
}

方法三:反转链表

最后在准备一个temp,表示还未反转的第一个结点。

  1. 初始化三个指针: pre结点初始指向nullptr,current 为head,next为NULL。
  2. 通过链表迭代。在循环中,执行以下操作。
    //在更改当前节点的下一个节点之前,
    //存储下一个节点
    next = curr-> next
    //现在改变当前节点的下一节点
    //这是实际逆转发生的地方
    curr-> next = prev
    //将prev和curr向前移动一步
    prev = curr
    curr = next
  • 总结:先存储当前节点的下一节点,再反转当前节点的pnext指针,最后重置head头部。
  • 注意:若head指向Null而不放数据,则prev、current 、next应相应改变。如果head为空,循环都不会执行。

C#:

	using System.Collections;
    using System.Collections.Generic;
    	
    /*
	public class ListNode
	{
    	public int val;
    	public ListNode next;
    	public ListNode (int x)
    	{
    		val = x;
    	}
	}*/
	
	class Solution
    {
        public List<int> printListFromTailToHead(ListNode listNode)
        {
            if (listNode == null)
            {
                return new List<int>();
            }

            ListNode current = listNode; //表示当前正在反转的结点,current初始化为head
            ListNode next = null; //表示还未反转的第一个结点
            ListNode pre = null; //表示正在反转结点的前一个结点

            while (current != null)
            {
                next = current.next;
                current.next = pre;
                pre = current;
                current = next;
            }

            List<int> ls = new List<int>();

            while (pre != null)
            {
                ls.Add(pre.val);
                pre = pre.next;
            }

            return ls;
        }
    }

方法四:List.Insert(Int32, T) 方法

List中有个方法是 Insert (index,value),可以指定 index 位置插入 value 值

public void Insert (int index, T item);

参数:

  • index:应插入 item 的从零开始的索引。
  • item:要插入的对象。 对于引用类型,该值可以为 null。

所以我们在遍历 listNode 的同时将每个遇到的值插入到 list 的 0 位置,最后输出 listNode 即可得到逆序链表.

C#:

using System.Collections.Generic;
/*
public class ListNode
{
    public int val;
    public ListNode next;
    public ListNode (int x)
    {
        val = x;
    }
}*/
class Solution
{
    // 返回从尾到头的列表值序列
    public List<int> printListFromTailToHead(ListNode listNode)
    {
       List<int> myList = new List<int>();
        while(listNode!=null)
        {
            myList.Insert(0, listNode.val); //将每个遇到的值插入到 list 的 0 位置
            listNode =listNode.next;
        }
        
        return myList;
    }
}
  • 时间复杂度:O(n)
  • 空间复杂度:O(n)

方法五:栈

链表只能从头遍历到尾,但是输出却要求从尾到头,是典型的"先进后出",可以用栈实现。

C#:

	using System.Collections;
	using System.Collections.Generic;
	/*
	public class ListNode
	{
    	public int val;
    	public ListNode next;
    	public ListNode (int x)
    	{
        	val = x;
    	}
	}
	*/
	
	class Solution
    {
        public List<int> printListFromTailToHead(ListNode listNode)
        {
            Stack resStack = new Stack();
            List<int> resList = new List<int>();

            while(listNode != null)
            {
                resStack.Push(listNode.val);
                listNode = listNode.next;
            }

            while(resStack.Count>0)
            {
                resList.Add((int)resStack.Pop());
            }

            return resList;
        }
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值