leetcode 链表排序
2016-04-05 17:46
393 查看
对链表排序,用归并排序。题目要求空间时间复杂度为O(nlogn),但是空间复杂度为O(1)
1.自己写的程序,时间复杂度为O(nlogn),但是空间复杂度为O(n)
用快慢指针(分别走2步和1步)找到中间节点。但是最后排序的部分,用复制将排好序的部分粘贴会原来链表中,这个方法比较笨,而且增加空间复杂度,并不满足题目要求
leetcode 提交的时候说runtime error,但自己执行是通过的,可能因为时间复杂度的原因吧,需要后期再改
2.leetcode中大神的代码,这里粘贴是为了自己以后找起来方便
它是自底向上的,归并起来。step为1,2,4,8....
其余补充的部分,对链接初始化和输出打印部分
3.最后提交上去的版本,能运行通过且过程简单易懂,也是从别人那里看到的
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
void mergesort(ListNode* head, ListNode* as, ListNode* ae, ListNode* bs, ListNode* be){
vector<int> vec;
ListNode* ps = as;
ListNode* pe = be;
int i= 0;
int anum = ae - as;
int bnum = be - bs;
int ia = 0, ib = 0;
while(ia <= anum && ib <= bnum){
if(as->val <= bs->val){
vec.push_back(as->val);
as = as->next;
ia++;
}
else{
vec.push_back(bs->val);
bs = bs->next;
ib++;
}
}
while(ia <= anum){
vec.push_back(as->val);
as = as->next;
ia++;
}
while(ib <= bnum){
vec.push_back(bs->val);
bs = bs->next;
ib++;
}
int pnum = pe - ps;
int ip = 0;
while(ip <= pnum){
ps->val = vec[i++];
ps = ps->next;
ip++;
}
}
void merge(ListNode* head,ListNode* start, ListNode* end){
int hnum = end - start;
if(hnum > 0){
ListNode* former=start, * latter = start->next;
while(latter!= NULL && latter->next != NULL){
former = former->next;
if(latter->next->next == NULL)
latter = latter->next;
else
latter = latter->next->next;
}
merge(head,start,former);
merge(head,former->next,latter);
mergesort(head,start,former,former->next,end);
}
else
return;
}
ListNode* sortList(ListNode* head) {
if(head == NULL || head->next == NULL)
return head;
ListNode* p = head;
while(p->next != NULL)
p = p->next;
merge(head,head,p);
return head;
}
};
1.自己写的程序,时间复杂度为O(nlogn),但是空间复杂度为O(n)
用快慢指针(分别走2步和1步)找到中间节点。但是最后排序的部分,用复制将排好序的部分粘贴会原来链表中,这个方法比较笨,而且增加空间复杂度,并不满足题目要求
leetcode 提交的时候说runtime error,但自己执行是通过的,可能因为时间复杂度的原因吧,需要后期再改
void mergesort(ListNode* head, ListNode* as, ListNode* ae, ListNode* bs, ListNode* be){ vector<int> vec; ListNode* ps = as; ListNode* pe = be; int i= 0; int anum = ae - as; int bnum = be - bs; int ia = 0, ib = 0; while(ia <= anum && ib <= bnum){ if(as->val <= bs->val){ vec.push_back(as->val); as = as->next; ia++; } else{ vec.push_back(bs->val); bs = bs->next; ib++; } } while(ia <= anum){ vec.push_back(as->val); as = as->next; ia++; } while(ib <= bnum){ vec.push_back(bs->val); bs = bs->next; ib++; } int pnum = pe - ps; int ip = 0; while(ip <= pnum){ ps->val = vec[i++]; ps = ps->next; ip++; } } void merge(ListNode* head,ListNode* start, ListNode* end){ if(start < end){ ListNode* former=start, * latter = start; int snum = end - start; int latt = 0; while(latt + 2 <= snum){ former = former->next; latter = latter->next->next; latt = latt + 2; } if(latt+1 == snum){ latter = latter->next; } merge(head,start,former); merge(head,former->next,latter); mergesort(head,start,former,former->next,end); } else return; }
2.leetcode中大神的代码,这里粘贴是为了自己以后找起来方便
它是自底向上的,归并起来。step为1,2,4,8....
/** * merge the two sorted linked list l1 and l2, * then append the merged sorted linked list to the node head * return the tail of the merged sorted linked list */ ListNode* merge(ListNode* l1, ListNode* l2, ListNode* head){ ListNode *cur = head; while(l1 && l2){ if(l1->val > l2->val){ cur->next = l2; cur = l2; l2 = l2->next; } else{ cur->next = l1; cur = l1; l1 = l1->next; } } cur->next = (l1 ? l1 : l2); while(cur->next) cur = cur->next; return cur; } /** * Divide the linked list into two lists, * while the first list contains first n ndoes * return the second list's head */ ListNode* split(ListNode *head, int n){ //if(!head) return NULL; for(int i = 1; head && i < n; i++) head = head->next; if(!head) return NULL; ListNode *second = head->next; head->next = NULL; return second; } ListNode *sortList(ListNode *head) { if(!head || !(head->next)) return head; //get the linked list's length ListNode* cur = head; int length = 0; while(cur){ length++; cur = cur->next; } ListNode dummy(0); dummy.next = head; ListNode *left, *right, *tail; for(int step = 1; step < length; step <<= 1){ cur = dummy.next; tail = &dummy; while(cur){ left = cur; right = split(left, step); cur = split(right,step); tail = merge(left, right, tail); } } return dummy.next; }
其余补充的部分,对链接初始化和输出打印部分
/** * Definition for singly-linked list.*/ struct ListNode { int val; ListNode *next; ListNode(int x) : val(x), next(NULL) {} }; ListNode* init(int a[], int n){ ListNode* q = NULL, *head = NULL; for(int i = 0; i < n; i++){ ListNode* p = new ListNode(0); p->val = a[i]; if(i==0){//不要忽略头结点的赋值 head = q = p; continue; } q->next=p; q = q->next; } q->next = NULL; return head; } void prints(ListNode* head){ while(head){ cout<<head->val<<" "; head = head->next; } } int main(int argc, const char * argv[]) { int a[]={2,5,3,7,9,4,1,8}; //int a[]={2,1}; ListNode* head =new ListNode(0); head=init(a,8); ListNode* L = sortList(head); prints(L); return 0; }
3.最后提交上去的版本,能运行通过且过程简单易懂,也是从别人那里看到的
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
void mergesort(ListNode* head, ListNode* as, ListNode* ae, ListNode* bs, ListNode* be){
vector<int> vec;
ListNode* ps = as;
ListNode* pe = be;
int i= 0;
int anum = ae - as;
int bnum = be - bs;
int ia = 0, ib = 0;
while(ia <= anum && ib <= bnum){
if(as->val <= bs->val){
vec.push_back(as->val);
as = as->next;
ia++;
}
else{
vec.push_back(bs->val);
bs = bs->next;
ib++;
}
}
while(ia <= anum){
vec.push_back(as->val);
as = as->next;
ia++;
}
while(ib <= bnum){
vec.push_back(bs->val);
bs = bs->next;
ib++;
}
int pnum = pe - ps;
int ip = 0;
while(ip <= pnum){
ps->val = vec[i++];
ps = ps->next;
ip++;
}
}
void merge(ListNode* head,ListNode* start, ListNode* end){
int hnum = end - start;
if(hnum > 0){
ListNode* former=start, * latter = start->next;
while(latter!= NULL && latter->next != NULL){
former = former->next;
if(latter->next->next == NULL)
latter = latter->next;
else
latter = latter->next->next;
}
merge(head,start,former);
merge(head,former->next,latter);
mergesort(head,start,former,former->next,end);
}
else
return;
}
ListNode* sortList(ListNode* head) {
if(head == NULL || head->next == NULL)
return head;
ListNode* p = head;
while(p->next != NULL)
p = p->next;
merge(head,head,p);
return head;
}
};
相关文章推荐
- 使用C++实现JNI接口需要注意的事项
- [C/C++]反转链表
- 关于指针的一些事情
- c++ primer 第五版 笔记前言
- share_ptr的几个注意点
- C#实现基于链表的内存记事本实例
- Lua中调用C++函数示例
- Lua教程(一):在C++中嵌入Lua脚本
- Lua教程(二):C++和Lua相互传递数据示例
- C++联合体转换成C#结构的实现方法
- C++高级程序员成长之路
- C++编写简单的打靶游戏
- C++ 自定义控件的移植问题
- C++变位词问题分析
- C/C++数据对齐详细解析
- C++基于栈实现铁轨问题
- C++中引用的使用总结
- 使用Lua来扩展C++程序的方法
- C++中调用Lua函数实例
- Lua和C++的通信流程代码实例