这个是高频的面试题,今天总结了一些。反转链表用三个指针实现,返回新链表的头节点;而从尾到头打印,应用栈实现,返回vector整个链表。

//题目描述
//
//输入一个链表,反转链表后,输出链表的所有元素。

struct ListNode
{
    int val;
    struct ListNode *next;
    ListNode(int x) :val(x), next(nullptr){}
};

//思路
//在反转链表的时候,我们很容易想到让当前结点的next指向前一个结点,
//但是这样做了之后这个节点原本next所指的结点就找不回了,所以每次我们都要保存新的前一结点,
//当前结点和下一结点三个指针,只要下一结点为空,那么我们就到了原本结点的尾部,这时正是新链表的头部
class Solution {
public:
    ListNode* ReverseList(ListNode* pHead) {

        ListNode *current = pHead;
        ListNode *pre = nullptr;
        ListNode *pNewNode = nullptr;
        if (pHead == nullptr)
        {
            return nullptr;
        }
        while (current != nullptr)  //当前结点不为空
        {
            ListNode *pnext = current->next; //当前结点的后继
            if (pnext == nullptr)
            {
                pNewNode = current;  //最后结点,即反转链表的头节点
            }
            current->next = pre; //当前结点的后继转为前驱
            pre = current;  //前驱转为当前结点
            current = pnext;  //当前结点向后移
        }
        return pNewNode;
    }
};

//1、三个指针在链表上同时滑动,比较容易想到但是编码略复杂
class Solution {
public:
    ListNode* ReverseList(ListNode* pHead) {
        if (pHead == nullptr) return nullptr;
        if (pHead->next == nullptr) return pHead;

        ListNode *pBefore = pHead, *p = pHead->next, *pAfter = p->next;
        while (pAfter) {
            p->next = pBefore; // reverse
            pBefore = p;
            p = pAfter;
            pAfter = pAfter->next;
        }
        p->next = pBefore; //完成最后一个结点的前驱
        pHead->next = nullptr; //尾结点后继为空
        return p;
    }
};

//2、从原链表的头部一个一个取节点并插入到新链表的头部
class Solution {
public:
    ListNode* ReverseList(ListNode* pHead) {
        if (pHead == nullptr) return nullptr;
        ListNode* head = pHead;
        pHead = pHead->next;
        head->next = nullptr; //此时的head为尾结点
        while (pHead) {
            ListNode *next = pHead->next;
            pHead->next = head;
            head = pHead; //
            pHead = next;
        }
        return head;
    }
};

//使用一个栈来解决问题,C++

#include<stack>
using namespace std;
class Solution {
public:
    ListNode* ReverseList(ListNode* pHead) {
        if (pHead == nullptr || pHead->next == nullptr)
        {
            return pHead;
        }
        ListNode * p = pHead;
        ListNode * newHead;
        stack<ListNode *> stack1;
        while (p->next != NULL)
        {
            stack1.push(p);
            p = p->next;
        }
        newHead = p;
        while (!stack1.empty())
        {
            p->next = stack1.top();
            p = p->next;
            stack1.pop();
        }
        p->next = NULL;
        return newHead;
    }
};

//题目描述
//
//输入一个链表,从尾到头打印链表每个节点的值。
//输入描述 :
//输入为链表的表头
//
//
//输出描述 :
//输出为需要打印的“新链表”的表头
#include<vector>
class Solution {
public:
    vector<int> printListFromTailToHead(struct ListNode* head) {

        //std::stack<ListNode*> nodes;

        // ListNode *pNode = head;
        // while(pNode != NULL)
        // {
        //      nodes.push(head);
        //      head = head->next;
        // }

        //  while(!nodes.empty())
        //  {
        //     head = nodes.top();
        //     printf("%d\t" ,head->val);
        //     nodes.pop();
        //  }

        vector<int> dev1;
        if (head != NULL)
        {
            if (head->next != NULL)
            {
                dev1 = printListFromTailToHead(head->next);
            }
            dev1.push_back(head->val);
        }
        return dev1;

    }
};

class Solution {
public:
    vector<int> printListFromTailToHead(struct ListNode* head) {
        //利用栈的逆序输出特性
        stack<int> stack;
        vector<int> vector;
        struct ListNode *p = head;
        if (head != NULL) {
            stack.push(p->val);
            while ((p = p->next) != NULL) {
                stack.push(p->val);
            }
            while (!stack.empty()) {
                vector.push_back(stack.top());
                stack.pop();
            }
        }
        return vector;
    }

};

/***
*从原理上来说,借助栈会使得问题的解决思路非常简单明了。
*注意函数的返回类型是int类型的vector
*/
class Solution {
public:
    vector<int> printListFromTailToHead(struct ListNode* head)
    {
        vector<int> vec;         //声明一个vector存放Node的int类型的val值
        std::stack<ListNode *>nodes;
        ListNode *pNode = head;
        //遍历入栈
        while (pNode != NULL)
        {
            nodes.push(pNode);    //遍历所有节点,将结点压入栈中
            pNode = pNode->next;
        }
        //遍历出栈
        while (!nodes.empty())
        {
            pNode = nodes.top();        //定义的结点指针始终指向栈顶,取出栈顶结点的val值存入到定义的vec中,然后弹出栈顶元素。由栈顶往栈底遍历
            vec.push_back(pNode->val);
            nodes.pop();
        }
        return vec;    //返回值为int型的vector
    }
};

