华为高频手撕冲刺

简单题

两数之和

方法一,暴力破解,时间复杂度O(n^2),空间复杂度O(1)

class Solution:def twoSum(self, nums: List[int], target: int) -> List[int]:n=len(nums)for i in range(n):for j in range(i+1,n):if nums[i]+nums[j]==target:return[i,j]

方法二,哈希表,时间复杂度O(n),空间复杂度O(n)

思路:向右枚举j,将值和下标存入哈希表,然后再枚举左边的数i,找到对应下标。

class Solution:def twoSum(self, nums: List[int], target: int) -> List[int]:h={}# 向右枚举j,将值和下标存入哈希表,然后再枚举左边的数i,找到对应下标for j,x in enumerate(nums):if target-x in h:return [h[target-x],j]   h[x]=j

 移动零

方法一:把非零数都移到前面,其他数都赋值为0

时间复杂度:O(n),空间复杂度O(1)

class Solution:def moveZeroes(self, nums: List[int]) -> None:"""Do not return anything, modify nums in-place instead."""i=0for j in range(len(nums)):if nums[j]!=0:nums[i]=nums[j]i+=1for x in range(i,len(nums)):nums[x]=0return nums

方法二: 双指针

思路:快慢指针,快指针在前面遍历,如果找到非零数,就与慢指针交换,慢指针向前走一步,直到所有非零元素都移动到前面。

时间复杂度O(n),空间复杂度O(1)

class Solution:def moveZeroes(self, nums: List[int]) -> None:"""Do not return anything, modify nums in-place instead."""l=0for r in range(len(nums)):if nums[r]!=0:nums[l],nums[r]=nums[r],nums[l]l+=1return nums

反转字符串 

双指针

左右指针,互相交换,然后各走一步,遍历完就完成了反转

class Solution:def reverseString(self, s: List[str]) -> None:"""Do not return anything, modify s in-place instead."""l,r=0,len(s)-1while l<r:s[l],s[r]=s[r],s[l]l+=1r-=1return s

同构字符串

思路:index方法,遍历每一个字符,然后判断每一个字符首次出现的下标是否相等,如果相等的话,则是同构,不同的话则不是同构。

最坏的情况,因为index本身复杂度是n,时间复杂度O(n^2),空间复杂度O(1)

class Solution:def isIsomorphic(self, s: str, t: str) -> bool:for i in range(len(s)):if s.index(s[i]) != t.index(t[i]):return Falsereturn True 

反转链表

思路:反转链表后,意思就是指针更改方向,创建一个pre指针赋为None,创建一个cur指针赋值为头,让cur指针指向pre指针,然后再移动。最后返回pre指针即链表的新头节点。

注意:要存储cur指向的指针,不然会断开后面的连接

时间复杂度O(n),空间复杂度O(1)

# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, val=0, next=None):
#         self.val = val
#         self.next = next
class Solution:def reverseList(self, head: Optional[ListNode]) -> Optional[ListNode]:pre=Nonecur=headwhile cur:temp=cur.nextcur.next=prepre=curcur=tempreturn pre

字符串相加

 双指针,让两个指针指向尾部,模拟人工加法,处理好进位,然后再拼接起来

class Solution:def addStrings(self, num1: str, num2: str) -> str:res=""i,j,carry=len(num1)-1,len(num2)-1,0while i>=0 or j >=0:# 超出索引范围直接赋值为0,相当于长度短的数字前面填0,方便后续计算n1=int(num1[i]) if i>=0 else 0n2=int(num2[j]) if j>=0 else 0temp=n1+n2+carrycarry = temp//10res=str(temp%10)+resi,j=i-1,j-1# 循环结束时,如果carry为1,则加到头部,没有则直接返回结果return "1"+res if carry else res

找出字符串中第一个匹配项的下标

方法一:直接用Python的内置函数index或者find,可以用来寻找字符串中子串,如果能找到,则返回第一个下标,否则抛出异常。

时间复杂度O(n)

class Solution:def strStr(self, haystack: str, needle: str) -> int:try:return haystack.index(needle)except:return -1

 方法二:切片

 class Solution:def strStr(self, haystack: 'str', needle: 'str') -> 'int':for i in range(0, len(haystack) - len(needle) + 1):if haystack[i:i+len(needle)] == needle:return ireturn -1

