逆置链表的返回

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

看到这个题目,相信大家脑海里会有很多想法,今天主要在这里说三种它的实现方法。

利用栈实现逆置

我们都知道栈遵循先进后出的原则,所以当我们面对逆置问题时,最先想到的应该就是利用栈来实现,原理如下图所示:

我们对链表进行遍历将其各个节点依次入栈,遍历完成后,再依次出栈,将其放入容器中,完成逆置。

代码如下:

class Solution {
public:
    vector<int> printListFromTailToHead(ListNode* head) {
         vector<int> con;
        if(head == nullptr) return con;
        ListNode *p = head;
          
        stack<int> st;
        while(p!= nullptr)
        {
             st.push(p->val);
             p= p->next;
        }
        while(!st.empty())
        {
            con.push_back(st.top());
            st.pop();
        }
      
        return con;
    }
};

我们发现这样除了必要的容器之外还要给栈开辟空间,造成的一定的空间损失,那么有没有什么办法可以不借用栈来实现链表逆置呢?我们在寻找一种方法可以在将节点放入容器的过程中完成逆置,这个时候头插法就有了用处。

 利用头插法

相信这个大家很容易理解,它的实现原理如图所示:

首先我们定义一个容器value用于存放新的链表:

我们将原链表依次遍历利用头插法将其放入value中,如下图所示:

当我们将head所指节点数值放入新容器之后,head指向下一个节点,重复此操作知道head指向空值,遍历结束,最后我们将valud返回就好。

下面是我们的实现代码:

class Solution {
public:
    vector<int> printListFromTailToHead(ListNode* head) {
        vector<int> value;
        if(head==nullptr) return value;
        else
        {
            while(head!=nullptr)
            {
                value.insert(value.begin(),head->val);
                head=head->next;
            }
        }
        return value;
    }
};

但是这样做有一个弊端,我们直接使用head遍历会破环原来的链表,所以我们可以对上面的代码进行稍微的改变,重新定义一个指针指向头结点完成遍历,这个很简单就不再写代码了。

 利用reverse()实现

reverse()函数可以实现容器内容的反转,所以我们只需要在将链表遍历存入容器后,调用reverse()函数将内容逆置就好。代码可以参考下面的:

class Solution {
public:
    vector<int> printListFromTailToHead(ListNode* head) {
        vector<int> con;
        if(head == nullptr) return con;
        ListNode *p = head;
        while(p!= nullptr)
        {
             con.push_back(p->val);
             p= p->next;
        }
        reverse(con.begin(),con.end());
        return con;
    }
};

猜你喜欢

转载自blog.csdn.net/pretysunshine/article/details/83543502
今日推荐