华为不再"遥遥领先"?
去年 9 月,华为技术有限公司申请注册两枚「遥遥领先」商标,国际分类为「科学仪器」和「运输工具」。
今年 1 月 20 日,商标流程信息显示,上述两枚商标被撤回注册申请,当前为无效状态。
如果只是商标被"驳回"的话,那很好理解。
毕竟如果这样的一句口号能作为商标的话,那么各类明着违反广告法的,带"最"字样的宣传语都能上了。
但如果是"撤回"的话,说明是华为主动行为,那就有节目效果了。
昨天,网传任正非在华为内部给余承东下了"禁令",每再提一句"遥遥领先"罚款一万。
不过该消息很快被余承东本人辟谣。
"遥遥领先"这个词汇最初出现在华为手机 Mate 40 的发布会上,华为常务董事、终端 BG CEO 余承东在介绍手机的各项性能时多次使用这个词。
而真正开始爆炸性普及则是在华为 2023 年 9 月 12 日的问界新 M7 发布会上,余承东 90 分钟内至少提及了五次"遥遥领先",二十多次"领先"。
后来的事情大家都知道了,"遥遥领先"甚至还入选了 2023 十大网络流行语。🤣
对于这么一句口号,余承东本人也曾经回应过。
2023 年 12 月 9 日,余承东在华为花粉年会上回应被网友调侃的"遥遥领先",称自己一场发布会有时最多有一个遥遥领先,甚至有时一个都没有,只有在这个领域领先比较多的时候才会说。
听起来可是位"实在派"演说家呀,大家怎么看呢?
...
回归主线。
来一道简单算法题。
题目描述
平台:LeetCode
题号:109
给定一个单链表的头节点 head
,其中的元素 按升序排序 ,将其转换为高度平衡的二叉搜索树。
本题中,一个高度平衡二叉树是指一个二叉树每个节点 的左右两个子树的高度差不超过 。
示例 1:
输入: head = [-10,-3,0,5,9]
输出: [0,-3,9,-10,null,5]
解释: 一个可能的答案是[0,-3,9,-10,null,5],它表示所示的高度平衡的二叉搜索树。
示例 2:
输入: head = []
输出: []
提示:
-
head
中的节点数在 范围内 -
递归分治
与上一题 108. 将有序数组转换为二叉搜索树 类似,但链表相对于数组,无法 找到构建当前 BST
根节点的“中点”下标。
一个仍可确保 时间复杂度(瓶颈在于需要创建 个节点),但需要 空间复杂度的做法是:对链表进行一次遍历,转成数组后套用上一题的做法。
一个不使用 空间复杂度的做法,需要每次遍历来找“中点”下标:起始我们先对 head
进行一次遍历,得到链表长度 ,随后仍然利用递归分治的思路进行构造,每次对入参的左右端点找“中点”,先通过直接结算的方式定位到偏移量 ,然后再通过从入参节点 head
出发往前走 的做法找到“中点”节点。
该做法每个节点的访问次数为在递归过程中被 所覆盖的次数,我们知道一个节点数量为 的平衡 BST
树高为 ,因此整体复杂度为 。
Java 代码:
class Solution {
public TreeNode sortedListToBST(ListNode head) {
int n = 0;
ListNode cur = head;
while (cur != null && ++n >= 0) cur = cur.next;
return build(head, 0, n - 1);
}
TreeNode build(ListNode head, int l, int r) {
if (l > r) return null;
int mid = l + r >> 1, t = mid - l;
ListNode cur = head;
while (t-- > 0) cur = cur.next;
TreeNode ans = new TreeNode(cur.val);
ans.left = build(head, l, mid - 1);
ans.right = build(cur.next, mid + 1, r);
return ans;
}
}
Python 代码:
class Solution:
def sortedListToBST(self, head: Optional[ListNode]) -> Optional[TreeNode]:
n = 0
cur = head
while cur:
n += 1
cur = cur.next
return self.build(head, 0, n - 1)
def build(self, head: ListNode, l: int, r: int) -> TreeNode:
if l > r:
return None
mid = l + r >> 1
t = mid - l
cur = head
while t > 0:
cur = cur.next
t -= 1
ans = TreeNode(cur.val)
ans.left = self.build(head, l, mid - 1)
ans.right = self.build(cur.next, mid + 1, r)
return ans
C++ 代码:
class Solution {
public:
TreeNode* sortedListToBST(ListNode* head) {
int n = 0;
ListNode* cur = head;
while (cur && ++n >= 0) cur = cur->next;
return build(head, 0, n - 1);
}
TreeNode* build(ListNode* head, int l, int r) {
if (l > r) return nullptr;
int mid = l + r >> 1, t = mid - l;
ListNode* cur = head;
while (t-- > 0) cur = cur->next;
TreeNode* ans = new TreeNode(cur->val);
ans->left = build(head, l, mid - 1);
ans->right = build(cur->next, mid + 1, r);
return ans;
}
};
TypeScript 代码:
function sortedListToBST(head: ListNode | null): TreeNode | null {
const build = function (head: ListNode | null, l: number, r: number): TreeNode | null {
if (l > r) return null;
let mid = l + r >> 1, t = mid - l;
let cur = head;
while (t-- > 0) cur = cur.next;
const ans = new TreeNode(cur!.val);
ans.left = build(head, l, mid - 1);
ans.right = build(cur!.next, mid + 1, r);
return ans;
}
let n = 0;
let cur = head;
while (cur != null && ++n >= 0) cur = cur.next;
return build(head, 0, n - 1);
}
-
时间复杂度: -
空间复杂度:
递归分治 - 中序遍历
由于给定的 nums
本身严格有序,而 BST
的中序遍历亦是有序。因此我们可以一边遍历链表,一边对 BST
进行构造。
具体的,我们仍然先对链表进行遍历,拿到链表长度 n
。递归构造过程中传入左右端点 l
和 r
,含义为使用链表中 部分节点,但不再在每次递归中传入当前头结点,而是使用全局变量 head
来记录。
递归构造过程中,计算“中点”位置 ,并根据如下流程进行构造:
-
使用 构建左子树,使用变量 left
保存当前左子树的根节点 -
构建完左子树后,全局变量 head
必然来到了“中点”位置,用其构建根节点ans
,并将根节点与此前构造的left
关联。同时让链表节点head
后移 -
使用 构建右子树,并将其挂载到根节点 ans
中
如此一来,即可确保「链表遍历」和「BST
构造」的同步性。
Java 代码:
class Solution {
ListNode head;
public TreeNode sortedListToBST(ListNode _head) {
head = _head;
int n = 0;
ListNode cur = head;
while (cur != null && ++n >= 0) cur = cur.next;
return build(0, n - 1);
}
TreeNode build(int l, int r) {
if (l > r) return null;
int mid = l + r >> 1;
TreeNode left = build(l, mid - 1);
TreeNode ans = new TreeNode(head.val);
head = head.next;
ans.left = left;
ans.right = build(mid + 1, r);
return ans;
}
}
Python 代码:
class Solution:
def sortedListToBST(self, head: Optional[ListNode]) -> Optional[TreeNode]:
self.head = head
n = 0
cur = self.head
while cur is not None:
n += 1
cur = cur.next
return self.build(0, n - 1)
def build(self, l: int, r: int) -> TreeNode:
if l > r:
return None
mid = l + r >> 1
left = self.build(l, mid - 1)
ans = TreeNode(self.head.val)
ans.left = left
self.head = self.head.next
ans.right = self.build(mid + 1, r)
return ans
C++ 代码:
class Solution {
public:
ListNode* head;
TreeNode* sortedListToBST(ListNode* _head) {
head = _head;
int n = 0;
ListNode* cur = head;
while (cur && n++ >= 0) cur = cur->next;
return build(0, n - 1);
}
TreeNode* build(int l, int r) {
if (l > r) return nullptr;
int mid = l + r >> 1;
TreeNode* left = build(l, mid - 1);
TreeNode* ans = new TreeNode(head->val);
ans->left = left;
head = head->next;
ans->right = build(mid + 1, r);
return ans;
}
};
TypeScript 代码:
function sortedListToBST(_head: ListNode | null): TreeNode | null {
const build =function(l: number, r: number): TreeNode | null {
if (l > r) return null;
const mid = l + r >> 1;
const left = build(l, mid - 1);
const ans = new TreeNode(head.val);
ans.left = left;
head = head.next;
ans.right = build(mid + 1, r);
return ans;
}
let head = _head;
let n = 0, cur = head;
while (cur && n++ >= 0) cur = cur.next;
return build(0, n - 1);
}
-
时间复杂度: -
空间复杂度:
最后
给大伙通知一下 📢 :
全网最低价 LeetCode 会员目前仍可用!!!
📅 年度会员:有效期加赠两个月!!; 季度会员:有效期加赠两周!!
🧧 年度会员:获 66.66 现金红包!!; 季度会员:获 22.22 现金红包!!
🎁 年度会员:参与当月丰厚专属实物抽奖(中奖率 > 30%)!!
专属链接:https://leetcode.cn/premium/?promoChannel=acoier
更多详情请戳 这里 。
我是宫水三叶,每天都会分享算法知识,并和大家聊聊近期的所见所闻。
欢迎关注,明天见。
更多更全更热门的「笔试/面试」相关资料可访问排版精美的 合集新基地 🎉🎉