墨菲定律: If anything can go wrong,it will.

本文深入探讨了墨菲定律的核心思想及其在行政管理中的实际应用,强调了面对不确定性时的准备和应对策略。通过实例分析,揭示了如何从悲观主义视角出发,积极面对工作中的挑战和失败,以及从中汲取的宝贵经验。

摩菲定理英语Murphy's Law),又译墨菲定律莫非定律,(香港译为梅菲定律),它的具体内容是“凡是可能出错的事必定会出错”,指的是任何一个事件,只要具有大于零的机率,就不能假设它不会发生。

墨菲定律主要内容是:事情如果有变坏的可能,不管这种可能性有多小,它总会发生。

墨菲定律是指“凡是可能出错的事均会出错。”(Anything that can go wrong will go wrong.)。引申为“所有的程序都有缺陷”,或“若缺陷有很多个可能性,则它必然会朝往令情况最坏的方向发展”。

行政管理涉及的因素非常复杂,单就人为而言,管理学家也是极难解释,故此,管理者自不能避免目标制订和执行永不出错,这个管理原则说明,如果一个危机将要发生,它总会出事,换言之,管理者需要时时刻刻做好准备,面对到来的失误和失​​败。

墨菲法则是管理哲学的一个论点,包含着悲观主义的元素,说明“得不喜,失不忧”,在工作上要时刻准备接受失败,有些人常常说凡事无不可为,只要一鼓作气往前冲,便能获得成功,可是,他们却忽略了一点,就是世上永无常胜将军,人生不免有挫折失败。

可是反过来说,我们亦可从乐观一方去想:“若要成功,总会成功”,墨菲理论没带有事情必坏或必好的成果,他只是让管理者知道,能发生的事,总会发生,换言之,管理者必须对所有可能会发生的事情作好周全的准备。

我想外国人之所以把东西弄的很好就是因为他们懂这个。他们是知道了如何把东西做到精益求精,要有严谨的态度,才把东西做得那么出色。我想这对我们是不是也应该有什么启示。比如生活中的一些小事:闯红绿灯,横穿马路,做产品时的一些细节。。。当面临这些时,我们是不是应该把这句话挂在耳边来警示自己呢?


