LeetCode—Sort List解题报告
2013-12-19 15:21
501 查看
转载请注明:http://blog.csdn.net/ict2014/article/details/17416115
原题如下:
题目解析:
题目要求是对单链表进行从小到大排序,要求的时间复杂度为O(nlogn)。
从时间复杂度上分析此题,可以排除插入排序等O(n^2)的算法。
剩余两种排序算法,快速排序和合并排序。这两种算法究竟使用哪一个呢?此时我们要结合题目的数据结构——单链表进行分析,看哪一个更加方便快捷。快速排序的思想是选定一个pivot点,在该点之前的都小于此点,在该点之后的都大于此点,然后前半部分和后半部分分别递归排序,繁杂的操作就是调整指针。对于合并排序而言,从中间将链表拆分成两个链表,两个链表单独进行排序,排序后的两个链表进行合并操作即可。相比较而言,个人感觉合并排序比较简单一些,拆分成两个链表的时候,从链表的中间进行切分即可,合并两个有序的单链表也是很简单的操作。
题目代码:
我们实现合并排序,算法的时间复杂度为O(nlogn)。代码在leetcode上Accept.
注意程序的第31行,左移右移运算符的优先级小于加减乘除,第一次总是wrong answer,调试之后,才发现
“size-size>>1”的结果始终为0,因此,必须用括号将size>>1括起来。这是一点需要注意的小事项。
程序总体是合并排序的思想,22-34是合并排序的核心代码段。完成拆分、合并操作。75-84完成拆分操作,36-73完成合并两个有序单链表操作。代码只是用英文进行了简单的注释,如有疑问,可以互相讨论。
原题如下:
题目解析:
题目要求是对单链表进行从小到大排序,要求的时间复杂度为O(nlogn)。
从时间复杂度上分析此题,可以排除插入排序等O(n^2)的算法。
剩余两种排序算法,快速排序和合并排序。这两种算法究竟使用哪一个呢?此时我们要结合题目的数据结构——单链表进行分析,看哪一个更加方便快捷。快速排序的思想是选定一个pivot点,在该点之前的都小于此点,在该点之后的都大于此点,然后前半部分和后半部分分别递归排序,繁杂的操作就是调整指针。对于合并排序而言,从中间将链表拆分成两个链表,两个链表单独进行排序,排序后的两个链表进行合并操作即可。相比较而言,个人感觉合并排序比较简单一些,拆分成两个链表的时候,从链表的中间进行切分即可,合并两个有序的单链表也是很简单的操作。
题目代码:
我们实现合并排序,算法的时间复杂度为O(nlogn)。代码在leetcode上Accept.
/** * 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) { //List is empty or only one node if(head == NULL || head->next == NULL){ return head; } //List size int size = GetSize(head); //Combination Sort return CombinationSort(head, size); } //Combination Sort ListNode* CombinationSort(ListNode* head, const int& size){ if(size <= 1){ return head; } ListNode* head2 = ForwardNSteps(head, size>>1); ListNode* newHead1 = CombinationSort(head, size>>1); ListNode* newHead2 = CombinationSort(head2,size-(size>>1)); return CombineTwoList(newHead1, newHead2); } //Combine two sorted lists ListNode* CombineTwoList(ListNode* head1, ListNode* head2){ ListNode* newhead; ListNode* current1 = head1; ListNode* current2 = head2; if(head1->val < head2->val){ newhead = head1; current1 = current1->next; }else{ newhead = head2; current2 = current2->next; } ListNode* pre = newhead; while(current1 != NULL && current2 != NULL){ if(current1->val < current2->val){ pre->next = current1; pre = current1; current1 = current1->next; }else{ pre->next = current2; pre = current2; current2 = current2->next; } } if(current1 != NULL){ pre->next = current1; } if(current2 != NULL){ pre->next = current2; } return newhead; } //move forward N steps ListNode* ForwardNSteps(ListNode* head, const int& nsteps){ for(int i = 1; i < nsteps; ++i){ head = head->next; } ListNode* head2 = head->next; head->next = NULL; return head2; } //calculate the length of list int GetSize(ListNode* head){ int length = 0; while(head != NULL){ head = head->next; ++length; } return length; } };
注意程序的第31行,左移右移运算符的优先级小于加减乘除,第一次总是wrong answer,调试之后,才发现
“size-size>>1”的结果始终为0,因此,必须用括号将size>>1括起来。这是一点需要注意的小事项。
程序总体是合并排序的思想,22-34是合并排序的核心代码段。完成拆分、合并操作。75-84完成拆分操作,36-73完成合并两个有序单链表操作。代码只是用英文进行了简单的注释,如有疑问,可以互相讨论。
相关文章推荐
- leetCode解题报告之Sort List
- LeetCode: Insertion Sort List 解题报告
- [leetcode] 147. Insertion Sort List 解题报告
- Leetcode Insertion Sort List 解题报告
- LeetCode Sort List 解题报告
- leetcode 148. Sort List 解题报告
- LeetCode 解题报告 Sort List
- [LeetCode]Sort List,解题报告
- 景岁的Leetcode解题报告:147.Insertion Sort List (Java)
- leetCode解题报告之Insertion Sort List
- [leetcode] 148. Sort List 解题报告
- [Leetcode] 147. Insertion Sort List 解题报告
- LeetCode Sort List 解题报告
- 【LeetCode】Sort List 解题报告(对链表进行归并排序)
- [Leetcode] 148. Sort List 解题报告
- 【LeetCode】Insertion Sort List 解题报告
- LeetCode—Insertion Sort List 解题报告
- Leetcode Sort List 解题报告
- LeetCode解题报告—— Rotate List & Set Matrix Zeroes & Sort Colors
- LeetCode: Sort List 解题报告