C++实现LeetCode(143.链表重排序)

 更新时间:2021年07月22日 15:42:09   作者:Grandyang  
这篇文章主要介绍了C++实现LeetCode(143.链表重排序),本篇文章通过简要的案例,讲解了该项技术的了解与使用,以下就是详细内容,需要的朋友可以参考下

[LeetCode] 143.Reorder List 链表重排序

Given a singly linked list LL0→L1→…→Ln-1→Ln,
reorder it to: L0→LnL1→Ln-1→L2→Ln-2→…

You may not modify the values in the list's nodes, only nodes itself may be changed.

Example 1:

Given 1->2->3->4, reorder it to 1->4->2->3.

Example 2:

Given 1->2->3->4->5, reorder it to 1->5->2->4->3.

这道链表重排序问题可以拆分为以下三个小问题:

1. 使用快慢指针来找到链表的中点,并将链表从中点处断开,形成两个独立的链表。

2. 将第二个链翻转。

3. 将第二个链表的元素间隔地插入第一个链表中。

解法一:

class Solution {
public:
    void reorderList(ListNode *head) {
        if (!head || !head->next || !head->next->next) return;
        ListNode *fast = head, *slow = head;
        while (fast->next && fast->next->next) {
            slow = slow->next;
            fast = fast->next->next;
        }
        ListNode *mid = slow->next;
        slow->next = NULL;
        ListNode *last = mid, *pre = NULL;
        while (last) {
            ListNode *next = last->next;
            last->next = pre;
            pre = last;
            last = next;
        }
        while (head && pre) {
            ListNode *next = head->next;
            head->next = pre;
            pre = pre->next;
            head->next->next = next;
            head = next;
        }
    }
};

我们尝试着看能否写法上简洁一些,上面的第二步是将后半段链表翻转,那么我们其实可以借助栈的后进先出的特性来做,如果我们按顺序将所有的结点压入栈,那么出栈的时候就可以倒序了,实际上就相当于翻转了链表。由于只需将后半段链表翻转,那么我们就要控制出栈结点的个数,还好栈可以直接得到结点的个数,我们减1除以2,就是要出栈结点的个数了。然后我们要做的就是将每次出栈的结点隔一个插入到正确的位置,从而满足题目中要求的顺序,链表插入结点的操作就比较常见了,这里就不多解释了,最后记得断开栈顶元素后面的结点,比如对于 1->2->3->4,栈顶只需出一个结点4,然后加入原链表之后为 1->4->2->3->(4),因为在原链表中结点3之后是连着结点4的,虽然我们将结点4取出插入到结点1和2之间,但是结点3后面的指针还是连着结点4的,所以我们要断开这个连接,这样才不会出现环,由于此时结点3在栈顶,所以我们直接断开栈顶结点即可,参见代码如下:

解法二:

class Solution {
public:
    void reorderList(ListNode *head) {
        if (!head || !head->next || !head->next->next) return;
        stack<ListNode*> st;
        ListNode *cur = head;
        while (cur) {
            st.push(cur);
            cur = cur->next;
        }
        int cnt = ((int)st.size() - 1) / 2;
        cur = head;
        while (cnt-- > 0) {
            auto t = st.top(); st.pop();
            ListNode *next = cur->next;
            cur->next = t;
            t->next = next;
            cur = next;
        }
        st.top()->next = NULL;
    }
};

参考资料:

https://leetcode.com/problems/reorder-list/

https://leetcode.com/problems/reorder-list/discuss/45175/Java-solution-with-stack

https://leetcode.com/problems/reorder-list/discuss/44992/Java-solution-with-3-steps

到此这篇关于C++实现LeetCode(143.链表重排序)的文章就介绍到这了,更多相关C++实现链表重排序内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • c语言读取obj文件转换数据的小例子

    c语言读取obj文件转换数据的小例子

    c语言读取obj文件转换数据的小例子,需要的朋友可以参考一下
    2013-03-03
  • Qt 自定义属性Q_PROPERTY不显示float类型的解决

    Qt 自定义属性Q_PROPERTY不显示float类型的解决

    这篇文章主要介绍了Qt 自定义属性Q_PROPERTY不显示float类型的问题及解决,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-11-11
  • C语言中操作字符串的函数详解

    C语言中操作字符串的函数详解

    这篇文章主要为大家详细介绍了C语言中操作字符串的函数,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下,希望能够给你带来帮助
    2022-03-03
  • C语言基于图形库实现双人贪吃蛇

    C语言基于图形库实现双人贪吃蛇

    这篇文章主要为大家详细介绍了C语言基于图形库实现双人贪吃蛇,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-05-05
  • C/C++ memset方法的误区

    C/C++ memset方法的误区

    memset 作为对内存初始化的函数,还是有不少坑和误区的,今天就来对这个函数作一个总结。避免后期使用不当踩入坑,需要的朋友可以参考下
    2021-04-04
  • C语言内存操作函数使用示例梳理讲解

    C语言内存操作函数使用示例梳理讲解

    这篇文章主要介绍了C语言库函数中的内存操作函数memcpy()、memmove()、memset()、memcmp()使用示例分析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2022-09-09
  • C++ Boost EnableIf函数使用介绍

    C++ Boost EnableIf函数使用介绍

    Boost是为C++语言标准库提供扩展的一些C++程序库的总称。Boost库是一个可移植、提供源代码的C++库,作为标准库的后备,是C++标准化进程的开发引擎之一,是为C++语言标准库提供扩展的一些C++程序库的总称
    2022-11-11
  • C++实现访问者模式的基础介绍

    C++实现访问者模式的基础介绍

    访问者模式表示一个作用于某对象结构中各元素的操作,它使我们可以在不改变各元素的类的前提下定义作用于这些元素的新操作。对C++访问者模式相关知识感兴趣的朋友一起看看吧
    2021-09-09
  • C++消息队列(定义,结构,如何创建,发送与接收)

    C++消息队列(定义,结构,如何创建,发送与接收)

    这篇文章主要介绍了C++消息队列(定义,结构,如何创建,发送与接收),消息队列是一种先进先出的队列型数据结构,实际上是系统内核中的一个内部链表
    2022-08-08
  • C语言实现最简单的剪刀石头布小游戏示例

    C语言实现最简单的剪刀石头布小游戏示例

    这篇文章主要介绍了C语言实现最简单的剪刀石头布小游戏,涉及C语言数组、随机数与数值运算等相关操作技巧,需要的朋友可以参考下
    2017-09-09

最新评论