#include <iostream>
#include <stdio.h>
#include <vector>
using namespace std;
/*
问题:
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位置前面的那个节点记为previous,
记录n位置后面的节点记为next,记录n位置对应的节点tail,
关键是这里的逆置好像有点问题。因为不能从后向前遍历
一遍应该是不可能的了。用一个数组存储位置m到n的节点
输入:
5(结点个数) 2(m) 4(n)
1 2 3 4 5
输出:
1 4 3 2 5
*/
struct ListNode {
int val;
ListNode *next;
ListNode(int x) : val(x), next(NULL) {}
};
class Solution {
public:
ListNode* reverseBetween(ListNode* head, int m, int n) {
if(NULL == head)
{
return NULL;
}
int count = 1;
vector<ListNode*> nodes;
ListNode* tempHead = head;
ListNode* tail = NULL;
ListNode* previous = NULL;
ListNode* next = NULL;
while(head)
{
if(m <= count && count <= n)
{
nodes.push_back(head);
//记录m节点的上一个节点
if(m == count)
{
previous = tail;
}
//记录n节点的下一个节点,退出
if(n == count)
{
next = head->next;
break;
}
}
tail = head;
head = head->next;
count++;
}
head = tempHead;
//接下来对位置m到位置n的所有节点进行逆置,每一次交换节点后,需要重新设定节点指向
//末尾节点被设置为头结点后,需要重新设置新的头结点指向原来头结点的后面一个节点
//头结点被设置为末尾节点,需要设置末尾节点前面的节点指向该新的末尾节点
int len = n - m + 1;
int j;
ListNode* temp;
for(int i = 0 ; i < len/2; i++)
{
j = len - i - 1;
temp = nodes.at(i);
nodes.at(i) = nodes.at(j);
nodes.at(j) = temp;
//设置新的头结点指向其后面的节点
if(i + 1 <= len - 1)
{
nodes.at(i)->next = nodes.at(i+1);
}
//设置新的头结点指向被其前面的节点所指向
if(i - 1 >= 0)
{
nodes.at(i-1)->next = nodes.at(i);
}
//设置原来尾节点前面的一个节点指向新的尾节点
if(j - 1 >= 0)
{
nodes.at(j-1)->next = nodes.at(j);
}
if(j + 1 <= len - 1)
{
nodes.at(j)->next = nodes.at(j+1);
}
}
//连接两个链表
if(previous)
{
previous->next = nodes.at(0);
}
if(nodes.at(len - 1))
{
nodes.at(len - 1)->next = next;
}
//这里要多加一个判断,如果是从链表头部就逆置,那么previous为空,此时应该返回nodes.at(0)
if(previous)
{
return head;
}
else
{
return nodes.at(0);
}
}
};
void print(ListNode* head)
{
if(!head)
{
cout << "no result" << endl;
}
ListNode* tempHead = head;
while(head)
{
cout << head->val << " ";
head = head->next;
}
cout << endl;
head = tempHead;
}
ListNode* buildList(vector<int>& nums)
{
if(nums.empty())
{
return NULL;
}
int size = nums.size();
ListNode* head ;
ListNode *tail;
ListNode* node;
for(int i = 0 ; i < size ; i++)
{
if(i)
{
node = new ListNode(nums.at(i));
tail->next = node;
tail = node;
}
else
{
head = new ListNode(nums.at(i));
tail = head;
}
}
return head;
}
void deleteList(ListNode* head)
{
ListNode* node;
while(head)
{
node = head->next;
delete head;
head = node;
}
}
void process()
{
vector<int> nums;
int value;
int num;
Solution solution;
vector<int> result;
int m , n;
while(cin >> num >> m >> n )
{
nums.clear();
for(int i = 0 ; i < num ; i++)
{
cin >> value;
nums.push_back(value);
}
ListNode* head = buildList(nums);
ListNode* newHead = solution.reverseBetween(head , m , n);
print(newHead);
deleteList(newHead);//删除节点了
}
}
int main(int argc , char* argv[])
{
process();
getchar();
return 0;
}
leecode 解题总结:92. Reverse Linked List II
最新推荐文章于 2023-04-30 18:52:36 发布