Leetcode 每日一题——143. 重排链表

143. 重排链表

给定一个单链表 L:L0→L1→…→Ln-1→Ln ,
将其重新排列后变为: L0→Ln→L1→Ln-1→L2→Ln-2→…

你不能只是单纯的改变节点内部的值,而是需要实际的进行节点交换。

Leetcode 每日一题——143. 重排链表_第1张图片
这个问题的对象如果是支持下标索引的数组那就简单很多了,根据数组下标进行重组就可以,但是链表本身是不支持下标索引的,所以很自然地会想到先将链表中的每个节点存入数组数据结构中,这样就容易多了,这种解法的时间复杂和空间复杂度都是o(N),还有一种方案要稍复杂一点,那就是先找到链表的中间节点,然后翻转后半段链表,最后合并链表,这样可以做到常数的空间复杂度,下面是使用这个思路完成的C++代码:

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode() : val(0), next(nullptr) {}
 *     ListNode(int x) : val(x), next(nullptr) {}
 *     ListNode(int x, ListNode *next) : val(x), next(next) {}
 * };
 */
class Solution {
public:
    void reorderList(ListNode* head) {
        
        if(! head) return;

        ListNode *slow=head;
        ListNode *fast=head;
        ListNode *new_head=head;

        while(fast!=NULL && fast->next!=NULL)
        {
            slow=slow->next;
            fast=fast->next->next;
        }
        fast=slow->next;
        slow->next=NULL;
        while(fast)
        {
            ListNode *tmpnext=fast->next;
            fast->next=slow->next;
            slow->next=fast;
            fast=tmpnext;
        }
        fast=slow->next;
        slow->next=NULL;
        
        while(fast)
        {
            ListNode *tmpnext=fast->next;
            fast->next=new_head->next;
            new_head->next=fast;
            new_head=fast->next;
            fast=tmpnext;
        } 
    }
};

运行效果(感觉时间和空间复杂度都不优秀。。。。):
Leetcode 每日一题——143. 重排链表_第2张图片
下面我们用Python来实现一下第一个思路:

# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, val=0, next=None):
#         self.val = val
#         self.next = next
class Solution:
    def reorderList(self, head: ListNode) -> None:
        """
        Do not return anything, modify head in-place instead.
        """
        if not head:
            return
        nodeList=list()
        temHead=head
        while(temHead):
            nodeList.append(temHead)
            temHead=temHead.next
        left=0
        right=len(nodeList)-1
        while(left<right):
            tmpNext=nodeList[left].next
            nodeList[left].next=nodeList[right]
            nodeList[right].next=tmpNext
            left+=1
            right-=1
        nodeList[left].next=None

运行效果(时间复杂度方面好像还挺优秀的。。。。。):
Leetcode 每日一题——143. 重排链表_第3张图片
(应该是我代码没优化的原因,还要多加练习啊!)

来源:力扣(LeetCode)链接

你可能感兴趣的:(数据结构和算法,链表,数据结构,leetcode,算法)