LeetCode147. 对链表进行插入排序

关于链表问题,一般情况下要创建一个新的节点,使其next指针指向题目中给定的头节点。目的是方便对头节点进行操作。

我的想法,每次出现待插入节点,都需要从前往后找需要插入的节点位置。

class Solution {
    public ListNode insertionSortList(ListNode head) {
        if(head==null || head.next==null){
            return head;
        }
        //额外的节点,方便对头头节点进行操作。
        ListNode Onlyhead = new ListNode(-1);
        Onlyhead.next = head;

        //要交换的节点
        ListNode cur = head;
        while(cur.next!=null){
            //如果未发生交换,那么cur指针需要向后移动,如果交换了那么不需要移动。
            boolean falg = false;
            ListNode temp = cur.next;
            for(ListNode pre = Onlyhead;pre.next!=temp;pre = pre.next){
                if(pre.next.val>temp.val){
                    falg = true;
                    cur.next = temp.next;
                    temp.next = pre.next;
                    pre.next = temp;
                    break;
                }
            }
            if(!falg){
                cur = cur.next;
            }
        }
        return Onlyhead.next;
    }
}

结果发现,时间运行比较慢,运行了28ms,为什么,看下面分析。

什么是插入排序,插入排序中已排序好的数组或者链表的最后一个节点一定是最大的节点。

所以我的程序中进行了无效的遍历,只需要提前判断一下就好了。

class Solution {
    public ListNode insertionSortList(ListNode head) {
        if(head==null || head.next==null){
            return head;
        }
        //额外的节点,方便对头头节点进行操作。
        ListNode Onlyhead = new ListNode(-1);
        Onlyhead.next = head;

        //要交换的节点
        ListNode cur = head;
        while(cur.next!=null){
            //删除掉falg标识符,使其通过前后指针的val的大小方式来判断            
            ListNode temp = cur.next;
            if(cur.val<=temp.val){
                cur = cur.next;
                continue;
            }
            for(ListNode pre = Onlyhead;pre.next!=temp;pre = pre.next){
                if(pre.next.val>temp.val){
                    cur.next = temp.next;
                    temp.next = pre.next;
                    pre.next = temp;
                    break;
                }
            }
        }
        return Onlyhead.next;
    }
}

结果发现运行了5ms,还是慢,那么请问,为什么需要continue这个关键字。删掉改为if else条件就可以了。

class Solution {
    public ListNode insertionSortList(ListNode head) {
        if(head==null || head.next==null){
            return head;
        }
        //额外的节点,方便对头头节点进行操作。
        ListNode Onlyhead = new ListNode(-1);
        Onlyhead.next = head;

        //要交换的节点
        ListNode cur = head;
        while(cur.next!=null){
            //删除掉falg标识符,使其通过前后指针的val的大小方式来判断            
            ListNode temp = cur.next;
            if(cur.val<=temp.val){
                cur = cur.next;
            }else{
                for(ListNode pre = Onlyhead;pre.next!=temp;pre = pre.next){
                if(pre.next.val>temp.val){
                        cur.next = temp.next;
                        temp.next = pre.next;
                        pre.next = temp;
                        break;
                    }
                }
            }
        }
        return Onlyhead.next;
    }
}

还是慢,运行了3ms,怎么改,既然一定有一定要发生交换,那么我们就不用for循环

强调,对于链表问题,我们尽量使用while而不是用for循环。

class Solution {
    public ListNode insertionSortList(ListNode head) {
        if(head==null || head.next==null){
            return head;
        }
        //额外的节点,方便对头头节点进行操作。
        ListNode Onlyhead = new ListNode(-1);
        Onlyhead.next = head;

        //要交换的节点
        ListNode cur = head;
        while(cur.next!=null){
            //删除掉falg标识符,使其通过前后指针的val的大小方式来判断            
            ListNode temp = cur.next;
            if(cur.val<=temp.val){
                cur = cur.next;
            }else{
                ListNode pre = Onlyhead;
                while(pre.next.val<temp.val){
                    pre = pre.next;
                }
                cur.next = temp.next;
                temp.next = pre.next;
                pre.next = temp;
            }
        }
        return Onlyhead.next;
    }
}

然后发现还是3ms,时间运行上没变化,但是可读性比较高,已经不错了。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值