当前位置: 首页 > news >正文

Leetcode148. 排序链表 中遇到的错误


分类: 链表
难度: 中等
情况: /*
备注: set比较器的写法;归并排序
tags:

  • leetcode

链接:148. 排序链表

代码

解法一:multiset

/*** Definition for singly-linked list.* struct ListNode {*     int val;*     ListNode *next;*     ListNode() : val(0), next(nullptr) {}*     ListNode(int x) : val(x), next(nullptr) {}*     ListNode(int x, ListNode *next) : val(x), next(next) {}* };*/
class Solution {
public:struct cmp { // set的比较器需要是一个类型bool operator() (const ListNode *a, const ListNode *b) const {return a->val < b->val;}};ListNode* sortList(ListNode* head) {ListNode *dumyhead = new ListNode(0);dumyhead->next = head;// set<ListNode *, cmp> s; // set不允许重复元素multiset<ListNode *, cmp> s;ListNode *cur = head;while (cur) {s.insert(cur);cur = cur->next;}cur = dumyhead;for (auto t:s) {cout << t->val << " ";cur->next = t;cur = cur->next;}// 断尾!cur->next = nullptr;  // 一定要加,防止形成环或访问已释放内存return dumyhead->next;}
};

解法二:归并排序

/*** Definition for singly-linked list.* struct ListNode {*     int val;*     ListNode *next;*     ListNode() : val(0), next(nullptr) {}*     ListNode(int x) : val(x), next(nullptr) {}*     ListNode(int x, ListNode *next) : val(x), next(next) {}* };*/
class Solution {
public:ListNode* sortList(ListNode* head) {if (!head || !head->next) return head;ListNode *fast = head, *slow = head;while (fast->next && fast->next->next) {fast = fast->next->next;slow = slow->next;}ListNode *left = head, *right = slow->next;// cout << left->val << " " << right->val << endl;slow->next = nullptr; // 断开链表left = sortList(left);right = sortList(right);// cout << left->val << " " << right->val << endl;return merge(left, right);}ListNode* merge(ListNode *l1, ListNode *l2) {ListNode *newhead = new ListNode(0);ListNode *cur = newhead;while (l1 && l2) {if (l1->val < l2->val) {cur->next = l1;l1 = l1->next;}else {cur->next = l2;l2 = l2->next;}cur = cur->next;}cur->next = l1 ? l1 : l2;return newhead->next;}
};

题解

set自定义比较器

    struct cmp { // set的比较器需要是一个类型bool operator() (const ListNode *a, const ListNode *b) const {return a->val < b->val;}};set<ListNode *, cmp> s;

遇到的错误

  1. set不允许重复元素,要用multiset

Line 14: Char 22: error: function cannot return function type 'bool (const ListNode *, const ListNode *)'14 |         bool oeprator() (const ListNode *a, const ListNode *b) {|                      ^

竟然是operator拼错了…

In file included from prog_joined.cpp:1:
In file included from ./precompiled/headers.h:50:
In file included from /usr/lib/gcc/x86_64-linux-gnu/14/../../../../include/c++/14/map:62:
/usr/lib/gcc/x86_64-linux-gnu/14/../../../../include/c++/14/bits/stl_tree.h:768:8: error: static assertion failed due to requirement 'is_invocable_v<const Solution::cmp &, ListNode *const &, ListNode *const &>': comparison object must be invocable as const759 |               is_invocable_v<const _Compare&, const _Key&, const _Key&>,|               ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

operator结尾没写const

Line 81: Char 9:
=================================================================
==21==ERROR: AddressSanitizer: heap-use-after-free on address 0x502000000078 at pc 0x5573084da1d6 bp 0x7ffd9b2b5ba0 sp 0x7ffd9b2b5b98
READ of size 8 at 0x502000000078 thread T0#0 0x5573084da1d5 in __ListNodeUtils__::freeList(ListNode*&) (solution+0x1ab1d5)#1 0x5573084b8738 in main solution.cpp:81:9#2 0x7f4075b2c1c9  (/lib/x86_64-linux-gnu/libc.so.6+0x2a1c9) (BuildId: 6d64b17fbac799e68da7ebd9985ddf9b5cb375e6)#3 0x7f4075b2c28a in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+

heap-use-after-free
代码里没有断开链表尾节点的next指针。在你用multiset重新连接链表节点时,需要显式断开尾节点的next,否则链表可能成环或者访问悬空指针。
原链表节点顺序被打乱,尾节点的next可能指向原链表中间某个节点,形成环。
dumyhead也最好使用局部变量ListNode dummyhead(0);

Line 46: Char 14: runtime error: member access within null pointer of type 'ListNode' (solution.cpp)
SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior prog_joined.cpp:55:14
    ListNode* merge(ListNode *l1, ListNode *l2) {ListNode *newhead = new ListNode(0);ListNode *cur = newhead->next;while (l1 && l2) {if (l1->val < l2->val) {cur = l1;l1 = l1->next;}else {cur = l2;l2 = l2->next;}cur = cur->next;}cur->next = l1 ? l1 : l2;return newhead->next;}

这段代码的问题出在: ListNode *cur = newhead->next;
这里把 cur 初始化为 newhead->next,但此时 newhead->nextnullptr,导致你在后续执行 cur->next = ... 时,相当于对空指针解引用,触发了 Undefined Behavior(未定义行为)

if (!head || !head->next) return nullptr;
这行的意思是:如果链表为空 或者 只有一个节点,就返回空指针。
但实际上,链表只有一个节点时就是排序好了的,应该返回这个节点本身,而不是 nullptr。

优化

还可以把递归改成迭代优化空间复杂度

http://www.dtcms.com/a/303016.html

相关文章:

  • 【LeetCode 热题 100】(一)哈希
  • 设计模式(十七)行为型:迭代器模式详解
  • c/c++ 函数返回指针和引用所引发的问题
  • Linux系统Centos7 安装mysql5.7教程 和mysql的简单指令
  • JVM 内存模型深度解析:原子性、可见性与有序性的实现
  • FFmpeg 安装与使用
  • 从JPEG到SER:小波+CNN如何横扫CVPR/ICASSP?
  • C#_索引器
  • 最新!Polkadot 更新 2025 路线图
  • 【C++】priority_queue的模拟实现
  • Tchebycheff变换简介
  • 应急响应案例处置(下)
  • Dify-14: 工作流API端点
  • gRPC 为 Sui 上更智能的数据访问奠定基础
  • 【Kubernetes】使用StatefulSet进行的资源调度,删除更新策略
  • Linux 应用程序组成
  • haproxy原理及实验演示(实现服务器集群的负载均衡)
  • 火线、零线、地线
  • 雷达系统设计学习:自制6GHz FMCW Radar
  • C++中std::variant的使用详解和实战代码示例
  • 三角洲摸金模拟器(简易版本)(开源)
  • 黑马JavaWeb【复习到哪更新到哪】
  • Coze Studio概览(二)
  • 【MySQL基础篇】:MySQL常用数据类型的选择逻辑与正确使用
  • Go语言-->变量
  • 【Practical Business English Oral Scene Interpretation】在职日常交流No.1~6
  • MySQL面试题及详细答案 155道(001-020)
  • 重构企业交互逻辑:云蝠智能 Voice Agent 的落地价值与实践指南
  • 设计模式(二十一)行为型:状态模式详解
  • 常见的未授权访问漏洞靶场-练习教程