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. modify_list_tail = head; 
  13. while(change_len&&head){//将逆置段逆置 
  14. ListNode* next = head->next; 
  15. head->next = new_head; 
  16. new_head = head; 
  17. head = next;//最后一次循环,head就是逆置段的后置 
  18. change_len--; 
  19.  
  20. modify_list_tail->next = head; 
  21. if (pre_head){ 
  22. pre_head->next = new_head; 
  23. else
  24. result = new_head; 
  25. return result; 
  26. }; 

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. modify_list_tail = head; 
  20. while (change_len&&head) {//将逆置段逆置 
  21. ListNode* next = head->next; 
  22. head->next = new_head; 
  23. new_head = head; 
  24. head = next;//最后一次循环,head就是逆置段的后置 
  25. change_len--; 
  26.  
  27. modify_list_tail->next = head; 
  28. if (pre_head) { 
  29. pre_head->next = new_head; 
  30. else
  31. result = new_head; 
  32. return result; 
  33. }; 
  34.  
  35. void main()
  36. ListNode a(1)
  37. ListNode b(2)
  38. ListNode c(3);  
  39. ListNode d(4);  
  40. ListNode e(5)
  41. a.next = &b; 
  42. b.next = &c; 
  43. c.next = &d; 
  44. d.next = &e; 
  45. Solution solve; 
  46. ListNode *head = solve.reverseBetween(&a, 2, 4); 
  47. while (head) { 
  48. printf("%d ", head->val); 
  49. head = head->next; 
  50. system("pause"); 
  51.  

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

原文地址:https://www.cnblogs.com/Howfars/p/10251698.html