Leetcode - Sort List

My code:

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) { val = x; }
 * }
 */
public class Solution {
    public ListNode sortList(ListNode head) {
        if (head == null)
            return null;
        int count = 0;
        ListNode temp = head;
        while (temp != null) {
            count++;
            temp = temp.next;
        }
        return sortList(head, count);
    }
    
    private ListNode sortList(ListNode head, int count) {
        if (count <= 1)
            return head;
        
        int left = 0;
        int right = 0;
        if (count % 2 == 0)
            left = count / 2;
        else
            left = count / 2 + 1;
        right = count - left;
        
        ListNode leftHead = head;
        ListNode rightHead = null;
        int countNode = 0;
        ListNode temp = head;
        while (temp != null) {
            countNode++;
            if (countNode == left) {
                rightHead = temp.next;
                temp.next = null;
                break;
            }
            else
                temp = temp.next;
        }
        
        ListNode subLeftHead = sortList(leftHead, left);
        ListNode subRightHead = sortList(rightHead, right);
        ListNode dummyNode = new ListNode(-1);
        ListNode tempDummy = dummyNode;
        int countLeft = 0;
        int countRight = 0;
        while (countLeft < left && countRight < right) {
            if (subLeftHead.val <= subRightHead.val) {
                tempDummy.next = subLeftHead;
                subLeftHead = subLeftHead.next;
                tempDummy = tempDummy.next;
                countLeft++;
            }
            else {
                tempDummy.next = subRightHead;
                subRightHead = subRightHead.next;
                tempDummy = tempDummy.next;
                countRight++;
            }
        }
        if (countLeft == left)
            tempDummy.next = subRightHead;
        else
            tempDummy.next = subLeftHead;
        
        return dummyNode.next;
    }
    
    public static void main(String[] args) {
        ListNode n1 = new ListNode(8);
        ListNode n2 = new ListNode(7);
        ListNode n3 = new ListNode(6);
        ListNode n4 = new ListNode(5);
        ListNode n5 = new ListNode(4);
        ListNode n6 = new ListNode(3);
        ListNode n7 = new ListNode(2);
        ListNode n8 = new ListNode(1);
        n1.next = n2;
        n2.next = n3;
        n3.next = n4;
        n4.next = n5;
        n5.next = n6;
        n6.next = n7;
        n7.next = n8;
        
        Solution test = new Solution();
        ListNode head = test.sortList(n1);
        while (head != null) {
            System.out.println(head.val);
            head = head.next;
        }
    }
}

My test result:

Paste_Image.png

这次作业说实话不难,但是要完全写出来还是有点细节的。
首先,一开始我很难理解,链表麻痹怎么排序啊,还是归并排序。
后来发现必须得统计结点个数,接下来就好做点了。
用递归么,一层层递归下去,用普林斯顿算法课的说法叫做, bottom -up.
分成一块一块,然后再一块块拼装起来。
思想还是归并排序的思想,在这里我想说一个小技巧,那就是, dummy node.
真的很好用,尤其对于链表,很多复杂情况不需要在考虑了。
还有这里有个细节,
因为我们要把一个链表切成两段,然后分别递归,事实上这两个子链表还是连接在一起的,所以我们需要人为得把他们切断,
即 temp.next = null;
然后再递归。这是一个注意点。
同时,链表操作我还是有些地方没注意到,像这道题目,通过dummy node来将两个子链表合二为一,并且排序,没有用到额外的空间,dummy node 就像是细线一样,将这些结点重新串在了一块儿。

**
总结: Merge Sort, LinkedList, Recursion
刚写代码,一个很久以前的朋友突然找我,上来第一句话就是,
以后去哪里发展?
很有社会上的口气。我就和他聊了开来,一开始是有提防心的,比如他问我在不在家,之类的,我都回避,但聊着聊着就聊开了。某人估计又要骂我傻逼了吧。
他要结婚了,然后一直说我了不起,本科,研究生的大学都很强,学历高。
说真的,我从来没觉得我的学校很强,觉得可以拿这个去比,从来没觉得。
但是,从他嘴中,我了解到了社会,尤其中国社会,原来这么看重学历。甚至高中是哪里的都很看重。那我应该更加自信点了,虽然以前我一直觉得一个人该有相当的本事再有相当的自信,现在看来,学历也是那么重要,即使你什么都不会。
但是,我现在很努力,为什么?就像我之前努力出国,为什么,真的不是为了学历。。当然学校是否有名也是有考虑的,但更多的,是想有一个好的环境让我去学习技术。所以其实我的出发点还是比较纯洁的,这也可能是我为什么能持续走下去的原因之一吧,因为我真的有这个需求,我很想学习这方面的知识。
女朋友的事,我这几天是有点操之过急了,毕竟她才培训一个礼拜啊,那么忙,身体也那么累,不像我回家还休息了一两天,然后之后也是懒散的学习。我真的把她当成了机器,虽然我的本心是好的,但我就是把她当成了机器,按照我的设计而去学习。这是不对的。
但同样,她也还是不够拼命,也许还没开始吧。希望下周可以真正开始了。
Because TOEFL is on the way.
**

