Sort List(LeetCode)

题目:

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


思路:

  1. 因为题目要求O(n log n),在wiki上看了一下各个排序的复杂度,最后选择了归并排序(MergeSort)
  2. 在wiki上了解了一下归并算法的思想。
    • 归并算法建立在归并操作的基础之上
    • 归并操作是将两个排好序的序列合并成一个排好序的序列(具体算法看wiki上mergesort词条)
    • 利用分治思想,将整个序列等分成两个子序列(若为奇数,有一边长度会多1)
      • 这里,我先统计了list的长度len
      • 然后在len/2的地方(即左边子序列的尾部),将下一个节点作为右边子序列的头结点rhead
      • 令左边子序列尾部指向null,左边子序列头结点lhead指向原来的head
      • 则原来的list分开成两个lists,分别以lhead和rhead开头
    • 递归地,将两个子序列分别进行归并排序
    • 将排好序的两个子序列进行合并操作成一个序列
      • 这里用了一个小技巧
      • 先让head指向随便一个新建的ListNode节点
      • 等归并操作结束后,令head = head.next,则让head还原成真正的第一个节点
      • 这样避免了,必须先从两个子序列中找出最小的node赋给head



注意点:

  1. 内部类不能创建实例
    • 需要自建一个ListNode类作链表节点
    • 刚开始把ListNode建在类中作为内部类,发现不能建实例(即ListNode head = new ListNode(0) 不成功)
    • 后来只能把ListNode单独建一个类调用
  2. ListNode判断为空的方式
    • 不能直接作为boolean判断,即将设有ListNode型head,用if(head)判断head是否为空是不对的
    • 只能用if(head!=null)来判断




代码:

/**
 * Definition for singly-linked list.
 * class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) {
 *         val = x;
 *         next = null;
 *     }
 * }
 */
public class Solution {
	public ListNode sortList(ListNode head) {
		ListNode l = head;
		int len;
		for (len = 0; l != null; len++) {
			// compute the length of the list
			l = l.next;
		}
		if (len <= 1) {
			// if the list is null or has only one node, return the list
			return head;
		}
		ListNode lhead, rhead, temp;
		temp = head;
		// divide the list into two half ones
		for (int i = 1; i < len / 2; i++) {
			temp = temp.next;
		}
		rhead = temp.next;
		temp.next = null;
		lhead = head;
		lhead = sortList(lhead);
		// sort the left sub-list and right sub-list recursively
		rhead = sortList(rhead);
		// merge the sorted left sub-list and right sub-list into one sorted list
		head = merge(lhead, rhead);
		return head;
	}

	static ListNode merge(ListNode lhead, ListNode rhead) {
		ListNode head, temp;
		head = new ListNode(0);//let head initially be an any ListNode node
		temp = head;//temp tags the end of the list
		while (lhead != null && rhead != null) {
			if (lhead.val < rhead.val) {
				temp.next = lhead;
				lhead = lhead.next;
				temp = temp.next;
				temp.next = null;
			} else {
				temp.next = rhead;
				rhead = rhead.next;
				temp = temp.next;
				temp.next = null;
			}
		}
		if (lhead != null) {
			temp.next = lhead;
		} else {
			temp.next = rhead;
		}
		head = head.next;//let head be the real first node of the list
		return head;
	}
}






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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值