最长和谐子序列 

 方法一:哈希表存储,用HashMap统计个数后,遍历的时候直接判断有没有相邻的数的个数统计答案即可

class Solution:def findLHS(self, nums: List[int]) -> int:cnt = defaultdict(int)ans=0for num in nums:cnt[num]+=1if num+1 in cnt:ans=max(ans,cnt[num]+cnt[num+1])if num-1 in cnt:ans=max(ans,cnt[num]+cnt[num-1])return ans

方法二:排序+双指针时间复杂度O(nlog(n)),空间复杂度O(1)

class Solution:def findLHS(self, nums: List[int]) -> int:nums.sort()left=0res=0for right in range(len(nums)):if nums[right]-nums[left]>1:left+=1if nums[right]-nums[left]==1:res=max(res,right-left+1)return res

存在重复元素

方法一:哈希集合,将数组转化为集合(会去掉重复元素),然后判断前后长度是否一致

class Solution:def containsDuplicate(self, nums: List[int]) -> bool:s=set(nums)if len(s)!=len(nums):return Trueelse:return False

 方法二:哈希表

class Solution:def containsDuplicate(self, nums: List[int]) -> bool:numset={}for i in nums:if i not in numset:numset[i]=1else:return Truereturn False

字符串中的第一个唯一字符

方法一:Counter法,统计字符串中每一个字符出现次数,然后遍历到第一个字符直接返回下标

时间复杂度:O(n^2),空间复杂度O(1)

class Solution:def firstUniqChar(self, s: str) -> int:l=Counter(s)for i in s:if l[i]==1:return s.index(i)return -1

方法二:哈希表,用哈希表存储每个字符,如果出现次数大于1则值为False,等于1则为True 

class Solution:def firstUniqChar(self, s: str) -> int:dic = {}for c in s:dic[c] = not c in dicfor i, c in enumerate(s):if dic[c]: return ireturn -1

罗马数字转整数

删除排序链表中的重复元素

快慢双指针,让快指针在前面探路,发现不重复元素,就放到慢指针后面,慢指针就往前一步,一直到遍历完整张表。此时从head到slow都是不重复元素,再断开slow后面的指针,即可去重。

# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, val=0, next=None):
#         self.val = val
#         self.next = next
class Solution:def deleteDuplicates(self, head: Optional[ListNode]) -> Optional[ListNode]:slow,fast=head,headif head is None:return Nonewhile fast:if fast.val!=slow.val:slow.next=fastslow=slow.nextfast=fast.nextslow.next=Nonereturn head

删除排序数组中的重复元素 

快慢指针,同上一题

class Solution:def removeDuplicates(self, nums: List[int]) -> int:if len(nums)==0:return 0slow,fast=0,0while fast<len(nums):if nums[fast]!=nums[slow]:slow+=1nums[slow]=nums[fast]fast+=1return slow+1

最长公共前缀

方法一:Python内置函数zip,可以把多个序列中的元素打包成一个元组,zip(*可迭代对象)

例如,flower,float,flew是三个数,使用zip函数处理后,

[f,f,f],[l,l,l].[o,o,e]...,因此只需要判断这些序列去重后长度是否为1,即可判断是否能作为公共前缀

class Solution:def longestCommonPrefix(self, strs: List[str]) -> str:l=0for i in zip(*strs):if len(set(i))>1:breakl+=1return strs[0][:l]

有效的括号

括号匹配,用栈来做最佳

方法一:栈+if-else循环

时间复杂度O(n),空间复杂度是O(n)

class Solution:def isValid(self, s: str) -> bool:if len(s)%2!=0:return Falsestk=[]for c in s:if c=="(":stk.append(")")elif c=="[":stk.append("]")elif c=="{":stk.append("}")elif not stk or stk.pop()!=c:return Falsereturn not stk

方法二:栈+哈希表 

思路:使用哈希表存储,键是左括号,值是右括号,遍历字符串,当遍历字符在哈希表中,将值压入栈中;如果栈为空,说明只有右括号,或者出栈元素跟当前元素不同,说明不匹配。

时空复杂度都是O(n)