你的代码试图用 **栈(`deque`)模拟先序遍历** 的方式将二叉树“原地”展开为链表(即变成右子树的单链),整体思路是正确的,但存在几个关键问题会导致行为不符合预期。 --- ## ❌ 你当前代码的问题分析 ```python class Solution: def flatten(self, root: Optional[TreeNode]) -> None: if not root or (not root.right and not root.left): return _list = deque([root.right, root.left]) # 先放右,再放左 → 出栈时先左后右 pre_p = root while _list: t = _list.pop() # 取出一个节点 pre_p.left = None pre_p.right = t # 当前节点接在右子树 pre_p = pre_p.right # 移动指针 if t: if t.right: _list.append(t.right) if t.left: _list.append(t.left) ``` ### 🔴 存在的问题: 1. **顺序错误:你想做的是“根→左→右”,但压栈顺序应为“右、左”才能保证出栈是“左、右”** - ✅ 正确:先访问左子树 → 所以左要后入栈(因为栈是 LIFO) - ❌ 你写的是:`[root.right, root.left]` → `left` 先出栈 → 没问题 - ⚠️ 但在后续循环中又 **先 push right 再 push left** → 这会导致 **left 后出,破坏先序** 2. **逻辑混乱:你在主循环中不断修改 `_list`,但没有控制访问顺序与连接顺序一致** 3. **最终结果可能不是连续的右链**,特别是当某些分支较深时。 --- ## ✅ 正确解法一:递归 + 后序处理(推荐) 核心思想: > 对每个节点,递归地把左右子树展平,然后拼接成: > > `当前节点 → 左子树展开部分 → 右子树展开部分` > > 并且所有节点只有右孩子 ```python class Solution: def flatten(self, root: Optional[TreeNode]) -> None: """ Do not return anything, modify root in-place instead. """ if not root: return self.flatten(root.left) self.flatten(root.right) # 保存原来的左右子树 left = root.left right = root.right # 清空左子树 root.left = None # 先接入左子树到右边 root.right = left # 找到当前右链的末尾 curr = root while curr.right: curr = curr.right # 把原来的右子树接在最后 curr.right = right ``` ### ✅ 示例演示 ``` 1 / \ 2 5 / \ \ 3 4 6 展开后: 1 → 2 → 3 → 4 → 5 → 6 (全部在右子树) ``` ### 🔍 解释: - 使用后序遍历,先处理子树再合并 - 把左子树移到右边,然后把原右子树接到左子树展开后的末尾 - 时间复杂度:O(n),每个节点访问一次 - 空间复杂度:O(h),递归栈深度 --- ## ✅ 正确解法二:迭代 + 栈(模拟先序遍历) 更接近你的原始想法。使用栈实现先序遍历(根 → 左 → 右),但连接成右链。 ```python from collections import deque class Solution: def flatten(self, root: Optional[TreeNode]) -> None: if not root: return stack = [root] prev = None # 记录上一个访问的节点,用于链接 while stack: node = stack.pop() if node.right: stack.append(node.right) if node.left: stack.append(node.left) # 断开左右,构建右链 node.left = None if prev: prev.right = node prev = node ``` ### ✅ 关键点: - 压栈顺序:先右后左 → 保证左先出栈(符合先序) - `prev` 指针记录前驱,将其 `right` 指向当前节点 - 当前节点 `left` 设为 `None` --- ## ✅ 正确解法三:Morris 遍历法(O(1) 空间) 利用线索二叉树的思想,在不使用栈的情况下完成先序遍历并展开。 ```python class Solution: def flatten(self, root: Optional[TreeNode]) -> None: curr = root while curr: if curr.left: # 找到左子树的最右节点 predecessor = curr.left while predecessor.right: predecessor = predecessor.right # 将右子树接到左子树最右节点的右边 predecessor.right = curr.right # 把左子树移到右子树位置 curr.right = curr.left curr.left = None # 继续处理下一个节点 curr = curr.right ``` ### ✅ 优势: - 时间 O(n),空间 O(1) - 不使用递归或栈 ### 🔍 思路: 对于每个有左孩子的节点: 1. 找其左子树的“先序后继”的前驱(其实就是左子树的最右下角) 2. 把它的右子树挂在那个位置 3. 把整个左子树移到右子树位置 4. 继续向右走 --- ## 🧪 测试样例验证 输入: ``` 1 / \ 2 5 / \ \ 3 4 6 ``` 输出(所有节点只保留右指针): ``` 1 → 2 → 3 → 4 → 5 → 6 ``` --- ## ❌ 为什么你原来的代码不行? 你用了 `deque([root.right, root.left])`,这没问题,但之后: ```python if t: if t.right: _list.append(t.right) if t.left: _list.append(t.left) ``` 👉 这相当于:**先压右,再压左** → 出栈时是 **左先于右**?不对! - 栈是 LIFO:先压 `right`,再压 `left` → 出栈时 `left` 先出 → 正确! - 所以这个部分其实是对的! 但还有一个致命问题: > 你没有在每次连接后确保 `pre_p` 能正确指向链表末尾。一旦某个节点没有子节点,`t` 是 `None`,`pre_p = pre_p.right` 就会停在一个叶子上,后续继续追加就会出错。 而且初始状态你直接把 `root.right = root.left`,**丢失了原右子树!** --- ## ✅ 改进建议(修复你的代码) ```python from collections import deque class Solution: def flatten(self, root: Optional[TreeNode]) -> None: if not root: return stack = [root] prev = None while stack: node = stack.pop() if node.right: stack.append(node.right) if node.left: stack.append(node.left) node.left = None if prev: prev.right = node prev = node ``` 这才是你原本想写的逻辑的正确版本。 --- ###
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值