【LeetCode】24. Swap Nodes in Pairs(C++)

地址:https://leetcode.com/problems/swap-nodes-in-pairs/

题目:

Given a linked list, swap every two adjacent nodes and return its head.

Example:

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

Note:

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

理解:

一开始就想到了直接改val,一看note不允许。。那就直接改喽。
为了处理链表的头,加了个头节点。用三个指针分别指向前一个,第一个和第二个节点。
修改的过程如下图所示:
在这里插入图片描述
注意三个指针保存了三个结点的地址,因此修改pr->next一定要晚于让pl->next=pr->next

实现1:

自己的实现,不过要比别人的慢一些。
下面更新了一版。

class Solution {
public:
	ListNode* swapPairs(ListNode* head) {
		if (!head || !head->next) return head;
		ListNode* nHead = new ListNode(0);
		nHead->next = head;
		ListNode* pre = nHead;
		ListNode *pl = pre->next, *pr = pre->next->next;
		while (1) {
			pl->next = pr->next;
			pr->next = pl;
			pre->next = pr;
			if (pl->next&&pl->next->next) {
				pre = pl;
				pl = pre->next;
				pr = pl->next;
			}
			else
				break;
		}
		return nHead->next;
	}
};

//后来仿照实现2修改的代码
class Solution {
public:
	ListNode* swapPairs(ListNode* head) {
		ListNode* pre = nullptr;
		ListNode* newHead=head;
		ListNode *pl = head, *pr=head;
		while (pl&&pl->next) {
			newHead = pl==pr ? pl->next : newHead;
			pr = pl->next;
			pl->next = pr->next;
			pr->next = pl;
			if (pre) {
				pre->next = pr;
			}
			pre = pl;
			pl = pl->next;
		}
		return newHead;
	}
};

实现2

下面是别人的实现。
其中retval只有第一次翻转会更新,就是新的头结点。巧妙的避免了要判断是否是头结点的情况。可能就是这里省了一点时间?

class Solution {
public:
    ListNode* swapPairs(ListNode* head) {
        ListNode* retval = head;
        ListNode* currval = head;
        ListNode* prevval = NULL;
        while (currval != NULL && currval->next != NULL)
        {
            retval = currval == retval ? currval->next : retval;
            ListNode* nextIter = currval->next->next;
            currval->next->next = currval;
            if (prevval != NULL)
            {
                prevval->next = currval->next;
            }
            currval->next = nextIter;
            prevval = currval;
            currval = nextIter;
        }
        return retval;        
    }
};

实现3:

使用了一个pointer to pointer,非常巧妙

class Solution {
public:
	ListNode* swapPairs(ListNode* head) {
		ListNode **pp = &head, *a, *b;
		ListNode **pp2;
		while ((a = *pp) && (b = a->next)) {
			a->next = b->next;
			b->next = a;
			*pp = b;
			ListNode *tmp = a->next;
			pp2 = &tmp;
			pp = &(a->next);
		}
		return head;
	}
};

分情况解释一下。

  • 如果为空,或只有一个,返回的就是head;
  • 不为空
    • 一开始,pp指向head指针,*pp=b使得head发生了改变;
    • 再后来,pp指向的是前一个链表节点的next域,*pp=b完成了pre->next=pr的工作。

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/Ethan95/article/details/84331675
今日推荐