链表的奇偶重排
链表的奇偶重排
若能开辟空间,这道题的做法就很多了,之间放在容器里面翻转,但有没有更好的方法。
实际上这个奇偶重排简化一下,我们可以定义两个哨兵位的头节点,定义一个flag变量,分别插入对应的哨兵位头节点,然后两个节点再链接即可。
但实际上由于头节点并不会改变,并且第二个节点存在的情况下,实际上不需要头节点,可以采用循环遍历的方式去将对应的节点链上。即遍历一次,让奇数节点后面指向下一个奇数
even为奇数的遍历节点,odd为偶数的遍历节点。
偶数节点情况:
奇数条件
结论:
上述两种情况可以看出偶数节点后面一定跟着NULL,所以我们不需要置尾,而且even每次走到的都是偶数节点的最后一个位置,只需要将even节点链接到奇数节点的头即可。
为什么even指向的位置都是偶数节点的最后一个?
由于enev每次都会在odd的前面,odd进入临界条件后enev一定在他的前头,而odd最多走到nullptr,而enev就是他前面的位置,所以enev不会出现越界的问题,而odd可能走到nullptr,所以需要再判断。
/**
* struct ListNode {
* int val;
* struct ListNode *next;
* ListNode(int x) : val(x), next(nullptr) {}
* };
*/
class Solution {
public:
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
*
* @param head ListNode类
* @return ListNode类
*/
ListNode* oddEvenList(ListNode* head) {
if(head == nullptr)
return head;
// write code here
ListNode* even = head;//奇数
ListNode* odd = head->next;//偶数
ListNode* oddtmp = odd;//偶数
ListNode* pre = even;//记录even的前一个
while(odd && even->next && odd->next)
{
//迭代遍历
pre = even;
even->next = odd->next;
even = even->next;
odd->next = even->next;
odd = odd->next;
}
even->next = oddtmp;
return head;
}
};