您的位置:首页 > Web前端 > Node.js

leecode 解题总结:24 Swap Nodes in Pairs

2017-02-01 12:21 459 查看
#include <iostream>
#include <stdio.h>
#include <vector>

using namespace std;
/*
问题:
Given a linked list, swap every two adjacent nodes and return its head.

For example,
Given 1->2->3->4, you should return the list as 2->1->4->3.

Your algorithm should use only constant space. You may not modify the values in the list, only nodes itself can be changed.

分析:交换链表中相邻两个结点,并且不是结点中的值交换。而且只能使用常量空间。
暴力破解:将链表从后向前每两个结点分成一组,记录每一组中两个结点的前驱和后继。
举例:
1->2->3->4->5->6
当前组的前驱将连接后一组的前驱
当前组的后继将会被连接在后一组的前驱

另外一种解法:直接对每一组内部结点先交换,重新确定每一组内部的连接指向,组外的连接指向则直接处理即可

需要注意的是:链表中第二个元素(如果有的话,会变成链表头部)

输入:
6(链表元素个数)
1 2 3 4 5 6

5
1 2 3 4 5

1
1
输出:
2 1 4 3 6 5
2 1 4 3 5
1

关键:
1 直接对每一组内部结点先交换,重新确定每一组内部的连接指向,组外的连接指向则直接处理即可
注意:设置最后一个结点指向为空
*/

struct ListNode {
int val;
ListNode *next;
ListNode(int x) : val(x), next(NULL) {}
};
class Solution {
public:
//交换结点
ListNode* swapPairs(ListNode* head) {
//如果链表为空,直接返回为空
if(NULL == head)
{
return NULL;
}
//如果链表只有一个元素,直接返回
if(NULL == head->next)
{
return head;
}

//下面需要将链表分成每两个结点一组
ListNode* node = head;
int count = 0;
vector< pair<ListNode* , ListNode*> > pairs;
while(node)
{
//刚好累计两个结点,加入元素中
pair<ListNode* , ListNode*> myPair;
myPair.first = node;
//如果第二个结点不空
if(NULL != node->next)
{
myPair.second = node->next;
pairs.push_back(myPair);
}
else
{
myPair.second = NULL;
pairs.push_back(myPair);
break;
}
//遍历第i + 2个结点
node = node->next->next;
}
//分组结束后,从后向前,先保存当前组组上一组的前驱pre和下一组的后继next,当前组的前驱指向下一组的后继,上一组的前驱指向当前组的后继
int size = pairs.size();
for(int i = 0 ; i < size ; i++)
{
if(i != size - 1)
{
pairs.at(i).second->next =  pairs.at(i).first;
ListNode* tempNode = pairs.at(i).first;
pairs.at(i).first = pairs.at(i).second;
pairs.at(i).second = tempNode;
}
else
{
//如果最后一组结点中第二个结点为空,直接跳过
if(NULL == pairs.at(i).second)
{
pairs.at(i).first->next = NULL;//设定最后一个结点指向空
continue;
}
else
{
pairs.at(i).second->next =  pairs.at(i).first;
ListNode* tempNode = pairs.at(i).first;
pairs.at(i).first = pairs.at(i).second;
pairs.at(i).second = tempNode;
pairs.at(i).second->next = NULL;
}
}
}
//每一组内部指向已经全部结束,下面进行组外连接:上一组的第二个结点连接到下一组的第一个结点即可
for(int i = 0 ; i < size - 1 ; i++)
{
pairs.at(i).second->next = pairs.at(i+1).first;
}
return pairs.at(0).first;
}
};

ListNode* buildList(vector<int>& datas)
{
if(datas.empty())
{
return NULL;
}
int size = datas.size();
ListNode* head = NULL;
ListNode* tail = NULL;
for(int i = 0 ; i < size ; i++)
{
if(i)
{
ListNode* node = new ListNode(datas.at(i));
tail->next = node;
tail = node;
}
else
{
head = new ListNode(datas.at(i));
tail = head;
}
}
return head;
}

void releaseList(ListNode* head)
{
while(head)
{
ListNode* node = head->next;
delete head;
head = node;
}
}

void print(ListNode* head)
{
if(NULL == head)
{
cout << "No result" << endl;
return;
}
ListNode* tempHead = head;
while(tempHead)
{
cout << tempHead->val << " ";
tempHead = tempHead->next;
}
cout << endl;
}

void process()
{
int nodeNum;
vector<int> datas;
int value;
Solution solution;
while(cin >> nodeNum)
{
datas.clear();
for(int i = 0 ; i < nodeNum ; i++)
{
cin >> value;
datas.push_back(value);
}
ListNode* head = buildList(datas);
ListNode* newHead = solution.swapPairs(head);
print(newHead);
releaseList(newHead);
}
}

int main(int argc , char* argv[])
{
process();
getchar();
return 0;
}

/*
if(i != size - 1)
{
}
//最后一组元素只需要获取前一组的前驱进行指向
else
{
//如果当前组第二个结点为空,则其本身无需交换,都无需修改
ListNode* secondNode = pairs.at(i).second;//当前组第一个结点现在要被其第二个结点指向
if(NULL == secondNode)
{
continue;
}
ListNode* firstNode = pairs.at(i).first;
ListNode* nextNode = pairs.at(i-1).first;

node->next = nextNode;
}
*/
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: