leetcode 147. Insertion Sort List (链表插入排序)

Given the head of a singly linked list, sort the list using insertion sort, and return the sorted list’s head.

The steps of the insertion sort algorithm:

Insertion sort iterates, consuming one input element each repetition and growing a sorted output list.
At each iteration, insertion sort removes one element from the input data, finds the location it belongs within the sorted list and inserts it there.
It repeats until no input elements remain.
The following is a graphical example of the insertion sort algorithm. The partially sorted list (black) initially contains only the first element in the list. One element (red) is removed from the input data and inserted in-place into the sorted list with each iteration.

在这里插入图片描述
Constraints:

The number of nodes in the list is in the range [1, 5000].
-5000 <= Node.val <= 5000

本题是链表的插入排序,遍历单向链表的每个node,删除该node,插入到正确的位置,使整个链表的节点从小到大排列。

思路:
比较纠结的就是指针问题,用几个指针,怎么移动。

因为是单向链表,如果删除node的话,需要知道当前node的前一个节点preNode, 通过修改preNode.next来删除当前node

还需要维护一段已经排好序的链表,分解线就是当前node,它的前半段是已经排好序的,后半段是待删除和插入的部分
这两段都需要两个指针,一个指向前面节点的preNode, 一个指向当前节点的curNode

head节点是会变的,因为如果在head前插入node,head就需要重新指向最前面的node
为了不频繁变动head,我们重新声明一个newHead,最开始用newHead.next指向head,
那么后续只需要变动newHead.next即可,最后返回newHead.next

前半段我们可以不用两个指针,只用一个指针代替preNode和curNode, 怎么做到呢,这就是newHead的好处,
我们声明一个tmp,指向newHead,用tmp.next表示curNode, tmp本身表示preNode

另外,在遍历后半段preNode和curNode时,如果preNode <= curNode时可以直接跳过的,因为已经排好序了
preNode > curNode时,删掉curNode, 遍历前半段,那肯定想问了,遍历的终止条件是什么呢?
这时注意到这个遍历的前提是preNode > curNode, 那么肯定会有node的值>curNode, 一定会停下来插入值,插值结束后就跳出了

不要忘了删除完curNode后,把curNode移动到preNode.next的位置

//2ms
    public ListNode insertionSortList(ListNode head) {
        if(head == null || head.next == null) return head;
        ListNode newHead = new ListNode();
        newHead.next = head;
        
        ListNode tmpNode = newHead;
        ListNode preNode = head;
        ListNode curNode = head.next;
        
        while(curNode != null) {
            if(preNode.val <= curNode.val) {
                preNode = preNode.next;
                curNode = curNode.next;
            } else {
                tmpNode = newHead;
                while(tmpNode.next.val <= curNode.val) {
                    tmpNode = tmpNode.next;
                }
                preNode.next = curNode.next;
                curNode.next = tmpNode.next;
                tmpNode.next = curNode;
                curNode = preNode.next;
            }
            
        }
        return newHead.next;
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

蓝羽飞鸟

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值