LeetCode 重排链表

给定一个单链表 L:L0→L1→…→Ln-1→Ln ,
将其重新排列后变为: L0→Ln→L1→Ln-1→L2→Ln-2→…
你不能只是单纯的改变节点内部的值,而是需要实际的进行节点交换。

示例 1:
给定链表 1->2->3->4, 重新排列为 1->4->2->3.
示例 2:
给定链表 1->2->3->4->5, 重新排列为 1->5->2->4->3.

思路分析:先扫描一遍链表,将链表的节点地址序列保存到容器中,然后根据对称的规律重排链表即可。(L0→Ln下标关于链表中心对称,L1→Ln-1下标关于链表中心对称…)

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
	void reorderList(ListNode* head) {
		vector<ListNode*> myVec;//保存链表序列
        //ptr用于扫描链表, endPtr用于记录重排后的尾端
		ListNode *ptr = head, *endPtr = head;
		//扫描链表
		while (ptr != NULL) {
			myVec.push_back(ptr);
			ptr = ptr->next;
		}
		int vecSize = myVec.size();
		if (vecSize <= 2) {
			return;
		}
        //首先放置原来的头、尾
		endPtr = head;
		endPtr->next = myVec[vecSize - 1];
		endPtr = endPtr->next;
		int nowIndex = 1;//即将访问的下一个节点
        int endIndex = vecSize / 2;//对称关系,截止下标
        if (vecSize % 2 == 0){//如果链表节点是偶数个,最后需要减少一对,因为后面还有一对
            endIndex -= 1;
        }
        //循环重排(对称性)
		while (nowIndex < endIndex) {
			endPtr->next = myVec[nowIndex];
			endPtr = endPtr->next;
			endPtr->next = myVec[vecSize - nowIndex - 1];
			endPtr = endPtr->next;
			++nowIndex;
		}
        //后面还有一个(如果是偶数那就还有一对)
		endPtr->next = myVec[nowIndex++];
		endPtr = endPtr->next;
		if (vecSize % 2 == 0) {
			endPtr->next = myVec[nowIndex++];
			endPtr = endPtr->next;
		}
        //最后需要封口
		endPtr->next = NULL;
	}
};

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/qq_41855420/article/details/87897499