class Solution:def isValid(self, s: str) -> bool:if len(s)%2!=0:return Falsestk=[]mp={'(':')','[':']','{':'}'}for c in s:if c in mp:stk.append(mp[c])elif not stk or stk.pop()!=c:return Falsereturn not stk

反转字符串中的元音字母

 对撞双指针,将元音字母顺序交换

class Solution:def reverseVowels(self, s: str) -> str:# a e i o u                                         #元音元素dic = {'a','e','i','o','u','A','E','I','O','U'}     #大小写元音元素集合作为判断依据pol = 0                                             #左指针por = len(s)-1                                      #右指针s_ = list(s)                                        #str类型数据无法直接查询in和not in,转换为listwhile pol < por:                                    #左右指针交错循环停止if s_[pol] in dic and s_[por] in dic:           #左右指针所指元素均在集合中s_[pol], s_[por] = s_[por], s_[pol]         #交换左右指针所指元素por -= 1                                    #右指针左移pol += 1                                    #左指针右移if s_[por] not in dic:                          #右指针所指元素不在集合中por -= 1                                    #右指针左移if s_[pol] not in dic:                          #左指针所指元素不在集合中pol += 1                                    #左指针右移return ''.join(s_)                                  #返回str格式数据

二进制转十进制

def binary_to_decimal(binary_array):# 将数组转换成字符串binary_str = ''.join(str(bit) for bit in binary_array)# 判断是否为负数is_negative = binary_str[0] == '1'if is_negative:# 对于负数,转换为原码后计算inverted = ['0' if b == '1' else '1' for b in binary_str]inverted_str = ''.join(inverted)# 加1操作decimal_value = -int(inverted_str, 2) + 1else:# 正数直接转换decimal_value = int(binary_str, 2)return decimal_value# 示例
binary_array = [1, 1, 1, 1]  # 表示-1(假设字长为4)
print(binary_to_decimal(binary_array))  # 输出: -1

反转二叉树

# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = Noneclass Solution:def invertTree(self, root: TreeNode) -> TreeNode:if not root:return Nonequeue=[root]while queue:node=queue.pop(0)if node.left:queue.append(node.left)if node.right:queue.append(node.right)node.left,node.right=node.right,node.leftreturn root

二叉树的中序遍历

快乐数 

 

中等题

三数之和

先给数组排序,固定好一个值,再创建两个对撞指针,遍历整张表,然后删除重复的元素。

class Solution:def threeSum(self, nums: List[int]) -> List[List[int]]:nums.sort()res = []n=len(nums)for i in range(n-2):x=nums[i]if i>0 and x==nums[i-1]:continuel=i+1r=n-1while l<r:s=x+nums[l]+nums[r]if s<0:l+=1elif s>0:r-=1else:res.append([x,nums[l],nums[r]])l+=1# 删除重复元素while l<r and nums[l]==nums[l-1]:l+=1r-=1while l<r and nums[r]==nums[r+1]:r-=1return res

 反转字符串中的单词

class Solution:def reverseWords(self, s: str) -> str:# 删除首尾空格s=s.strip()# 分割字符串strs=s.split()# 翻转单词列表strs.reverse()return " ".join(strs)

合并区间

 

两数相加

新建一个链表,使用虚拟头结点,然后计算两条链表的值,处理好进位

# 注意:python 代码由 chatGPT🤖 根据我的 java 代码翻译。
# 本代码的正确性已通过力扣验证,如有疑问,可以对照我的 java 代码查看。class Solution:def addTwoNumbers(self, l1: ListNode, l2: ListNode) -> ListNode:# 在两条链表上的指针p1, p2 = l1, l2# 虚拟头结点(构建新链表时的常用技巧)dummy = ListNode(-1)# 指针 p 负责构建新链表p = dummy# 记录进位carry = 0# 开始执行加法,两条链表走完且没有进位时才能结束循环while p1 is not None or p2 is not None or carry > 0:# 先加上上次的进位val = carryif p1 is not None:val += p1.valp1 = p1.nextif p2 is not None:val += p2.valp2 = p2.next# 处理进位情况carry = val // 10val = val % 10# 构建新节点p.next = ListNode(val)p = p.next# 返回结果链表的头结点(去除虚拟头结点)return dummy.next

