LeetCode Notes_#92 Reverse Linked List II(C++,Python)

LeetCode Notes_#92 Reverse Linked List II(C++,Python)

Contents

题目

Reverse a linked list from position m to n. Do it in one-pass.

Note: 1 ≤ m ≤ n ≤ length of list.

Example:

Input: 1->2->3->4->5->NULL, m = 2, n = 4
Output: 1->4->3->2->5->NULL

思路和解答

思路

  1. 几个关键节点

关键节点
关键节点

  1. 整体思路

图解
图解

图解
图解

(1)先将指针head移动到开始逆置的节点modify_list_tail
(2) 按照之前#206 Reverse Linked List的做法,将[m,n]这一段逆置
(3)将被逆置的一段和逆置段前驱,逆置段后继连接起来
(4)考虑特殊情况:m=1?
如果是从第一个节点开始逆置,那么最后就不需要连接pre_head了

(5)为什么逆置的最后一个节点不需要考虑?

  • 因为n<=length,之后无论如何还有一个NULL节点,最后还是要把链表和NULL接起来

3.思考:返回结果是什么?

  • 返回的结果的形式是指向链表第一个节点的头指针
  • 如果m!=1,结果是一开始的head,要提前保存;如果m=1,结果是new_head

解答

C++

  1. class Solution { 
  2. public: 
  3. ListNode* reverseBetween(ListNode* head, int m, int n) { 
  4. int change_len = n-m+1; 
  5. ListNode * new_head = NULL; 
  6. ListNode* result = head; 
  7. ListNode* pre_head = NULL; 
  8. ListNode* modify_list_tail = NULL; 
  9. for(int i=1;i<m;i++){ 
  10. pre_head = head;//保存逆置段的前驱 
  11. head=head->next;//将head移动到m节点  
  12. } 
  13. modify_list_tail = head; 
  14. while(change_len&&head){//将逆置段逆置 
  15. ListNode* next = head->next; 
  16. head->next = new_head; 
  17. new_head = head; 
  18. head = next;//最后一次循环,head就是逆置段的后置 
  19. change_len--; 
  20. } 
  21.  
  22. modify_list_tail->next = head; 
  23. if (pre_head){ 
  24. pre_head->next = new_head; 
  25. } 
  26. else{ 
  27. result = new_head; 
  28. } 
  29. return result; 
  30. } 
  31. }; 

4ms,C++的确比较快

一个困惑的点:
问题:16行,new_head是NULL,那么是不是最后的结果会在逆置段和逆置后继之间有一个NULL?
回答:不会,因为22行连接逆置段后继的时候,直接将NULL修改为逆置段后继了

自己编写测试用例,在VS Studio里调试

  1. #include <iostream> 
  2. using namespace std; 
  3. struct ListNode { 
  4. int val; 
  5. ListNode *next; 
  6. ListNode(int x) : val(x), next(NULL) {} 
  7. }; 
  8. class Solution { 
  9. public: 
  10. ListNode* reverseBetween(ListNode* head, int m, int n) { 
  11. int change_len = n - m + 1; 
  12. ListNode * new_head = NULL; 
  13. ListNode* result = head; 
  14. ListNode* pre_head = NULL; 
  15. ListNode* modify_list_tail = NULL; 
  16. for (int i = 1; i<m; i++) { 
  17. pre_head = head;//保存逆置段的前驱 
  18. head = head->next;//将head移动到m节点  
  19. } 
  20. modify_list_tail = head; 
  21. while (change_len&&head) {//将逆置段逆置 
  22. ListNode* next = head->next; 
  23. head->next = new_head; 
  24. new_head = head; 
  25. head = next;//最后一次循环,head就是逆置段的后置 
  26. change_len--; 
  27. } 
  28.  
  29. modify_list_tail->next = head; 
  30. if (pre_head) { 
  31. pre_head->next = new_head; 
  32. } 
  33. else { 
  34. result = new_head; 
  35. } 
  36. return result; 
  37. } 
  38. }; 
  39.  
  40. void main() { 
  41. ListNode a(1); 
  42. ListNode b(2); 
  43. ListNode c(3);  
  44. ListNode d(4);  
  45. ListNode e(5); 
  46. a.next = &b; 
  47. b.next = &c; 
  48. c.next = &d; 
  49. d.next = &e; 
  50. Solution solve; 
  51. ListNode *head = solve.reverseBetween(&a, 2, 4); 
  52. while (head) { 
  53. printf("%d\n", head->val); 
  54. head = head->next; 
  55. } 
  56. system("pause"); 
  57.  
  58. } 

Python

  1. class Solution(object): 
  2. def reverseBetween(self, head, m, n): 
  3. """ 
  4. :type head: ListNode 
  5. :type m: int 
  6. :type n: int 
  7. :rtype: ListNode 
  8. """ 
  9. change_len = n-m+1 
  10. pre_head = None 
  11. result = head 
  12.  
  13. for i in range(1,m): 
  14. pre_head = head 
  15. head = head.next 
  16. modify_list_tail = head 
  17.  
  18. new_head = None 
  19. while(change_len and head): 
  20. next = head.next 
  21. head.next = new_head 
  22. new_head = head 
  23. head = next 
  24. change_len-=1 
  25. # if modify_list_tail: 
  26. modify_list_tail.next = head 
  27.  
  28. if(pre_head): 
  29. pre_head.next = new_head 
  30. else: 
  31. result = new_head 
  32.  
  33. return result 

32ms

posted @ 2019-01-10 18:34  Howfar's  阅读(280)  评论(0)    收藏  举报