24. Swap Nodes in Pairs。

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.


这个题就是将临近的节点进行交换。理论上来说并不困难,想到了两种方法,但是效率都不高。。。
第一个就是直接在原先链表上进行交换,先标记当前节点的下一个节点,然后让当前节点直接指向下一个节点的下一个,就可以直接下一个节点隔开了。然后让当前节点的下一个节点指向当前节点。就完成了交换,需要再额外使用一个标记来记录交换位置之后的链表最后一个节点在哪。同时注意一下不要出现空指针异常就好了。

class Solution {
public:
    ListNode* swapPairs(ListNode* head) {
        if(!head || !head->next) {
            return head;
        }
        ListNode* p1 = NULL;
        ListNode* p2 = NULL;
        ListNode* tail = NULL;
        ListNode* result = head->next;

        while(head) {
            p1 = head;
            p2 = head->next;
            if(p2) {
                p1->next = p2->next;
                p2->next = p1;
            } else {
                tail->next = p1;
                break;
            }
            if(tail) {
                tail->next = p2;
                tail = p1;
            } else {
                tail = p1;
            }
            head = head->next;
        }
        return result;
    }
};

另一种方法就是使用queue的特性,先将后一个节点加入队列,然后将当前节点再加入队列,相当于将链表遍历一遍,然后遍历的同时交换位置存入队列。再遍历队列将各个节点串起来。

#include <iostream>
#include <queue>
using namespace std;

struct ListNode {
    int val;
    ListNode *next;
    ListNode(int x) : val(x), next(NULL) {}
};

class Solution {
public:
    ListNode* swapPairs(ListNode* head) {
        if(!head || !head->next) {
            return head;
        }

        queue<ListNode*> nodes;
        ListNode* start,* tail;

        while(head) {
            if(head->next) {
                nodes.push(head->next);
                //cout << "next:" << head->next->val << ",";
            }
            nodes.push(head);
            //cout << "head:" << head->val << endl;

            if(head->next) {
                head = head->next->next;
            } else {
                break;
            }
        }

        start = nodes.front();
        tail = start;
        nodes.pop();
        while(!nodes.empty()) {
            //cout << "queue:" << nodes.front()->val << ",";
            tail->next = nodes.front();
            tail = nodes.front();
            nodes.pop();
        }
        tail->next = NULL;
        return start;

        /*ListNode* tail = NULL;//用来指向交换后最后一个
        ListNode* temp;//用来标记两个需要交换的节点的第二个,head是第一个
        ListNode* result = head->next;


        while(head->next) {
            temp = head->next;
            head->next = temp->next;
            temp->next = head;

            if(tail) {
                tail->next = temp;
                tail = head;
            } else {
                tail = head;
            }
            head = head->next;
            if(!head) {
                break;
            }

        }
        return result;*/
    }
};

int main() {
    Solution s;


    ListNode node1(1);
    ListNode node2(2);
    ListNode node3(3);
    ListNode node4(4);
    ListNode node5(5);

    node1.next = &node2;
    //node2.next = &node3;
    //node3.next = &node4;
    //node4.next = &node5;

    ListNode* p = s.swapPairs(&node1);

    while(p) {
        cout << p->val;
        cout << endl;
        p = p->next;
    }

}


运行结果可能有误差。

这里写图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值