排序链表—leecode148

在 O(n log n) 时间复杂度和常数级空间复杂度下,对链表进行排序。

示例 1:

输入: 4->2->1->3
输出: 1->2->3->4
示例 2:

输入: -1->5->3->4->0
输出: -1->0->3->4->5

思路1:暴力解决,拿出来,再放回去

 

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    ListNode* sortList(ListNode* head) {
        vector<int> temp;
        ListNode* h = head;
        while(h!=NULL){
            temp.push_back(h->val);
            h = h->next;
        }
        sort(temp.begin(),temp.end());
        ListNode* r = head;
        int i=0;
        while(r!=NULL){
            r->val = temp[i++];
            r = r->next;
        }
        return head;
    }
};

思路2:复杂度要求为nlog2n,能想到的就是快排,堆排,归并排序。快排要找到第n个数由于是链表只能顺序找,太慢了,所以pass;堆排的空间复杂度为O(n),pass,只剩下堆排了,利用快慢指针找到中间节点进行分段,合并利用合并两个有序链表的方法,前面有这道题,然后就是递归了。

class Solution {
public:
    ListNode* sortList(ListNode* head) {
        if(head == NULL || head->next == NULL)	//递归出口
            return head;
        ListNode* head1 = head;
        ListNode* head2 = getMiddle(head);
        head1 = sortList(head1);	//对前半段进行递归
        head2 = sortList(head2);	//对后半段进行递归
        return merge(head1, head2);
    }
    
    //归并
    ListNode* merge(ListNode* head1, ListNode* head2){
        ListNode* dummyHead = new ListNode(-1);
        ListNode* cur = dummyHead;
        while(head1 != NULL && head2 != NULL){
            if(head1->val > head2->val){
                cur->next = head2;
                head2 =  head2->next;
            }
            else{
                cur->next = head1;
                head1 = head1->next;
            }
            cur = cur->next;
        }
        if(head1 == NULL)
            cur->next = head2;
        if(head2 == NULL)
            cur->next = head1;
        return dummyHead->next;
    }
    
    //获取链表中间位置,并将链表从中间分为两个链表
    ListNode* getMiddle(ListNode* head){
    	//使用快慢节点方法寻找链表的中间节点
        ListNode *fast = head, *slow = head;
        while(fast->next != NULL && fast->next->next != NULL){
            slow = slow->next;
            fast = fast->next->next;
        }
        fast = slow;
        slow = slow->next;	//第二个链表的首节点
        fast->next = NULL;	//将原来的链表从中间断开
        return slow;	
    }
};

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值