力扣-147-对链表进行插入排序
ListNode* insertionSortList(ListNode* head) {
// 待排节点需要和它前面的节点比较?单链表怎么比,单链表的反向遍历?
// 只能从头开始找
// 还要手写链表的交换?
if (!head->next) return head;
ListNode* dummyNode = new ListNode(-501);
dummyNode->next = head;
ListNode* iteratorNode = head->next;
ListNode* pre = head;
while (iteratorNode) {
for (ListNode* it = dummyNode->next, *prepre = dummyNode; it!=iteratorNode; prepre = it, it = it->next) {
if (it->val > iteratorNode->val) {
// 插
pre->next = iteratorNode->next;
prepre->next = iteratorNode;
iteratorNode->next = it;
break;
}
}
pre = iteratorNode;
iteratorNode = iteratorNode->next;
}
return dummyNode->next;
}
好容易写出来他说我超时😂本来用插入排效率就不高啊,那测试数据叫一个恐怖
看看有没有可以优化的地方
算法的时间主要花费在了查找上面,对于数据量大的测试用例而言会超时
要么就用二分查找,也就是二分插入,对前半段有序序列做二分查找
看了一眼官解,大概知道为什么效率这么差了:
对于数组插入排序来说,是直接和上一个比,但是对于链表,没法一直向上比较,就不得不从头开始比
但是!不是每个元素都需要从头开始比,这里我写的代码中pre是当前遍历节点的上一个节点,同时也是有序序列的最后一个节点,它是有序节点中最大的,所以只要大于它的就应该直接跳过,傻傻去从头开始比较的话费时不说,还完全没有意义
ListNode* insertionSortList(ListNode* head) {
if (!head->next) return head;
ListNode* dummyNode = new ListNode(-501);
dummyNode->next = head;
ListNode* iteratorNode = head->next;
ListNode* pre = head;
while (iteratorNode) {
if (iteratorNode->val < pre->val)
for (ListNode* it = dummyNode->next, *prepre = dummyNode; it != iteratorNode; prepre = it, it = it->next) {
if (it->val > iteratorNode->val) {
// 插
pre->next = iteratorNode->next;
prepre->next = iteratorNode;
iteratorNode->next = it;
break;
}
}
pre = iteratorNode;
iteratorNode = iteratorNode->next;
}
return dummyNode->next;
}
肯定是还有优化空间,用时相对于官解来说也还有差距