对链表排序,时间开销O(nlogn), 空间开销O(1)

LeetCode 上的题目:

Sort a linked list in O(n log n)
time using constant space complexity.

最初想法是快排,因为要求空间开销O(1),但是某些case无法通过,大家懂得,快排最坏时间开销O(n^2)

所以还是得用merge sort,对于数组merge sort一般需要O(n)空间开销,但是也有in-place merge sort可以做到O(1)空间开销,这个太复杂,

总是记不住。

但是对于链表,做到O(1)空间开销还是相对简单的,只不过要注意一些边界条件。

public ListNode sortList(ListNode head)
	{
		if(head==null||head.next==null)
            return head;

		ListNode tail=head;
		int len=1;
        while(tail.next!=null)
        {
            tail=tail.next;
            len++;
        }

        head=mergeSort(null,head,len);
        return head;
	}

	// return the head of sorted list.
	private ListNode mergeSort(ListNode preHead,ListNode head, int len) {

		if(head==null||len<=1)
			return head;

		int left=len/2;
		int right=len-left;
		//sort left part
		head=mergeSort(preHead,head,left);
		//sort right part
		ListNode pMid=head;
		for(int i=0;i<left-1;i++)
		{
			pMid=pMid.next;
		}
		mergeSort(pMid,pMid.next,right);

		//p1 points to left part head,p2 points to right part head
		ListNode p1=head,p2=pMid.next;
		ListNode pre1=preHead,pre2=pMid;

		//new head is little one between left head and right head.
		if(p1.val>p2.val)
			head=p2;

		while(left>0&&right>0)
		{
			//if p2.val<p1.val move p2 previous to p1.
			if(p1.val>p2.val)
			{	

				//delete p2
				pre2.next=p2.next;
				//add p2 previous to p1
				p2.next=p1;
				if(pre1!=null)
				{
					pre1.next=p2;
				}
				//pre1 move to p2
				pre1=p2;
				//p2 move to pre2.next
				p2=pre2.next;
				right--;
			}
			else
			{
				pre1=p1;
				p1=p1.next;
				left--;
			}
		}
		return head;
	}
时间: 2024-09-20 14:49:21

对链表排序,时间开销O(nlogn), 空间开销O(1)的相关文章

Sort List &amp;&amp; Insertion Sort List (链表排序总结)

Sort List Sort a linked list in O(n log n) time using constant space complexity. Have you been asked this question in an interview?                   Yes               说明:归并排序: 时间 O(nlogn),空间 O(1). 每次将链表一分为二, 然后再合并.快排(用两个指针) /** * Definition for sing

148. Sort List (java 给单链表排序)

题目:Sort a linked list in O(n log n) time using constant space complexity. 分析:给单链表排序,要求时间复杂度是O(nlogn),空间复杂度是O(1).时间复杂度为O(nlogn)的排序算法有快速排序和归并排序, 但是,对于单链表来说,进行元素之间的交换比较复杂,但是连接两个有序链表相对简单,因此这里采用归并排序的思路. 编码: public ListNode sortList(ListNode head) { if(hea

基本排序(四):索引指针排序、链表排序、关键字排序

1. 索引和指针排序 因为元素的数量或者数据量巨大等原因,我们不希望频繁移动要排序的元素.因此,不移动元素的排序方法是维持一个索引数组或者索引指针,而排序的目标就是重排索引数组或指针. 如: 初始化for(int i = 0; i < N; i++) a[i] = &data[i]; 使用间接比较#define less(A, B) (*A < *B) 使用下标或指针排序的主要原因是避免扰乱要排序的数据.我们可以对只读文件进行排序,或者针对一个文件的多个关键字进行排序. 另一个原因是避

STL 中的链表排序

一直以来学习排序算法, 都没有在链表排序上下太多功夫,因为用得不多.最近看STL源码,才发现,原来即使是链表,也能有时间复杂度为O(nlogn)的算法, 大大出乎我的意料之外,一般就能想到个插入排序. 下面的代码就是按照源码写出的(去掉了模板增加可读性),注意forward_list是C++11新加的单向链表,这里选这个是因为它更接近我们自己实现链表时的做法. void sort_list(forward_list<int>& l){ auto it = l.begin(); if (

链表插入和删除,判断链表是否为空,求链表长度算法的,链表排序算法演示——C语言描述

关于数据结构等的学习,以及学习算法的感想感悟,听了郝斌老师的数据结构课程,其中他也提到了学习数据结构的或者算法的一些个人见解,我觉的很好,对我的帮助也是很大,算法本就是令人头疼的问题,因为自己并没有学习过算法的系统性的课程,现在还是处于不断摸索的阶段,好多算法题目根本就没有什么思路,导致自己对好多题目都很是头疼,就算是自己做过的一些算法的题目,再次遇到也还是不一定会做出来,他给出的建议就是,看懂别人的程序,然后自己去敲,一定会出错,然后调试,有错误接着调试,一直到没有错误为止,并且要时常的去复习

Leetcode 234 Palindrome Linked List 复杂度为时间O(n) 和空间(1)解法

1. 问题描写叙述 给定一个单链表,推断其内容是不是回文类型. 比如1–>2–>3–>2–>1.时间和空间复杂都尽量低. 2. 方法与思路 1)比較朴素的算法. 因为给定的数据结构是单链表,要訪问链表的尾部元素,必须从头開始遍历.为了方便推断.我们能够申请一个辅助栈结构来存储链表的内容,第一次遍历将链表节点值依次入栈,第二次遍历比較推断是否为回文. /** * Definition for singly-linked list. * struct ListNode { * int

链表排序

链表是一种在物理存储上非连续,非顺序的存储结构,数据的逻辑关系是通过指针链接次序实现的,链表通过一系列结点组成,结点可以在运行时动态生成.每个结点由两部分组成:数据域和存储下一结点的指针域.链表是一种常见的数据结构. 要想进行链表排序,首先得建立一个单链表,程序代码是由一个数组转化而来,代码如下: 先建立一个结点的结构体: struct node { int val; node *next; }; node* _initial_node() //生成一个空的链表 { node *head=new

【模板小程序】链表排序(qsort/insert_sort/merge_sort)

前言 本文章整理了链表排序的三种方法,分别是快速排序.插入排序.归并排序.为适应不同用途,先给出常用的int版本,再在此基础上抽象出类模板. 目录 一.针对整数的版本(常用) 文中链表定义 链表相关操作 三种排序方法 完整测试程序 二.模板版本(适用性广泛) 文中链表定义 链表相关操作 三种排序方法 完整测试程序 总结 参考文章 一.针对整数的版本(常用) 文中链表定义: 1 //definition for singly-linked list. 2 struct ListNode 3 { 4

C语言 链表排序

1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <assert.h> 4 5 typedef struct node{ 6 int data; // 存放数据 7 struct node* next; // 下一节点 8 }ListNode; 9 10 extern int CSort(); 11 12 ListNode *root = NULL;// 13 14 int main(int argc, char