一、题目
二、本人思路及代码
直接在链表里进行翻转不太方便操作,但是数组就可以通过下标进行操作,于是,
思路1、
先遍历链表,以此存到vector中,然后再从后往前遍历这vector,存入到一个新的vector,就完成了翻转操作。
/**
* struct ListNode {
* int val;
* struct ListNode *next;
* ListNode(int x) :
* val(x), next(NULL) {
* }
* };
*/
class Solution {
public:
vector<int> printListFromTailToHead(ListNode* head) {
vector<int> a,ret;
while(head){
a.push_back(head->val);
head=head->next;
}
for(int i=a.size()-1;i>=0;i--){
ret.push_back(a[i]);
}
return ret;
}
};
思路2、
先遍历链表,以此存到vector中,然后定义两个指针,分别从头部和尾部同时往中间遍历,并将相应的位置进行交换,直到两个指针相等或后面的指针小于前面的。例如{1,2,3,4,5} --> 1和5交换,2和4交换。
/**
* struct ListNode {
* int val;
* struct ListNode *next;
* ListNode(int x) :
* val(x), next(NULL) {
* }
* };
*/
class Solution {
public:
vector<int> printListFromTailToHead(ListNode* head) {
vector<int> a;
while(head){
a.push_back(head->val);
head=head->next;
}
int i=0;
int j=a.size()-1;
int k;
for(;i<j; j--,i++){
k=a[i];
a[i]=a[j];
a[j]=k;
}
return a;
}
};
三、学习他人精华
在牛客上看到一个思路,觉得非常不错,记录一下。
解法采用递归来实现链表的反转. 其实递归和反转可以说是一对孪生兄弟, 递归在触底反弹之后, 执行的就是一个逆向的遍历过程.
在函数外部声明, 即把ret声明为Solution类的一个公有变量. 从而函数每次直接调用ret执行操作即可, 不需要在每一层递归都声明一个新的ret.
class Solution {
public:
vector<int> ret;
vector<int> printListFromTailToHead(ListNode* head) {
if(!head) return ret;
printListFromTailToHead(head->next);
ret.push_back(head->val);
return ret;
}
};