这道题居然是困难,回想起做过的其他困难题这个绝对是我做过最简单的困难题。
解决这个问题首先是需要解决如何翻转链表的问题,参考leetcode206
其实绝大多数人都可以想到最简单的翻转方法(大家更喜欢叫做迭代的方式):
ListNode * reverseListNode(ListNode * head){
if(head == nullptr) return nullptr;
if(head->next == nullptr) return head;
ListNode * prevNode = nullptr;
ListNode * currentNode = head;
while(currentNode!=nullptr){
ListNode * tmpNode = currentNode->next;
currentNode->next = prevNode;
prevNode = currentNode;
currentNode = tmpNode;
}
return prevNode;
}
当然这里还有一种解法(递归解法):
ListNode* reverseList(ListNode* head) {
if(head == nullptr){
return nullptr;
}
if(head->next == nullptr){
return head;
}
auto last = reverseList(head->next);
head->next->next = head;
head->next = nullptr;
return last;
}
其实这里的head->next->next = head是最难理解的:
不要跳进递归呢!!!
我们假设说这个reverseList(head->next);这一句代码已经把node2之后的链表已经翻转。结果如下:
执行完head->next->next = head; head->next = nullptr;如下所示:
注意红色箭头。
其实对比起来迭代的好理解又没有栈溢出的风险。迭代方法你值得拥有。
其实这么一想,递归方法千万不要跟着走入递归。
人脑能压几个栈?(教皇他有几个师?笑)
剩余内容请看24. 两两交换链表中的节点