【剑指offer】算法题06.从尾到头打印链表(C++)
输入一个链表的头节点,从尾到头反过来返回每个节点的值(用数组返回)。 【示例 1】 输入:head = [1,3,2] 输出:[2,3,1] 【限制】 0 <= 链表长度 <= 10000
【解题思路】
思路一:从头开始遍历链表,每一次都将节点的值插入到数组的第一个位置。插入时使用emplace()或者insert()都可以。
/** * Definition for singly-linked list. * struct ListNode { * int val; * ListNode *next; * ListNode(int x) : val(x), next(NULL) {} * }; */ class Solution { public: vector<int> reversePrint(ListNode* head) { vector<int> nums; if(head==NULL) return nums; ListNode* p=head; while(p!=NULL){ nums.emplace(begin(nums),p->val); p=p->next; } return nums; } };
思路二:从头遍历链表,将节点值按顺序存入数组中,最后将数组倒序。利用reverse()。
/** * Definition for singly-linked list. * struct ListNode { * int val; * ListNode *next; * ListNode(int x) : val(x), next(NULL) {} * }; */ class Solution { public: vector<int> reversePrint(ListNode* head) { vector<int> nums; if(head==NULL) return nums; ListNode* p=head; while(p!=NULL){ nums.push_back(p->val); p=p->next; } reverse(nums.begin(),nums.end()); return nums; } };
【结果对比】
思路 | 执行时间 | 内存消耗 |
一 | 72ms | 10.1MB |
二 | 4ms | 10.3MB |
【相关总结】
1. C++ vector插入元素的方法。
(1). 使用成员函数emplace(),可以在vector序列中插入新的元素。emplace() 的第一个参数是一个迭代器,它确定了对象生成的位置。对象会被插入到迭代器所指定元素的后面。第一个参数后的参数,都作为插入元素的构造函数的参数传入。例如:
std::vector<std::string> words {"first", "second"}; // Inserts string(5,'A') as 2nd element auto iter = words.emplace(++std::begin(words),5,'A'); //Inserts string ("$$$$") as 3rd element words.emplace(++iter, "$$$$");
这段代码执行后,vector 中的字符串对象如下:
"first" "AAAAA" "$$$$" "second"
【注意】
- 使用vector.begin()和begin(vector)都可以。begin()返回容器中指向第一个元素的迭代器,end()返回指向容器最后一个元素所在位置后一个位置的迭代器,通常和 begin() 结合使用。
- cbegin()、cend() 和 begin() 、end()功能相同,只不过在其基础上,增加了 const 属性,不能用于修改元素。
(2). 使用成员函数insert(),可以在 vector 中插入一个或多个元素。第一个参数总是一个指向插入点的 const 或 non-const 迭代器。元素会被迅速插入到第一个参数所指向元素的前面,如果第一个参数是一个反向迭代器,元素会被插入到迭代器所指向元素的后面。
更多操作可以在此处看到——>http://c.biancheng.net/view/427.html
2. emplace() 和 insert() 的区别。
在使用 emplace() 时,对象会在容器中直接生成,而不是先单独生成对象,然后再把它作为参数传入。而 insert() 会先单独生成一个对象,作为传入的第二个参数。第二个参数是一个临时对象,所以会调用第二个函数重载版本,临时对象会被移动插入而不是被复制插入容器。因此,在使用同样参数的情况下,调用 emplace() 更加高效。