无重复字符的最长子串

滑动窗口

class Solution:def lengthOfLongestSubstring(self, s: str) -> int:ans = left = 0window = set()  # 维护从下标 left 到下标 right 的字符for right, c in enumerate(s):# 如果窗口内已经包含 c,那么再加入一个 c 会导致窗口内有重复元素# 所以要在加入 c 之前,先移出窗口内的 cwhile c in window:  # 窗口内有 cwindow.remove(s[left])left += 1  # 缩小窗口window.add(c)  # 加入 cans = max(ans, right - left + 1)  # 更新窗口长度最大值return ans

 每日温度

创建一个列表,创建一个空单调栈,倒着遍历温度,如果当前栈中元素小于当前温度,则出栈,直到找到大于当前温度的元素,如果栈为空说明没有,则赋值为0,否则赋值为栈顶元素-当前下标

时间复杂度O(n),空间复杂度是O(n)

class Solution:def dailyTemperatures(self, temperatures):n = len(temperatures)res = [0]*n# 这里放元素索引,而不是元素s = []# 单调栈模板for i in range(n-1, -1, -1):while s and temperatures[s[-1]] <= temperatures[i]:s.pop()# 得到索引间距res[i] = 0 if not s else s[-1] - i# 将索引入栈,而不是元素s.append(i)return res

删除排序链表中重复元素II

class Solution:def deleteDuplicates(self, head: Optional[ListNode]) -> Optional[ListNode]:cur = dummy = ListNode(next=head)while cur.next and cur.next.next:val = cur.next.valif cur.next.next.val == val:while cur.next and cur.next.val == val:cur.next = cur.next.nextelse:cur = cur.nextreturn dummy.next

跳跃游戏

思路:初始化一个值,表示当前能到达的最大位置,然后遍历nums,如果max_i大于当前下标,且i+jump大于当前能到达最大位置,则更新,最后输出能否到达尾部。

时间复杂度O(n),空间复杂度O(1)

class Solution:def canJump(self, nums: List[int]) -> bool:max_i=0for i,jump in enumerate(nums):if max_i>=i and i+jump>max_i:max_i=i+jumpreturn max_i>=len(nums)-1

和为K的子数组

class Solution:def subarraySum(self, nums: List[int], k: int) -> int:s = [0] * (len(nums) + 1)for i, x in enumerate(nums):s[i + 1] = s[i] + xans = 0cnt = defaultdict(int)for sj in s:ans += cnt[sj - k]cnt[sj] += 1return ans

买卖股票的最佳时机

class Solution:def maxProfit(self, prices: List[int]) -> int:ans = 0min_pirce = prices[0]for p in prices:ans = max(ans, p - min_pirce)min_pirce = min(min_pirce, p)return ans

救生艇

class Solution:def numRescueBoats(self, people: List[int], limit: int) -> int:if people is None or len(people)==0:return 0# 创建对撞指针p1 = 0p2 = len(people)-1res = 0people.sort()while p1<=p2:# 如果头和尾相加小于限制,则头指针+1,表示可以坐一艘船if people[p1]+people[p2]<=limit:p1+=1# 如果超重,则尾指针-1,表示尾部单独坐一艘船p2-=1res+=1return res

整数转罗马数字

