struct ListNode {
int val;
struct ListNode *next;
};
想到两种方法:
1.空间换时间
想法是构建一个新的单链表,然后遍历原来的单链表,每遍一个就把它插入到最新的单链表的开头,下面是代码:
struct ListNode *reverseList(struct ListNode *list) {
struct ListNode *new;
struct ListNode *temp, *last;
if(NULL == list) {
return NULL;
}
temp = list;
last = NULL;
while(temp) {
new = (struct ListNode *)malloc(sizeof(struct ListNode));
new->val = temp->val;
new->next = last; //将最新的结点插入到开头
last = new;
temp = temp->next;
}
return new;
}
2.原地反转
这个思路是遍历链表,每次都把元素移到链表最前端,这样就实现了翻转。比如1-2-3-4,那么过程如下:
2-1-3-4
3-2-1-4
4-3-2-1
其实也很简单,下面是代码:
struct ListNode *reverseList(struct ListNode *list) {
struct ListNode *first,*second,*temp;
first = list;
second = list->next;
if(list == NULL) //空链表直接返回空
return NULL;
if(list->next == NULL) //一个结点返回这个结点
return list;
if(list->next->next == NULL) { //2个结点链表将结点对调返回头结点
temp = second->next;
first->next = temp;
second->next = first;
return second;
}
while(second->next) {
temp = second->next; //第三个结点赋给temp
first->next = temp; //头结点的next指向第三个结点
second->next = first; //第二个结点的next指向头结点(自己变成了头结点)
first = second; //头结点重置
second = first->next; //第二个节点重置
}
}
2的算法比1的算法空间复杂度低,时间复杂度相同都是O(n).