Leetcode 328. Odd Even Linked List

我的解法

没有什么需要推理的地方,要注意一开始要让cur走的比odd和even快,否则会导致cur的next被odd和even修改,代码里有注释。

ListNode *oddEvenList(ListNode *head) {
        if (!head) {
            return head;
        }
        ListNode *cur = nullptr, *headofOdd = head,
                 *headofEven = head->next ? head->next : nullptr;
        if (!headofEven) {
            return head;
        }
        ListNode *odd = headofOdd, *even = headofEven;
        cur = head->next->next;
        odd->next = even->next = nullptr;
        if (!cur) {
            odd->next = headofEven;
            return headofOdd;
        }
        int cnt = 3;
        while (cur) {
            std::cout << cur->val << std::endl;
            if (cnt & 1) {
                odd->next = cur;
                odd = cur;
            }  //	奇数
            else {
                even->next = cur;
                even = cur;
            }
            cnt++;
            cur = cur->next;
			// 这两处记得把连接切断,否则会死循环
            odd->next = nullptr;
            even->next = nullptr;
        }
        odd->next = headofEven;
        return headofOdd;
    }
};

但是这个解法非常慢,25ms只超过了5.12%的人,肯定不是正解,故STFW。

正解

因为遍历链表的过程不可能再加速了,所以我们可以确定,问题就出在cnt上,我们加入的计数器导致了速度变慢。
解释都写在注释里。

ListNode *oddEvenList(ListNode *head) {
		// 如果是空的或者只有一个点,就不用翻转了
		if(!head || !head->next) {
			return head;
		}
		auto cur = head, oddHead = cur, oddTail = cur;
		auto evenHead = cur->next, evenTail = evenHead;
		cur = cur->next->next;
		while(cur) {
			oddTail->next = cur;
			oddTail = oddTail->next;
			cur = cur->next;
			if(cur) {
				evenTail->next = cur;
				evenTail = evenTail->next;
				// 这里要记得再跳一下next,因为这个点已经处理过了
				cur = cur->next;
			}
			// 这里之所以不用把odd和even的next都置为nullptr,是因为原来的写法一次只操作奇数或者
			// 偶数当中的一个,奇数轮需要把偶数置空,反之同理,为了省去if判断,每次都全部置空
			// 现在每次都会操作两个,就不需要了
		}
		evenTail->next = nullptr;
		oddTail->next = evenHead;
		return oddHead;
	}
posted @ 2024-10-21 16:57  Gold_stein  阅读(3)  评论(0编辑  收藏  举报