offer--链表反转和从尾到头打印链表的更多相关文章

  1. 剑指Offer - 九度1511 - 从尾到头打印链表

    剑指Offer - 九度1511 - 从尾到头打印链表2013-11-29 21:08 题目描述: 输入一个链表,从尾到头打印链表每个节点的值. 输入: 每个输入文件仅包含一组测试样例.每一组测试案例 ...

  2. JS 剑指Offer(四) 从尾到头打印链表

    题目:输入一个链表的头节点,从尾到头反过来返回每个节点的值(用数组返回). 首先定义一下链表中的节点,关于链表这个数据结构在另外一篇文章中会详细讲 function ListNode(val) { t ...

  3. 剑指offer【03】- 从尾到头打印链表(4种实现方法)

    题目:从尾到头打印链表 考点:链表 题目描述:输入一个链表,按链表值从尾到头的顺序返回一个ArrayList. 法一:ArrayList头插法 /** * public class ListNode ...

  4. 【Offer】[6] 【从尾到头打印链表】

    题目描述 思路分析 Java代码 代码链接 题目描述 从尾到头打印链表,将其添加到ArrayList当中输出 思路分析 递归的思路 利用栈 Java代码 public class Offer006 { ...

  5. 剑指offer(3)从尾到头打印链表

    题目描述 输入一个链表,从尾到头打印链表每个节点的值. 题目分析 比较简单,主要注意下从尾到头,可以用栈可以用递归,我给出我比较喜欢的代码吧 代码 /* function ListNode(x){ t ...

  6. 【剑指Offer】3、从尾到头打印链表

      题目描述:   输入一个链表,按链表值从尾到头的顺序返回一个ArrayList.   解题思路:   (三种方法:借助栈.递归.列表的首位插入)   从头到尾打印链表比较简单,从尾到头很自然的可以 ...

  7. 剑指offer第二版-6.从尾到头打印链表

    描述:输入一个链表的头节点,从尾到头打印每个节点的值. 思路:从尾到头打印,即为“先进后出”,则可以使用栈来处理:考虑递归的本质也是一个栈结构,可递归输出. 考点:对链表.栈.递归的理解. packa ...

  8. 剑指offer(5)——从尾到头打印链表

    题目: 输入一个链表的头结点,从尾到头反过来打印出每个结点的值.结点定义如下: public class ListNode { int val; ListNode next = null; ListN ...

  9. 剑指Offer编程题3——从尾到头打印链表

    题目描述 输入一个链表,按链表值从尾到头的顺序返回一个ArrayList.   题目解析 方法1:建立两个vector,第一个用来存储正向访问的数据,第二个用来反向存储. /** * struct L ...

随机推荐

  1. tomcat报警告 An attempt was made to authenticate the locked user

    有好多这样的警报怪怪的,一分钟抛一次,大概抛了10分钟,停止 有 Anattempt was made to authenticate the locked user "root" ...

  2. python 调用 C++ code

    本文以实例code讲解python 调用 C++的方法. 1. 如果没有参数传递从python传递至C++,python调用C++的最简单方法是将函数声明为C可用函数,然后作为C code被pytho ...

  3. javascript 简繁转换

    js 简繁转换 function copy(ob) { var obj=findObj(ob); if (obj) { obj.select();js=obj.createTextRange();js ...

  4. js中substr与substring的用法与区别

    substrsubstr(start,length)表示从start位置开始,截取length长度的字符串. var src="images/pic_1.png";alert(sr ...

  5. [HIHO1300]展胜地的鲤鱼旗(栈,dp)

    题目链接:http://hihocoder.com/problemset/problem/1300 给一个字符串,只包含'('和')',问存在多少个子串似的括号是匹配的. 匹配规则在题干中描(蒻)述( ...

  6. leetcode Database3(Nth Highest Salary<—>Consecutive Numbers<—>Department Highest Salary)

    一.Nth Highest Salary Write a SQL query to get the nth highest salary from the Employee table. +----+ ...

  7. leetcode:Odd Even Linked List

    Given a singly linked list, group all odd nodes together followed by the even nodes. Please note her ...

  8. 3D volume texture和cube map

    cube map texture可以理解为6个面的纸盒, sample的时候使用vector射线型的sample. volume texture可以理解是一摞2D texture,sample的时候用 ...

  9. 基于UltraVNC实现客户端远程控制

    前言 一般远程就直接用windows自带的,配置好动态IP花生壳,在任何地方都可以连回机子.最近项目里遇到这么个情况,需要快速接入远程控制功能,客户机的IP每次都会变,并且都是在外网,这样,就必须使用 ...

  10. Jenkins+Maven+SVN搭建自动部署、自动测试环境

    .打开http://10.3.15.78:8080/jenkins/,第一次进入里面没有数据,我们需要创建job,我们这有2个项目,需要创建2个job.http://10.3.34.163:9890/ ...