【LeetCode】Reverse Linked List
来源:互联网 发布:手机视频录播软件 编辑:程序博客网 时间:2024/06/04 00:15
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.
Note:
Given m, n satisfy the following condition:
1 ≤ m ≤ n ≤ length of list.
翻转链表中第m个节点到第n个节点的部分
注意事项
m,n满足1 ≤ m ≤ n ≤ 链表长度
样例
给出链表1->2->3->4->5->null, m = 2 和n = 4,返回1->4->3->2->5->null
挑战
在原地一次翻转完成
【思路】头插法
整个链表翻转的一般做法:从前向后拿到一个值就扔到整个链表的头部。
即:
1,定义一个head节点指向链表的头部(头指针)
2,从前向后遍历链表,找到一个值就把这个值插入到head后面
PS: 链表的翻转之与head节点有关,即:仅翻转head节点后面的内容。 那翻转m到n的做法就简单了,即: 先空转m-1次,然后令当前的第m个节点为head,然后用“整个链表翻转的一般做法”翻转n-m次。
简述:
①空转m-1次,找到第m-1个结点,即开始反转的第一个结点的前驱(因为这样只需要end-start即可,无需end-start+1),记作head
②以head为起始节点遍历n-m次,将第i次是,将找到的结点插入到head->next中即可。
(1)Java
/** * Definition for ListNode * public class ListNode { * int val; * ListNode next; * } */public class Solution { public ListNode reverseBetween(ListNode head, int m, int n) { if (m >= n || head == null) { return head; } ListNode dummy = new ListNode(0); dummy.next = head; head = dummy; for (int i = 1; i < m; i++) { //空转from-1次,找到起始结点(效果:指针后移到pPre) if (head == null) { return null; } head = head.next; } ListNode premNode = head; //pPre是from的前驱结点 ListNode mNode = head.next; ListNode nNode = mNode, postnNode = mNode.next; for (int i = m; i < n; i++) { if (postnNode == null) { return nu3ll; } ListNode temp = postnNode.next; //向前翻转 postnNode.next = nNode; nNode = postnNode; postnNode = temp;//后移指针 } mNode.next = postnNode;//(翻转部分)尾部相接: 最后一次翻转结束后,postnNode在末端结点的后面(最后结点的下一个pNext),mNode为翻转的链表的最后一个结点。二者需要相连。 premNode.next = nNode;//(翻转部分)头部相接:premNode在头部(翻转前from的前驱结点,即反转部分的前一个个结点),nNode一直作为翻转部分的头结点。二者需要相连。 return dummy.next; }}//Version 21. 创建Dummynode 录下head.2. 找到m的前节点Pre(这样做是为了方便用插入法reverse linkedlist)3. 记录下Pre的下一个节点 reverseTail,它将会是Reversed link的尾部。4. 翻转指定区间的链表,翻到最后一个节点时,把reverseTail.next指向它的next。这样就把翻转链表与之后的链表接起来了。5. 返回dummynode的下一个节点。②public class ReverseBetween { public ListNode reverseBetween(ListNode head, int m, int n) { if (head == null || head.next == null) { return head; } if (m >= n) { return head; } ListNode dummy = new ListNode(0); dummy.next = head; ListNode pre = dummy; //1. get the pre node before m. for (int i = m; i > 1; i--) { pre = pre.next; } // record the tail of the reversed link. ListNode reverseTail = pre.next; pre.next = null; // reverse the link. ListNode cur = reverseTail; for (int i = n - m + 1; i > 0; i--) { if (i == 1) { // 这里是翻转段后的第一个元素 . reverseTail.next = cur.next; } ListNode tmp = cur.next; cur.next = pre.next; pre.next = cur; cur = tmp; } return dummy.next; }}
(2)C++
①class Solution { public: void reverse(ListNode *head) { ListNode *prev = NULL; while (head != NULL) { ListNode *temp = head->next;//将后面的结点向前翻转 head->next = prev; prev = head;//指针后移 head = temp; } } ListNode *findkth(ListNode *head, int k) {//空转k-1次,找到起始结点 for (int i = 0; i < k; i++) { if (head == NULL) { return NULL; } head = head->next; } return head; } ListNode *reverseBetween(ListNode *head, int m, int n) { ListNode *dummy = new ListNode(-1, head); ListNode *mth_prev = findkth(dummy, m - 1); ListNode *mth = mth_prev->next; ListNode *nth = findkth(dummy, n); ListNode *nth_next = nth->next; nth->next = NULL; reverse(mth); mth_prev->next = nth;//尾部相接 mth->next = nth_next; return dummy->next; }};②#include "stdafx.h"#include <iostream>#include <cstdio>using namespace std;typedef struct tagSNode{ int value; tagSNode* pNext; tagSNode(int v) :value(v), pNext(NULL) {}}SNode;void Reverse(SNode* pHead, int from, int to) { if (from >= to || pHead == NULL) { return ; } SNode* pCur = pHead->pNext; int i; for (i = 0; i < from - 1; i++) {//空转from-1次,找到起始结点(效果:指针后移到pPre) if (pHead == NULL) return; pHead = pCur; pCur = pCur->pNext; } SNode* pPre = pCur;//pPre是from的前驱结点 pCur = pCur->pNext;//pCur的i == from to--; SNode*pNext; for (; i < to - 1; i++) {//此前i == from - 1, 循环中:i从from - 1,到to - 1//效果:将指针从pCur(i == from)一个个向前翻转。 pNext = pCur->pNext; pCur->pNext = pHead->pNext; pHead->pNext = pCur; pPre->pNext = pNext; pCur = pNext; }}1void Print(SNode* sn) { SNode* p = sn->pNext; while (p) { if (p->pNext != NULL) { cout << p->value << " -> "; }else{cout << p->value;} p = p->pNext; } cout << endl;}void Destroy(SNode* p) { SNode* next; while (p) { next = p->pNext; delete p; p = next; }}int main(){ SNode* pHead = new SNode(0); int i; for (i = 0; i < 10; i++) { SNode* p = new SNode(rand() % 10); p->pNext = pHead->pNext; pHead->pNext = p; } Print(pHead); Reverse(pHead, 4, 8); Print(pHead); Destroy(pHead); return 0;}
阅读全文
1 0
- [LeetCode]Reverse Linked List
- [Leetcode] Reverse Linked List
- leetcode Reverse Linked List
- [LeetCode] Reverse Linked List
- [LeetCode]Reverse Linked List
- Leetcode---Reverse Linked List
- [leetcode] Reverse Linked List
- [leetcode]Reverse Linked List
- Leetcode Reverse Linked List
- [leetcode] Reverse Linked List
- leetcode Reverse Linked List
- Reverse Linked List[LeetCode]
- leetcode--Reverse Linked List
- LeetCode Reverse Linked List
- leetcode: Reverse Linked List
- [leetcode] Reverse Linked List
- LeetCode - Reverse Linked List
- LeetCode || Reverse Linked List
- ZeroBrane Studio 设置
- 【LeetCode】Partition List 链表划分
- Python之 @property 用法
- 关于jquery里面prop和attr的带示例详细对比,深度理解
- 文件系统学习1 四巨头
- 【LeetCode】Reverse Linked List
- phpstorm命令行运行console
- 28-SpringBoot——核心-数据缓存Cache
- GitChat · 安全 | 如何利用搜索引擎做一些「不可描述」的事情?
- BZOJ2442 修剪草坪
- 汉诺塔问题(基础)(java实现)
- 利用Annotation和Aop实现日志记录
- java虚拟机垃圾回收执行流程
- GitChat·DevOps | 如何结合 Scrum 和 Kanban