92. Reverse Linked List II。
来源:互联网 发布:怎样申请网络直播平台 编辑:程序博客网 时间:2024/06/09 18:51
Reverse a linked list from position m to n. Do it in-place and in one-pass.
For example:
Given 1->2->3->4->5->NULL, m = 2 and n = 4,
return 1->4->3->2->5->NULL.
题中让在一条链表中将给定位置中间的节点进行反转。可以使用两个栈node1和node2,node1存储位置m之前的节点,然后将m和n之前的节点存放在node2中。然后将node1中的节点依次取出,使用头插法插入到新链表来保证和之前链表顺序一致,因为m位置之前并不需要转换位置。node1取完之后将node2的依次取出链接到新链表,这样的话m和n之间的位置就进行了反转,然后再处理剩下的节点(也就是n位置之后的),依次添加到新链表之后即可。
class Solution {public: ListNode* reverseBetween(ListNode* head, int m, int n) { if(!head || m==n) { return head; } ListNode* dummpy = new ListNode(0); dummpy->next = head; ListNode* temp = dummpy; ListNode* result = new ListNode(0); ListNode* tail = result; stack<ListNode*> node1; stack<ListNode*> node2; int num = n - m + 1;//需要加1,此时需要包含后面的那个节点 m--; while(m) {//将m之前的都存放在node1栈中 temp = temp->next; node1.push(temp); m--; } while(num&&temp) { temp = temp->next; node2.push(temp); num--; } if(temp) { temp = temp->next;//移动到变换后的一个节点 } while(!node1.empty()) {//前面的顺序不变,所以使用头插法 node1.top()->next = result->next; result->next = node1.top(); if(tail == result) { tail = node1.top(); } node1.pop(); } while(!node2.empty()) { tail->next = node2.top(); tail = tail->next; node2.pop(); } while(temp) { tail->next = temp; tail = temp; temp = temp->next; } tail->next = nullptr; return result->next; }};
也可以使用两个指针,第一个指针先移动到m位置,然后记录下此刻的位置,然后计算出此刻共需要反转多少个元素,从第一个指针所指的m位置开始遍历,反转一定的元素之后再遍历下面的元素。这个方法就是需要记录各个关键地方的位置。
class Solution {public: ListNode* reverseBetween(ListNode* head, int m, int n) { if(!head || m==n) { return head; } ListNode* dummpy = new ListNode(0); dummpy->next = head; ListNode* start = dummpy;//指向需要变换的开头 ListNode* tail = nullptr;//指向需要变换的结尾 ListNode* temp = nullptr; ListNode* p1,*p2; int num = n - m; m--; while(m) {//运行到需要变换位置的前一个节点 start = start->next; m--; } p1 = start;//记录中断的位置 p2 = start->next;//记录转换后的最后一个位置(也就是m位置) start = start->next;//此刻的位置才是需要开始变换的位置 temp = start->next;//指向下一个节点 start->next = nullptr; while(temp && num) {//将m和n之间进行反转链接 tail = temp->next; temp->next = start; start = temp; temp = tail; num--; } p1->next = start;//与前半部分对接 while(temp) {//需要用temp而不是tail,因为tail可能为空(如果没有进while(temp&&num)tail就是空) p2->next = temp; p2 = temp; temp = temp->next; } return dummpy->next; }};
还有一种极为简洁的写法,思路也是使用指针。与上述方法不同的是:上述方法将n和m中间的节点相当于是完全隔离出来进行反转,然后再次进行对接,也就是说将原链表断开了,单独处理n和m之间。下面这种方式是保证原链表不断的情况下进行n和m之间的反转,代码写的可以说是非常漂亮了。
class Solution {public: ListNode* reverseBetween(ListNode* head, int m, int n) { if(m == n) return head; n = n - m; ListNode* pre = new ListNode(0); ListNode* pre_stable = pre; pre->next = head; while(--m > 0) pre = pre->next; ListNode* p = pre->next; while(n-- > 0) { ListNode* q = p->next; p->next = p->next->next; q->next = pre->next; pre->next = q; } return pre_stable->next; }};
阅读全文
0 0
- 92. Reverse Linked List II
- 92. Reverse Linked List II
- 92. Reverse Linked List II
- 92. Reverse Linked List II
- 92. Reverse Linked List II
- 92. Reverse Linked List II
- 92. Reverse Linked List II
- 92. Reverse Linked List II
- 92. Reverse Linked List II
- 92. Reverse Linked List II
- 92. Reverse Linked List II
- 92. Reverse Linked List II
- 92. Reverse Linked List II
- 92. Reverse Linked List II
- 92. Reverse Linked List II
- 92. Reverse Linked List II
- 92. Reverse Linked List II
- 92. Reverse Linked List II
- 制作SSL证书-openssl命令
- Hibernate annotation 一对多,多对一
- 合并支付宝和微信的收钱码
- Hibernate annotation 多对多单向关联
- SSL协议及理论总结
- 92. Reverse Linked List II。
- Hibernate annotation 多对多双向关联(很少用)
- rmi实例
- 声明和定义
- ASP.NET状态管理之六(缓存Cache)
- jmx实例
- 用myeclipse的Hibernate 反向引擎 生成 数据库的 entity
- ACboy needs your help hdu 分组背包问题
- python高效编程技巧11(如何使用多线程)