Anyway, Good luck, Richardo!

My code:

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) { val = x; }
 * }
 */
public class Solution {
    public ListNode sortList(ListNode head) {
        if (head == null)
            return null;
        return sort(head);    
    }
    
    /** sort this list */
    private ListNode sort(ListNode head) {
        if (head == null || head.next == null)
            return head;
        ListNode slow = head;
        ListNode fast = head;
        /** find the middle node in the linkedlist using slow and fast pointers */
        while (fast.next != null && fast.next.next != null) {
            slow = slow.next; // jump 1 node for slow pointer
            fast = fast.next; // jump 2 nodes for fast pointer
            fast = fast.next;
        }
        
        ListNode leftHead = head;
        ListNode rightHead = slow.next;
        slow.next = null; // cut the connection between left and right sub linked list
        /** sort these two sub linked lists separately */
        leftHead = sort(leftHead); // make sure this sub lis is sorted
        rightHead = sort(rightHead);
        /** merge them into one sorted linked list */
        return merge(leftHead, rightHead);
    }
    
    /** merge these two sub sorted lists */
    private ListNode merge(ListNode leftHead, ListNode rightHead) {
        if (leftHead == rightHead)
            return leftHead;
        ListNode leftScanner = leftHead;
        ListNode rightScanner = rightHead;
        ListNode head;
        /** ensure the head node */
        if (leftHead.val < rightHead.val) {
            head = leftHead;
            leftScanner = leftScanner.next;
        }
        else {
            head = rightHead;
            rightScanner = rightScanner.next;
        }
        ListNode scanner = head;
        /** merge two linked lists until one of them is finished */
        while (leftScanner != null && rightScanner != null) {
            if (leftScanner.val < rightScanner.val) {
                scanner.next = leftScanner;
                leftScanner = leftScanner.next;
            }
            else {
                scanner.next = rightScanner;
                rightScanner = rightScanner.next;
            }
            scanner = scanner.next;
        }
        /** connect the rest of the other list to this new sorted list */
        if (leftScanner == null)
            scanner.next = rightScanner;
        else
            scanner.next = leftScanner;
        return head;
    }
    
    public static void main(String[] args) {
        Solution test = new Solution();
        ListNode a0 = new ListNode(3);
        ListNode a1 = new ListNode(2);
        ListNode a2 = new ListNode(4);
        a0.next = a1;
        a1.next = a2;
        ListNode head = test.sortList(a0);
        while (head != null) {
            System.out.println(head.val);
            head = head.next;
        }
    }
}

这道题目写了一会儿。以前的写法是不对的。因为我声明了一个dummy node需要内存,然后一层层下来就是, log(n) 的复杂度,就不再是常数级别了。
然后其他就差不多了,就是 merge sort the linked list

Anyway, Good luck, Richardo!

My code:

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) { val = x; }
 * }
 */
public class Solution {
    public ListNode sortList(ListNode head) {
        return helper(head);
    }
    
    private ListNode helper(ListNode head) {
        if (head == null || head.next == null) {
            return head;
        }
        ListNode slow = head;
        ListNode fast = head;
        while (fast.next != null && fast.next.next != null) {
            slow = slow.next;
            fast = fast.next.next;
        }
        ListNode right = slow.next;
        ListNode left = head;
        slow.next = null;
        left = helper(left);
        right = helper(right);
        return merge(left, right);
    }
    
    private ListNode merge(ListNode leftHead, ListNode rightHead) {
        if (leftHead == null) {
            return rightHead;
        }
        else if (rightHead == null) {
            return leftHead;
        }
        
        ListNode left = leftHead;
        ListNode right = rightHead;
        ListNode dummy = new ListNode(-1);
        ListNode curr = dummy;
        
        while (left != null || right != null) {
            if (left == null) {
                curr.next = right;
                curr = curr.next;
                right = right.next;
            }
            else if (right == null) {
                curr.next = left;
                curr = curr.next;
                left = left.next;
            }
            else if (left.val < right.val) {
                curr.next = left;
                curr = curr.next;
                left = left.next;
            }
            else {
                curr.next = right;
                curr = curr.next;
                right = right.next;
            }
        }
        
        return dummy.next;
        
    }
}

这道题目本身没有什么难度。空间复杂度是O(1),虽然用了dummy node,但是是在merge中使用的,使用完了后立刻释放。

Anyway, Good luck, Richardo! -- 08/17/2016

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,491评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,856评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,745评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,196评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,073评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,112评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,531评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,215评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,485评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,578评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,356评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,215评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,583评论 3 299
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,898评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,174评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,497评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,697评论 2 335

推荐阅读更多精彩内容