地址:https://www.nowcoder.com/practice/3d281dc0b3704347846a110bf561ef6b
排行第一的大佬的方法:
class Solution {
public:
void reorderList(ListNode *head) {
// 由于链表不支持下标访问, 所以无法随机访问链表中任意位置的元素
// 因此我们可以利用线性表可以进行下标访问的特点, 直接的按照顺序访问指定的元素, 重建该链表即可
// 1. 初始化空数组res, 遍历整个链表, 将链表的节点存储到数组当中
// 2. 设置双指针 left right
// 根据题目的要求 res[left].next = res[right], 指针left+1
// 再次的拼接res[right]结点, res[right].next = res[left], 指针right -1
// 循环到 left >= right 之后跳出循环
if (head == nullptr)
return;
vector<ListNode*> res;
ListNode* node = head;
while (node != nullptr)
{
res.push_back(node);
node = node->next;
}
//线性容器将链表指针存起来
// 进行链表的节点的交换
int left = 0, right = res.size()-1;
while (left < right){ //vector(1,2,3,4,5,6)这里是指针链接,存放的是指针 ,
res[left]->next = res[right]; //最左边的下一个是最右边的,1(left)-6(right) 2-3-4-5,这里不是vector容器中的变化,是数字相应指针的变化
left += 1; //左边+1,继续这个操作,因为最右边的被拿走了,新的最右边的又被放到现在的左边的下一个
if (left == right)//vector(1,2(left),3,4,5,6(right))
break;
res[right]->next = res[left];//1-6(right)-2(left)-3-4-5
right -= 1; //vector(1,2(left),3,4,5(right),6)
}
//循环上面操作
//1-6-2-5-3(left)-4(right),链表 vector(1,2,3(left),4(right),5,6)
//left+1=right退出
//vector(1,2,3,4(right,right),5,6),1-6-2-5-3-4(right,left)
// 最后指向空
res[left]->next = nullptr;
}
};
代码作者:
https://www.nowcoder.com/profile/659277924
另一个比较难以理解的代码
class Solution {
public:
void reorderList(ListNode head) {
if (head == NULL || head->next == NULL || head->next->next == NULL)
return;
ListNode* left = &head;
ListNode** right = left; //left,right 都是head地址
while (*left != NULL && (*left)->next != NULL) //*left也就是head
{
while (*right != NULL && (*right)->next != NULL)
{//1(head,*left,*right)-2-3-4-5
right = &(*right)->next;//链接head下一个结点
}//1(head,*left)-2(*right)-3-4-5
//最终1(head,*left)-2-3-4-5(*right)
ListNode* tail = *right;//1(head,*left)-2-3-4-5(*right,tail)
*right = NULL;//1(head,*left)-2-3-4-5(tail)
tail->next = (*left)->next;//1(head,*left)-2-3-4-5(tail)-2-3-4
(*left)->next = tail;//1(left)-5(tail)-2-3-4
left = &(*left)->next->next;//1-5(tail)-2(left)-3-4
right = left;1-5(tail)-2(left,right)-3-4
}
return;
}
};
这个代码指针的运用很好,对现在的我来说理解比较艰难,不过还好勉强理解了
但是有个疑问。
ListNode* tail = *right;//1(head,*left)-2-3-4-5(*right,tail)
*right = NULL;//1(head,*left)-2-3-4-5(tail)
tail->next = (*left)->next;//1(head,*left)-2-3-4-5(tail)-2-3-4
这一步 tail链接left的链接1-2-3-4-5-2-3-4-5-。。。。不会一直链接下去吗。
当然既然程序运行正常,说明是不会一直链接下去。