R = (("", "I", "II", "III", "IV", "V", "VI", "VII", "VIII", "IX"),  # 个位("", "X", "XX", "XXX", "XL", "L", "LX", "LXX", "LXXX", "XC"),  # 十位("", "C", "CC", "CCC", "CD", "D", "DC", "DCC", "DCCC", "CM"),  # 百位("", "M", "MM", "MMM"),  # 千位
)class Solution:def intToRoman(self, num: int) -> str:return R[3][num // 1000] + R[2][num // 100 % 10] + R[1][num // 10 % 10] + R[0][num % 10]

零钱兑换II

最后一块石头的重量II

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/882368.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

python 作业1

任务1: python为主的工作是很少的 学习的python的优势在于制作工具&#xff0c;制作合适的工具可以提高我们在工作中的工作效率的工具 提高我们的竞争优势。 任务2: 不换行 换行 任务3: 安装pycharm 进入相应网站Download PyCharm: The Python IDE for data science and we…

AnaTraf | TCP重传的工作原理与优化方法

目录 什么是TCP重传&#xff1f; TCP重传的常见触发原因 TCP重传对网络性能的影响 1. 高延迟与重传 2. 吞吐量的下降 如何优化和减少TCP重传 1. 优化网络设备配置 2. 优化网络链路 3. 网络带宽的合理规划 4. 部署CDN和缓存策略 结语 AnaTraf 网络性能监控系统NPM | …

餐饮店怎么标注地图位置信息?

随着市场竞争的日益激烈&#xff0c;商家若想在竞争中脱颖而出&#xff0c;就必须想方设法去提高自身的曝光度和知名度&#xff0c;为店铺带来更多的客流量。其中&#xff0c;地图标注便是一种简单却极为有效的方法。通过在地图平台上添加店铺位置信息&#xff0c;不仅可以方便…

Qt-系统文件相关介绍使用(61)

目录 描述 输⼊输出设备类 打开/读/写/关闭 使用 先初始化&#xff0c;创建出大致的样貌 输入框设置 绑定槽函数 保存文件 打开文件 提取文件属性 描述 在C/C Linux 中我们都接触过关于文件的操作&#xff0c;当然 Qt 也会有对应的文件操作的 ⽂件操作是应⽤程序必不…

【C语言】文件操作(1)(文件打开关闭和顺序读写函数的万字笔记)

文章目录 一、什么是文件1.程序文件2.数据文件 二、数据文件1.文件名2.数据文件的分类文本文件二进制文件 三、文件的打开和关闭1.流和标准流流标准流 2.文件指针3.文件的打开和关闭文件的打开文件的关闭 四、文件的顺序读写1.fgetc函数2.fputc函数3.fgets函数4.fputs函数5.fsc…

微信小程序上传组件封装uploadHelper2.0使用整理

一、uploadHelper2.0使用步骤说明 uploadHelper.js ---上传代码封装库 cos-wx-sdk-v5.min.js---腾讯云&#xff0c;对象存储封装库 第一步&#xff0c;下载组件代码&#xff0c;放置到自己的小程序项目中 第二步、 创建上传对象&#xff0c;执行选择图片/视频 var _this th…

npm install进度卡在 idealTree:node_global: sill idealTree buildDeps

ping一下源&#xff1a;ping http://registry.npm.taobao.org/ ping不通&#xff0c;原因&#xff1a;原淘宝npm永久停止服务&#xff0c;已更新新域名~~震惊&#xff01;&#xff01;&#xff01; 重新安装&#xff1a;npm config set registry https://registry.npmmirror.c…

推荐?还是踩雷?3款中英互译软件大盘点,你真的选对了吗?

作为一个爱到处跑的人&#xff0c;我特别明白旅行的时候能说会道有多重要。不管是跟当地人聊天&#xff0c;还是看路标、菜单&#xff0c;有个好用的翻译软件是肯定少不了的。今天&#xff0c;我打算给你们介绍3款中英文互译的翻译工具&#xff0c;帮你挑出最适合自己的那一个。…

机器学习:opencv--人脸检测以及微笑检测

目录 前言 一、人脸检测的原理 1.特征提取 2.分类器 二、代码实现 1.图片预处理 2.加载分类器 3.进行人脸识别 4.标注人脸及显示 三、微笑检测 前言 人脸检测是计算机视觉中的一个重要任务&#xff0c;旨在自动识别图像或视频中的人脸。它可以用于多种应用&#xff0…

Python和MATLAB锂电铅蓄电化学微分模型和等效电路

&#x1f3af;要点 对比三种电化学颗粒模型&#xff1a;电化学的锂离子电池模型、单粒子模型和带电解质的单粒子模型。求解粒子域内边界通量与局部电流密度有关的扩散方程。扩展为两个相的负或正电极复合电极粒子模型。模拟四种耦合机制下活性物质损失情况。模拟锂离子电池三参…

【PhpSpreadsheet】ThinkPHP5+PhpSpreadsheet实现批量导出数据

目录 前言 一、安装 二、API使用 三、完整实例 四、效果图 前言 为什么使用PhpSpreadsheet&#xff1f; 由于PHPExcel不再维护&#xff0c;所以建议使用PhpSpreadsheet来导出exlcel&#xff0c;但是PhpSpreadsheet由于是个新的类库&#xff0c;所以只支持PHP7.1及以上的版…

服务器数据恢复—RAID5阵列上层Linux操作系统中节点损坏的数据恢复案例

服务器数据恢复环境&#xff1a; 一台服务器上有一组由5块硬盘&#xff08;4块数据盘1块热备盘&#xff09;组建的raid5阵列。服务器安装Linux Redhat操作系统&#xff0c;运行一套基于oracle数据库的OA系统。 服务器故障&#xff1a; 这组raid5阵列中一块磁盘离线&#xff0c…

观测云 AI 助手上线:智能运维,从此触手可及!

在当前的云原生时代&#xff0c;运维的复杂性和数据的爆炸式增长给企业带来了前所未有的挑战。为了帮助企业高效应对这些挑战&#xff0c;观测云自豪地推出了 AI 助手——智能化的运维助手&#xff0c;让每位用户都能轻松驾驭复杂的可观测性场景。 01 你身边的 PE 助手&#x…

《重置MobaXterm密码并连接Linux虚拟机的完整操作指南》

目录 引言 一、双击MobaXterm_Personal_24.2进入&#xff0c;但是忘记密码。 那么接下来请跟着我操作。 二、点击此链接&#xff0c;重设密码。 三、下载完成后&#xff0c;现在把这个exe文件解压。注意解压要与MobaXterm_Personal_24.2.exe在同一目录下哦&#xff0c;不然…

vim编辑器交换文件的产生与处理方法

文章目录 问题附图交换文件的作用和产生原因报错信息解读解决方法恢复文件使用命令行删除在文件管理器中删除在文本编辑器中处理 问题附图 简要分析 这个报错信息是由 vim 编辑器产生的&#xff0c;它表明在你尝试打开文件 /opt/software/openGauss/clusterconfig.xml 时&#…

MyBatis实践:提高持久层数据处理效率

文章目录 1 Mybatis简介1.1 简介1.2 持久层框架对比 2 快速入门2.1 准备数据库2.2 项目搭建2.3 依赖导入2.4 准备MyBatis配置文件2.5 实体类准备2.6 准备Mapper接口和MapperXML文件2.7 运行和测试 3. 核心配置文件4. MyBatis进阶使用4.0 以包为单位&#xff0c;引入所有的映射文…

一次性入门三款分布式定时任务调度框架:Quartz、ElasticJob3.0、xxl-job

分布式定时任务调度框架&#xff08;文末有源码&#xff09; 前言1、Quartz1.1 数据库1.2 maven依赖1.3 代码实现1.3.1 创建一个job1.3.1 为job设置trigger 1.4 配置文件1.5 启动、测试1.1 单机1.2 集群 2、ElasticJob2.1 下载zk2.2 新建三个类型的作业2.3 配置文件2.4 启动项目…

Nature?拿捏~

之前有分享过很多《Nature》论文插图&#xff0c;想着为大家提供更加广阔的作图思路。 但有人说&#xff0c;这些图好看是好看&#xff0c;可惜也就大佬们能画&#xff0c;跟我这个小卡拉米没啥关系。 此言差矣。 如果我说&#xff0c;Matlab就能画呢&#xff1f; 比如&…

AIGC助力小学生编程梦:C++入门不再难!

文章目录 一、AIGC时代下的编程教育新趋势二、小学生C入门趣味编程的意义三、小学生C入门趣味编程的实践策略四、面临的挑战与应对策略五、AIGC技术在小学生C编程中的应用与前景《小学生C趣味编程从入门到精通》编辑推荐内容简介作者简介目录 随着人工智能生成内容&#xff08;…

C++初阶——入门

目录 1、C发展历史 2、C版本更新 3、C参考文档 4、C书籍推荐 5、C的程序 6、命名空间 6.1 namespace的作用 6.2 namespace的定义 6.3 namespace的使用 7、C输入&输出 8、缺省参数 9、函数重载 10、引用 10.1 引用的概念和定义 10.2 引用的特性 10.3 引用的使…