leetcode:147. 对链表进行插入排序

leetcode:147. 对链表进行插入排序

注意
当我们进行插入排序时,只会对应两种情况:

  1. 需要插入的数值 > 新数组的最后一项(即最大值)
  2. 对新数组由左至右遍历:需要插入的数值 < 新数组的某一个值

容易犯的错

  1. 需要插入的数值 > 新数组的最后一项(即最大值)
  2. 需要插入的数值 < 新数组的第一项(即最小值)
  3. 对新数组由左至右遍历:新数组的第 i 项 < 需要插入的数值 < 新数组的第 i+1 项

在遍历新数组时,当需要插入的数值小于新数组的第 i+1 项时,必定大于第 i 项。
并且遍历时,已经把 “需要插入的数值 < 新数组的第一项(即最小值)” 这种情况考虑到了。

思路1:遍历原链表生成新数组,对数组进行插入排序,在返回新链表

# 执行用时 : 132 ms, 在所有 Python3 提交中击败了95.13%的用户
# 内存消耗 : 16.5 MB, 在所有 Python3 提交中击败了5.37%的用户
class Solution:
    def insertionSortList(self, head: ListNode) -> ListNode:
        def insert_sort(oldArray):
            res = [oldArray.pop(0)]
            while(oldArray):
                curr, i = oldArray.pop(0), 0
                if(curr >= res[-1]):
                    res.append(curr)
                else:
                    while(not(res[i] > curr)):
                        i += 1
                    res.insert(i, curr)
            return res
            
        if(head == None or head.next == None):
            return head
        aArray, curr = [], head
        while(curr):
            aArray.append(curr.val)
            curr = curr.next
        newArray = insert_sort(aArray)
        newHead = ListNode('null')
        curr = newHead
        for i in newArray:
            curr.next = ListNode(i)
            curr = curr.next
        return newHead.next
// 执行用时 : 200 ms, 在所有 JavaScript 提交中击败了7.69%的用户
// 内存消耗 : 46.2 MB, 在所有 JavaScript 提交中击败了8.33%的用户
var insertionSortList = function(head) {
    function insert_sort(oddArray){
        let res = [];
        res.push(oddArray.shift());
        for(let tar of oddArray){
            if(res[res.length-1] <= tar){
                res.push(tar);
            }else{
                let i = 0;
                while(!(tar <= res[i])){i += 1};
                res.splice(i, 0, tar);
            }
        }
        return res
    }
    
    if(head == null || head.next == null){return head};
    let aArray = [], cur = head;
    while(cur){
        aArray.push(cur.val);
        cur = cur.next;
    }
    aArray = insert_sort(aArray);
    let aListHead = new ListNode('null'), curr = aListHead;
    for(let i of aArray){
        let newNode = new ListNode(i);
        curr.next = newNode;
        curr = curr.next;
    }
    return aListHead.next
};

思路2:创建新链表,取出旧链表元素,对元素在新链表中进行插入排序

# 执行用时 : 188 ms, 在所有 Python3 提交中击败了93.51%的用户
# 内存消耗 : 16.3 MB, 在所有 Python3 提交中击败了5.37%的用户
class Solution:
    def insertionSortList(self, head: ListNode) -> ListNode:
        if(head == None or head.next == None):
            return head
        newListHead = ListNode('null')
        nLHPrev = newListHead
        nLHPrev.next = ListNode(head.val)
        nLH = nLHPrev.next
        curr = head.next
        while(curr):
            if(nLH.val <= curr.val):
                nLH.next = ListNode(curr.val)
                nLHPrev = nLH
                nLH = nLH.next
            else:
                tar = newListHead
                while(tar.next.val < curr.val):
                    tar = tar.next
                newNode = ListNode(curr.val)
                newNode.next = tar.next
                tar.next = newNode
            curr = curr.next
        return newListHead.next
// 执行用时 : 84 ms, 在所有 JavaScript 提交中击败了98.90%的用户
// 内存消耗 : 37.1 MB, 在所有 JavaScript 提交中击败了16.67%的用户
var insertionSortList = function(head) {
    if(head == null || head.next == null){return head};
    let aListHead = new ListNode('null');
    let prevNode = aListHead;
    prevNode.next = new ListNode(head.val);
    let currNode = prevNode.next;
    let tar = head.next;
    while(tar){
        if(tar.val >= currNode.val){
            currNode.next = new ListNode(tar.val);
            prevNode = currNode;
            currNode = currNode.next;
        }else{
            let begin = aListHead;
            while(!(tar.val <= begin.next.val)){
                begin = begin.next;
            }
            let newNode = new ListNode(tar.val);
            newNode.next = begin.next;
            begin.next = newNode;
        }
        tar = tar.next;
    }
    return aListHead.next
};
// 执行用时 : 84 ms, 在所有 JavaScript 提交中击败了98.90%的用户
// 内存消耗 : 37.6 MB, 在所有 JavaScript 提交中击败了8.33%的用户
var insertionSortList = function(head) {
    if(head == null || head.next == null){return head};
    let aListHead = new ListNode('null');
    let prevNode = aListHead;
    prevNode.next = new ListNode(head.val);
    let currNode = prevNode.next;
    let tar = head.next;
    while(tar){
        if(tar.val >= currNode.val){
            currNode.next = new ListNode(tar.val);
            prevNode = currNode;
            currNode = currNode.next;
        }else if(tar.val <= aListHead.next.val){
            let newNode = new ListNode(tar.val);
            newNode.next = aListHead.next;
            aListHead.next = newNode;
        }else{
            let begin = aListHead.next
            while(!(begin.val <= tar.val && tar.val <= begin.next.val)){
                begin = begin.next
            }
            let newNode = new ListNode(tar.val);
            newNode.next = begin.next;
            begin.next = newNode;
        }
        tar = tar.next;
    }
    return aListHead.next
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值